|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH for-4.9 1/2] x86/pv: Fix the handling of `int $x` for vectors which alias exceptions
The claim at the top of c/s 2e426d6eecf "x86/traps: Drop use_error_code
parameter from do_{,guest_}trap()" is only actually true for hardware
exceptions. It is not true for `int $x` instructions (which never push error
code), irrespective of whether the vector aliases an exception or not.
Futhermore, c/s 6480cc6280e "x86/traps: Fix failed ASSERT() in
do_guest_trap()" really should have helped highlight that a regression had
been introduced.
Modify pv_inject_event() to understand event types other than
X86_EVENTTYPE_HW_EXCEPTION, and introduce pv_inject_sw_interrupt() for the
`int $x` handling code.
Add further assertions to pv_inject_event() concerning the type of events
passed in, which in turn requires that do_guest_trap() set its type
appropriately (which is now used exclusively for hardware exceptions).
Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
---
CC: Jan Beulich <JBeulich@xxxxxxxx>
CC: Julien Grall <julien.grall@xxxxxxx>
This fix needs backporting to Xen 4.8, and therefore should be considered for
4.9 at this point.
The fix will need to be rather different for Xen 4.8. I am happy to do the
backport if this patch is accepted.
---
xen/arch/x86/traps.c | 9 +++++++--
xen/include/asm-x86/domain.h | 11 +++++++++++
2 files changed, 18 insertions(+), 2 deletions(-)
diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c
index 27fdf12..b2421c9 100644
--- a/xen/arch/x86/traps.c
+++ b/xen/arch/x86/traps.c
@@ -633,9 +633,12 @@ void pv_inject_event(const struct x86_event *event)
const struct trap_info *ti;
const uint8_t vector = event->vector;
const bool use_error_code =
+ (event->type == X86_EVENTTYPE_HW_EXCEPTION) &&
((vector < 32) && (TRAP_HAVE_EC & (1u << vector)));
unsigned int error_code = event->error_code;
+ ASSERT(event->type == X86_EVENTTYPE_HW_EXCEPTION ||
+ event->type == X86_EVENTTYPE_SW_INTERRUPT);
ASSERT(vector == event->vector); /* Confirm no truncation. */
if ( use_error_code )
ASSERT(error_code != X86_EVENT_NO_EC);
@@ -649,7 +652,8 @@ void pv_inject_event(const struct x86_event *event)
tb->cs = ti->cs;
tb->eip = ti->address;
- if ( vector == TRAP_page_fault )
+ if ( event->type == X86_EVENTTYPE_HW_EXCEPTION &&
+ vector == TRAP_page_fault )
{
v->arch.pv_vcpu.ctrlreg[2] = event->cr2;
arch_set_cr2(v, event->cr2);
@@ -689,6 +693,7 @@ static inline void do_guest_trap(unsigned int trapnr,
{
const struct x86_event event = {
.vector = trapnr,
+ .type = X86_EVENTTYPE_HW_EXCEPTION,
.error_code = (((trapnr < 32) && (TRAP_HAVE_EC & (1u << trapnr)))
? regs->error_code : X86_EVENT_NO_EC),
};
@@ -3427,7 +3432,7 @@ void do_general_protection(struct cpu_user_regs *regs)
if ( permit_softint(TI_GET_DPL(ti), v, regs) )
{
regs->rip += 2;
- do_guest_trap(vector, regs);
+ pv_inject_sw_interrupt(vector);
return;
}
}
diff --git a/xen/include/asm-x86/domain.h b/xen/include/asm-x86/domain.h
index 6ab987f..924caac 100644
--- a/xen/include/asm-x86/domain.h
+++ b/xen/include/asm-x86/domain.h
@@ -655,6 +655,17 @@ static inline void pv_inject_page_fault(int errcode,
unsigned long cr2)
pv_inject_event(&event);
}
+static inline void pv_inject_sw_interrupt(unsigned int vector)
+{
+ const struct x86_event event = {
+ .vector = vector,
+ .type = X86_EVENTTYPE_SW_INTERRUPT,
+ .error_code = X86_EVENT_NO_EC,
+ };
+
+ pv_inject_event(&event);
+}
+
#endif /* __ASM_DOMAIN_H__ */
/*
--
2.1.4
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
https://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |