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

[Xen-changelog] [xen stable-4.4] x86/vmx: Fix injection of #DB traps following XSA-156



commit 425f7f77ce950f39236f7c13e288ce5198c3576a
Author:     Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
AuthorDate: Wed Jan 20 14:10:12 2016 +0100
Commit:     Jan Beulich <jbeulich@xxxxxxxx>
CommitDate: Wed Jan 20 14:10:12 2016 +0100

    x86/vmx: Fix injection of #DB traps following XSA-156
    
    Most #DB exceptions are traps rather than faults, meaning that the 
instruction
    pointer in the exception frame points after the instruction rather than at 
it.
    
    However, VMX intercepts all have fault semantics, even when intercepting a
    trap.  Re-injecting an intercepted trap as a fault causes an infinite loop 
in
    the guest, by re-executing the same trapping instruction repeatedly.  This
    breaks debugging inside the guest.
    
    Introduce a helper which copies VM_EXIT_INTR_INTO to VM_ENTRY_INTR_INFO, and
    use it to mirror the intercepted interrupt back to the guest.
    
    Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
    Acked-by: Kevin Tian <kevin.tian@xxxxxxxxx>
    master commit: 0747bc8b4d85f3fc0ee1e58418418fa0229e8ff8
    master date: 2016-01-05 11:28:56 +0000
---
 xen/arch/x86/hvm/vmx/vmx.c |   32 +++++++++++++++++++++++++++++---
 1 files changed, 29 insertions(+), 3 deletions(-)

diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c
index a8a9d58..f35119b 100644
--- a/xen/arch/x86/hvm/vmx/vmx.c
+++ b/xen/arch/x86/hvm/vmx/vmx.c
@@ -2465,6 +2465,33 @@ static int vmx_handle_eoi_write(void)
     return 0;
 }
 
+/*
+ * Propagate VM_EXIT_INTR_INFO to VM_ENTRY_INTR_INFO.  Used to mirror an
+ * intercepted exception back to the guest as if Xen hadn't intercepted it.
+ *
+ * It is the callers responsibility to ensure that this function is only used
+ * in the context of an appropriate vmexit.
+ */
+static void vmx_propagate_intr(void)
+{
+    unsigned long intr, tmp;
+
+    __vmread(VM_EXIT_INTR_INFO, &intr);
+
+    ASSERT(intr & INTR_INFO_VALID_MASK);
+
+    __vmwrite(VM_ENTRY_INTR_INFO, intr);
+
+    if ( intr & INTR_INFO_DELIVER_CODE_MASK )
+    {
+        __vmread(VM_EXIT_INTR_ERROR_CODE, &tmp);
+        __vmwrite(VM_ENTRY_EXCEPTION_ERROR_CODE, tmp);
+    }
+
+    __vmread(VM_EXIT_INSTRUCTION_LEN, &tmp);
+    __vmwrite(VM_ENTRY_INSTRUCTION_LEN, tmp);
+}
+
 static void vmx_idtv_reinject(unsigned long idtv_info)
 {
 
@@ -2685,7 +2712,7 @@ void vmx_vmexit_handler(struct cpu_user_regs *regs)
             HVMTRACE_1D(TRAP_DEBUG, exit_qualification);
             write_debugreg(6, exit_qualification | 0xffff0ff0);
             if ( !v->domain->debugger_attached )
-                hvm_inject_hw_exception(vector, HVM_DELIVER_NO_ERROR_CODE);
+                vmx_propagate_intr();
             else
                 domain_pause_for_debugger();
             break;
@@ -2754,8 +2781,7 @@ void vmx_vmexit_handler(struct cpu_user_regs *regs)
             break;
         case TRAP_alignment_check:
             HVMTRACE_1D(TRAP, vector);
-            __vmread(VM_EXIT_INTR_ERROR_CODE, &ecode);
-            hvm_inject_hw_exception(vector, ecode);
+            vmx_propagate_intr();
             break;
         case TRAP_nmi:
             if ( (intr_info & INTR_INFO_INTR_TYPE_MASK) !=
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.4

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

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