[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH for-4.8] 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.

Furthermore, 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).

This is logically a backport of c/s 5c4f579e0ee4f38cad5636bbf8ce700a394338d0
from Xen 4.9, but disentangled from the other injection work.

Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
---
CC: Jan Beulich <JBeulich@xxxxxxxx>
---
 xen/arch/x86/traps.c | 26 +++++++++++++++++++++-----
 1 file changed, 21 insertions(+), 5 deletions(-)

diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c
index 19ac652..8c992ce 100644
--- a/xen/arch/x86/traps.c
+++ b/xen/arch/x86/traps.c
@@ -625,14 +625,24 @@ void fatal_trap(const struct cpu_user_regs *regs, bool_t 
show_remote)
           (regs->eflags & X86_EFLAGS_IF) ? "" : ", IN INTERRUPT CONTEXT");
 }
 
-static void do_guest_trap(unsigned int trapnr,
-                          const struct cpu_user_regs *regs)
+static void pv_inject_event(
+    unsigned int trapnr, const struct cpu_user_regs *regs, unsigned int type)
 {
     struct vcpu *v = current;
     struct trap_bounce *tb;
     const struct trap_info *ti;
-    const bool use_error_code =
-        ((trapnr < 32) && (TRAP_HAVE_EC & (1u << trapnr)));
+    bool use_error_code;
+
+    if ( type == X86_EVENTTYPE_HW_EXCEPTION )
+    {
+        ASSERT(trapnr < 32);
+        use_error_code = TRAP_HAVE_EC & (1u << trapnr);
+    }
+    else
+    {
+        ASSERT(type == X86_EVENTTYPE_SW_INTERRUPT);
+        use_error_code = false;
+    }
 
     trace_pv_trap(trapnr, regs->eip, use_error_code, regs->error_code);
 
@@ -658,6 +668,12 @@ static void do_guest_trap(unsigned int trapnr,
                 trapstr(trapnr), trapnr, regs->error_code);
 }
 
+static void do_guest_trap(
+    unsigned int trapnr, const struct cpu_user_regs *regs)
+{
+    pv_inject_event(trapnr, regs, X86_EVENTTYPE_HW_EXCEPTION);
+}
+
 static void instruction_done(
     struct cpu_user_regs *regs, unsigned long eip, unsigned int bpmatch)
 {
@@ -3685,7 +3701,7 @@ void do_general_protection(struct cpu_user_regs *regs)
         if ( permit_softint(TI_GET_DPL(ti), v, regs) )
         {
             regs->eip += 2;
-            do_guest_trap(vector, regs);
+            pv_inject_event(vector, regs, X86_EVENTTYPE_SW_INTERRUPT);
             return;
         }
     }
-- 
2.1.4


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
https://lists.xen.org/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.