hvm: Add instruction length to hvm_trap info.
authorKeir Fraser <keir@xen.org>
Wed, 30 May 2012 08:40:44 +0000 (09:40 +0100)
committerKeir Fraser <keir@xen.org>
Wed, 30 May 2012 08:40:44 +0000 (09:40 +0100)
Add documentation notes to vmx_inject_trap() and respect instruiction
length parameter for software-generated exceptions/interrupts.

Signed-off-by: Xudong Hao <xudong.hao@intel.com>
Signed-off-by: Eddie Dong <eddie.dong@intel.com>
Signed-off-by: Xiantao Zhang <xiantao.zhang@intel.com>
Signed-off-by: Keir Fraser <keir@xen.org>
xen/arch/x86/hvm/vmx/vmx.c
xen/include/asm-x86/hvm/hvm.h

index c96d18b99e62d468f3a0b1d71de44e5966235f49..79f2b21599d3da249ed46bff06543f490f2e5ff7 100644 (file)
@@ -1381,6 +1381,14 @@ void vmx_inject_nmi(void)
                            HVM_DELIVER_NO_ERROR_CODE);
 }
 
+/*
+ * Generate a virtual event in the guest.
+ * NOTES:
+ *  - INT 3 (CC) and INTO (CE) are X86_EVENTTYPE_SW_EXCEPTION;
+ *  - INT nn (CD nn) is X86_EVENTTYPE_SW_INTERRUPT;
+ *  - #DB is X86_EVENTTYPE_HW_EXCEPTION, except when generated by
+ *    opcode 0xf1 (which is X86_EVENTTYPE_PRI_SW_EXCEPTION)
+ */
 static void vmx_inject_trap(struct hvm_trap *trap)
 {
     unsigned long intr_info;
@@ -1425,6 +1433,9 @@ static void vmx_inject_trap(struct hvm_trap *trap)
             _trap.error_code = 0;
     }
 
+    if ( _trap.type >= X86_EVENTTYPE_SW_INTERRUPT )
+        __vmwrite(VM_ENTRY_INSTRUCTION_LEN, _trap.inslen);
+
     if ( nestedhvm_vcpu_in_guestmode(curr) &&
          nvmx_intercepts_exception(curr, _trap.vector, _trap.error_code) )
     {
@@ -2424,7 +2435,8 @@ void vmx_vmexit_handler(struct cpu_user_regs *regs)
                     struct hvm_trap trap = {
                         .vector = TRAP_int3,
                         .type = X86_EVENTTYPE_SW_EXCEPTION,
-                        .error_code = HVM_DELIVER_NO_ERROR_CODE
+                        .error_code = HVM_DELIVER_NO_ERROR_CODE,
+                        .inslen = __vmread(VM_EXIT_INSTRUCTION_LEN)
                     };
                     hvm_inject_trap(&trap);
                     break;
index 65f7e20e9a85482007ece8ec5cf22fca9d5a5ebb..a3d8bf14a0cb4409663c270ac9815a22aeb3646c 100644 (file)
@@ -76,6 +76,7 @@ struct hvm_trap {
     unsigned int  type;         /* X86_EVENTTYPE_* */
     int           error_code;   /* HVM_DELIVER_NO_ERROR_CODE if n/a */
     unsigned long cr2;          /* Only for TRAP_page_fault h/w exception */
+    int           inslen;       /* Instruction length */ 
 };
 
 /*
@@ -375,6 +376,7 @@ static inline int hvm_do_pmu_interrupt(struct cpu_user_regs *regs)
 #define X86_EVENTTYPE_NMI                   2    /* NMI                */
 #define X86_EVENTTYPE_HW_EXCEPTION          3    /* hardware exception */
 #define X86_EVENTTYPE_SW_INTERRUPT          4    /* software interrupt */
+#define X86_EVENTTYPE_PRI_SW_EXCEPTION      5    /* privileged software exception */
 #define X86_EVENTTYPE_SW_EXCEPTION          6    /* software exception */
 
 int hvm_event_needs_reinjection(uint8_t type, uint8_t vector);