WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] [HVM][VMX] Fix injection of software exce

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] [HVM][VMX] Fix injection of software exceptions (#BP, #OF)
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Thu, 27 Jul 2006 16:10:18 +0000
Delivery-date: Thu, 27 Jul 2006 09:13:06 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User kfraser@xxxxxxxxxxxxxxxxxxxxx
# Node ID f42039dcdc814cf3d154cdccd58f930df98901dd
# Parent  ed20a5addce450af042e61f0bdb6f7b59de9b25c
[HVM][VMX] Fix injection of software exceptions (#BP,#OF)
From: George Dunlap <dunlapg@xxxxxxxxx>
Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
---
 xen/arch/x86/hvm/vmx/vmx.c        |   18 ++++++-------
 xen/include/asm-x86/hvm/vmx/vmx.h |   52 +++++++++++++++++++++++++++-----------
 2 files changed, 47 insertions(+), 23 deletions(-)

diff -r ed20a5addce4 -r f42039dcdc81 xen/arch/x86/hvm/vmx/vmx.c
--- a/xen/arch/x86/hvm/vmx/vmx.c        Thu Jul 27 12:59:36 2006 +0100
+++ b/xen/arch/x86/hvm/vmx/vmx.c        Thu Jul 27 13:05:33 2006 +0100
@@ -286,7 +286,7 @@ static inline int long_mode_do_msr_write
         if ( msr_content & ~(EFER_LME | EFER_LMA | EFER_NX | EFER_SCE) )
         {
             printk("trying to set reserved bit in EFER\n");
-            vmx_inject_exception(v, TRAP_gp_fault, 0);
+            vmx_inject_hw_exception(v, TRAP_gp_fault, 0);
             return 0;
         }
 
@@ -300,7 +300,7 @@ static inline int long_mode_do_msr_write
             {
                 printk("trying to set LME bit when "
                        "in paging mode or PAE bit is not set\n");
-                vmx_inject_exception(v, TRAP_gp_fault, 0);
+                vmx_inject_hw_exception(v, TRAP_gp_fault, 0);
                 return 0;
             }
 
@@ -318,7 +318,7 @@ static inline int long_mode_do_msr_write
         if ( !IS_CANO_ADDRESS(msr_content) )
         {
             HVM_DBG_LOG(DBG_LEVEL_1, "Not cano address of msr write\n");
-            vmx_inject_exception(v, TRAP_gp_fault, 0);
+            vmx_inject_hw_exception(v, TRAP_gp_fault, 0);
             return 0;
         }
 
@@ -1438,7 +1438,7 @@ static int vmx_set_cr0(unsigned long val
                        &v->arch.hvm_vmx.cpu_state) )
         {
             HVM_DBG_LOG(DBG_LEVEL_1, "Enable paging before PAE enabled\n");
-            vmx_inject_exception(v, TRAP_gp_fault, 0);
+            vmx_inject_hw_exception(v, TRAP_gp_fault, 0);
         }
 
         if ( test_bit(VMX_CPU_STATE_LME_ENABLED,
@@ -1520,7 +1520,7 @@ static int vmx_set_cr0(unsigned long val
     {
         if ( value & X86_CR0_PG ) {
             /* inject GP here */
-            vmx_inject_exception(v, TRAP_gp_fault, 0);
+            vmx_inject_hw_exception(v, TRAP_gp_fault, 0);
             return 0;
         } else {
             /*
@@ -1764,7 +1764,7 @@ static int mov_to_cr(int gp, int cr, str
         else
         {
             if ( test_bit(VMX_CPU_STATE_LMA_ENABLED, 
&v->arch.hvm_vmx.cpu_state) )
-                vmx_inject_exception(v, TRAP_gp_fault, 0);
+                vmx_inject_hw_exception(v, TRAP_gp_fault, 0);
 
             clear_bit(VMX_CPU_STATE_PAE_ENABLED, &v->arch.hvm_vmx.cpu_state);
         }
@@ -2192,7 +2192,7 @@ asmlinkage void vmx_vmexit_handler(struc
             if ( test_bit(_DOMF_debugging, &v->domain->domain_flags) )
                 domain_pause_for_debugger();
             else 
-                vmx_inject_exception(v, TRAP_int3, VMX_DELIVER_NO_ERROR_CODE);
+                vmx_reflect_exception(v);
             break;
         }
 #endif
@@ -2219,7 +2219,7 @@ asmlinkage void vmx_vmexit_handler(struc
                 /*
                  * Inject #PG using Interruption-Information Fields
                  */
-                vmx_inject_exception(v, TRAP_page_fault, regs.error_code);
+                vmx_inject_hw_exception(v, TRAP_page_fault, regs.error_code);
                 v->arch.hvm_vmx.cpu_cr2 = va;
                 TRACE_3D(TRC_VMX_INT, v->domain->domain_id, TRAP_page_fault, 
va);
             }
@@ -2335,7 +2335,7 @@ asmlinkage void vmx_vmexit_handler(struc
     case EXIT_REASON_VMON:
         /* Report invalid opcode exception when a VMX guest tries to execute 
             any of the VMX instructions */
-        vmx_inject_exception(v, TRAP_invalid_op, VMX_DELIVER_NO_ERROR_CODE);
+        vmx_inject_hw_exception(v, TRAP_invalid_op, VMX_DELIVER_NO_ERROR_CODE);
         break;
 
     default:
diff -r ed20a5addce4 -r f42039dcdc81 xen/include/asm-x86/hvm/vmx/vmx.h
--- a/xen/include/asm-x86/hvm/vmx/vmx.h Thu Jul 27 12:59:36 2006 +0100
+++ b/xen/include/asm-x86/hvm/vmx/vmx.h Thu Jul 27 13:05:33 2006 +0100
@@ -143,11 +143,12 @@ extern unsigned int cpu_rev;
  */
 #define INTR_INFO_VECTOR_MASK           0xff            /* 7:0 */
 #define INTR_INFO_INTR_TYPE_MASK        0x700           /* 10:8 */
-#define INTR_INFO_DELIEVER_CODE_MASK    0x800           /* 11 */
+#define INTR_INFO_DELIVER_CODE_MASK     0x800           /* 11 */
 #define INTR_INFO_VALID_MASK            0x80000000      /* 31 */
 
 #define INTR_TYPE_EXT_INTR              (0 << 8) /* external interrupt */
-#define INTR_TYPE_EXCEPTION             (3 << 8) /* processor exception */
+#define INTR_TYPE_HW_EXCEPTION             (3 << 8) /* hardware exception */
+#define INTR_TYPE_SW_EXCEPTION             (6 << 8) /* software exception */
 
 /*
  * Exit Qualifications for MOV for Control Register Access
@@ -421,7 +422,7 @@ static inline int vmx_pgbit_test(struct 
 }
 
 static inline int __vmx_inject_exception(struct vcpu *v, int trap, int type, 
-                                         int error_code)
+                                         int error_code, int ilen)
 {
     unsigned long intr_fields;
 
@@ -429,22 +430,33 @@ static inline int __vmx_inject_exception
     intr_fields = (INTR_INFO_VALID_MASK | type | trap);
     if (error_code != VMX_DELIVER_NO_ERROR_CODE) {
         __vmwrite(VM_ENTRY_EXCEPTION_ERROR_CODE, error_code);
-        intr_fields |= INTR_INFO_DELIEVER_CODE_MASK;
+        intr_fields |= INTR_INFO_DELIVER_CODE_MASK;
      }
-    
+
+    if(ilen)
+      __vmwrite(VM_ENTRY_INSTRUCTION_LEN, ilen);
+
     __vmwrite(VM_ENTRY_INTR_INFO_FIELD, intr_fields);
     return 0;
 }
 
-static inline int vmx_inject_exception(struct vcpu *v, int trap, int 
error_code)
+static inline int vmx_inject_hw_exception(struct vcpu *v, int trap, int 
error_code)
 {
     v->arch.hvm_vmx.vector_injected = 1;
-    return __vmx_inject_exception(v, trap, INTR_TYPE_EXCEPTION, error_code);
+    return __vmx_inject_exception(v, trap, INTR_TYPE_HW_EXCEPTION,
+                                 error_code, 0);
+}
+
+static inline int vmx_inject_sw_exception(struct vcpu *v, int trap, int 
instruction_len) {
+     v->arch.hvm_vmx.vector_injected=1;
+     return __vmx_inject_exception(v, trap, INTR_TYPE_SW_EXCEPTION,
+                                  VMX_DELIVER_NO_ERROR_CODE,
+                                  instruction_len);
 }
 
 static inline int vmx_inject_extint(struct vcpu *v, int trap, int error_code)
 {
-    __vmx_inject_exception(v, trap, INTR_TYPE_EXT_INTR, error_code);
+    __vmx_inject_exception(v, trap, INTR_TYPE_EXT_INTR, error_code, 0);
     __vmwrite(GUEST_INTERRUPTIBILITY_INFO, 0);
 
     return 0;
@@ -452,14 +464,14 @@ static inline int vmx_inject_extint(stru
 
 static inline int vmx_reflect_exception(struct vcpu *v)
 {
-    int error_code, vector;
-
-    __vmread(VM_EXIT_INTR_INFO, &vector);
-    if (vector & INTR_INFO_DELIEVER_CODE_MASK)
+    int error_code, intr_info, vector;
+
+    __vmread(VM_EXIT_INTR_INFO, &intr_info);
+    vector = intr_info & 0xff;
+    if (intr_info & INTR_INFO_DELIVER_CODE_MASK)
         __vmread(VM_EXIT_INTR_ERROR_CODE, &error_code);
     else
         error_code = VMX_DELIVER_NO_ERROR_CODE;
-    vector &= 0xff;
 
 #ifndef NDEBUG
     {
@@ -472,7 +484,19 @@ static inline int vmx_reflect_exception(
     }
 #endif /* NDEBUG */
 
-    vmx_inject_exception(v, vector, error_code);
+    /* According to Intel Virtualization Technology Specification for
+       the IA-32 Intel Architecture (C97063-002 April 2005), section
+       2.8.3, SW_EXCEPTION should be used for #BP and #OV, and
+       HW_EXCPEPTION used for everything else.  The main difference
+       appears to be that for SW_EXCEPTION, the EIP/RIP is incremented
+       by VM_ENTER_INSTRUCTION_LEN bytes, whereas for HW_EXCEPTION, 
+       it is not.  */
+    if((intr_info & INTR_INFO_INTR_TYPE_MASK) == INTR_TYPE_SW_EXCEPTION) {
+      int ilen;
+      __vmread(VM_EXIT_INSTRUCTION_LEN, &ilen);
+      vmx_inject_sw_exception(v, vector, ilen);
+    } else
+      vmx_inject_hw_exception(v, vector, error_code);
     return 0;
 }
 

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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] [HVM][VMX] Fix injection of software exceptions (#BP, #OF), Xen patchbot-unstable <=