[xen master] x86/pv: Fix the handling of `int $x` for vectors which alias exceptions

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

[xen master] x86/pv: Fix the handling of `int $x` for vectors which alias exceptions

patchbot
commit 5c4f579e0ee4f38cad5636bbf8ce700a394338d0
Author:     Andrew Cooper <[hidden email]>
AuthorDate: Mon May 15 13:05:45 2017 +0100
Commit:     Andrew Cooper <[hidden email]>
CommitDate: Wed May 17 12:05:22 2017 +0100

    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).
   
    Signed-off-by: Andrew Cooper <[hidden email]>
    Reviewed-by: Jan Beulich <[hidden email]>
    Release-acked-by: Julien Grall <[hidden email]>
---
 xen/arch/x86/traps.c         | 19 +++++++++++++++----
 xen/include/asm-x86/domain.h | 11 +++++++++++
 2 files changed, 26 insertions(+), 4 deletions(-)

diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c
index 27fdf12..dfca0a5 100644
--- a/xen/arch/x86/traps.c
+++ b/xen/arch/x86/traps.c
@@ -632,11 +632,20 @@ void pv_inject_event(const struct x86_event *event)
     struct trap_bounce *tb;
     const struct trap_info *ti;
     const uint8_t vector = event->vector;
-    const bool use_error_code =
-        ((vector < 32) && (TRAP_HAVE_EC & (1u << vector)));
     unsigned int error_code = event->error_code;
+    bool use_error_code;
 
     ASSERT(vector == event->vector); /* Confirm no truncation. */
+    if ( event->type == X86_EVENTTYPE_HW_EXCEPTION )
+    {
+        ASSERT(vector < 32);
+        use_error_code = TRAP_HAVE_EC & (1u << vector);
+    }
+    else
+    {
+        ASSERT(event->type == X86_EVENTTYPE_SW_INTERRUPT);
+        use_error_code = false;
+    }
     if ( use_error_code )
         ASSERT(error_code != X86_EVENT_NO_EC);
     else
@@ -649,7 +658,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 +699,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 +3438,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__ */
 
 /*
--
generated by git-patchbot for /home/xen/git/xen.git#master

_______________________________________________
Xen-changelog mailing list
[hidden email]
https://lists.xenproject.org/xen-changelog