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

[Xen-changelog] Refactor guest exception injection code.



# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxx
# Node ID 82390e707bb95d33407e04612b172bfb13569858
# Parent  e3dcc10765ea3512306665b07c621ba80da5cde8

Refactor guest exception injection code.

- Exceptions get reflected to the guest by default, instead of crashing
  the domain.
- Reduce code duplication and improve maintainability.

Signed-off-by: Asit Mallick <asit.k.mallick@xxxxxxxxx>
Signed-off-by: Arun Sharma <arun.sharma@xxxxxxxxx>

diff -r e3dcc10765ea -r 82390e707bb9 xen/include/asm-x86/vmx.h
--- a/xen/include/asm-x86/vmx.h Fri Jul  1 21:24:09 2005
+++ b/xen/include/asm-x86/vmx.h Fri Jul  1 21:25:19 2005
@@ -339,6 +339,63 @@
     return (cr0 & X86_CR0_PE) && (cr0 & X86_CR0_PG);
 }
 
+#define VMX_INVALID_ERROR_CODE  -1
+
+static inline int __vmx_inject_exception(struct vcpu *v, int trap, int type, 
+                                         int error_code)
+{
+    unsigned long intr_fields;
+
+    /* Reflect it back into the guest */
+    intr_fields = (INTR_INFO_VALID_MASK | type | trap);
+    if (error_code != VMX_INVALID_ERROR_CODE) {
+        __vmwrite(VM_ENTRY_EXCEPTION_ERROR_CODE, error_code);
+        intr_fields |= INTR_INFO_DELIEVER_CODE_MASK;
+     }
+    
+    __vmwrite(VM_ENTRY_INTR_INFO_FIELD, intr_fields);
+    return 0;
+}
+
+static inline int vmx_inject_exception(struct vcpu *v, int trap, int 
error_code)
+{
+    return __vmx_inject_exception(v, trap, INTR_TYPE_EXCEPTION, error_code);
+}
+
+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);
+    __vmwrite(GUEST_INTERRUPTIBILITY_INFO, 0);
+
+    return 0;
+}
+
+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)
+        __vmread(VM_EXIT_INTR_ERROR_CODE, &error_code);
+    else
+        error_code = VMX_INVALID_ERROR_CODE;
+    vector &= 0xff;
+
+#ifndef NDEBUG
+    {
+        unsigned long eip;
+
+        __vmread(GUEST_RIP, &eip);
+        VMX_DBG_LOG(DBG_LEVEL_1,
+                    "vmx_reflect_exception: eip = %lx, error_code = %x",
+                    eip, error_code);
+    }
+#endif /* NDEBUG */
+
+    vmx_inject_exception(v, vector, error_code);
+    return 0;
+}
+
 static inline shared_iopage_t *get_sp(struct domain *d)
 {
     return (shared_iopage_t *) d->arch.vmx_platform.shared_page_va;
diff -r e3dcc10765ea -r 82390e707bb9 xen/arch/x86/vmx.c
--- a/xen/arch/x86/vmx.c        Fri Jul  1 21:24:09 2005
+++ b/xen/arch/x86/vmx.c        Fri Jul  1 21:25:19 2005
@@ -178,32 +178,6 @@
     __vm_clear_bit(EXCEPTION_BITMAP, EXCEPTION_BITMAP_NM);
 }
 
-static void vmx_do_general_protection_fault(struct cpu_user_regs *regs) 
-{
-    unsigned long eip, error_code;
-    unsigned long intr_fields;
-
-    __vmread(GUEST_RIP, &eip);
-    __vmread(VM_EXIT_INTR_ERROR_CODE, &error_code);
-
-    VMX_DBG_LOG(DBG_LEVEL_1,
-                "vmx_general_protection_fault: eip = %lx, erro_code = %lx",
-                eip, error_code);
-
-    VMX_DBG_LOG(DBG_LEVEL_1,
-                "eax=%lx, ebx=%lx, ecx=%lx, edx=%lx, esi=%lx, edi=%lx",
-                (unsigned long)regs->eax, (unsigned long)regs->ebx,
-                (unsigned long)regs->ecx, (unsigned long)regs->edx,
-                (unsigned long)regs->esi, (unsigned long)regs->edi);
-
-    /* Reflect it back into the guest */
-    intr_fields = (INTR_INFO_VALID_MASK | 
-                  INTR_TYPE_EXCEPTION |
-                  INTR_INFO_DELIEVER_CODE_MASK |
-                  TRAP_gp_fault);
-    __vmwrite(VM_ENTRY_INTR_INFO_FIELD, intr_fields);
-    __vmwrite(VM_ENTRY_EXCEPTION_ERROR_CODE, error_code);
-}
 
 static void vmx_vmexit_do_cpuid(unsigned long input, struct cpu_user_regs 
*regs) 
 {
@@ -1249,11 +1223,6 @@
             vmx_do_no_device_fault();
             break;  
         }
-        case TRAP_gp_fault:
-        {
-            vmx_do_general_protection_fault(&regs);
-            break;  
-        }
         case TRAP_page_fault:
         {
             __vmread(EXIT_QUALIFICATION, &va);
@@ -1269,14 +1238,7 @@
                 /*
                  * Inject #PG using Interruption-Information Fields
                  */
-                unsigned long intr_fields;
-
-                intr_fields = (INTR_INFO_VALID_MASK | 
-                           INTR_TYPE_EXCEPTION |
-                           INTR_INFO_DELIEVER_CODE_MASK |
-                           TRAP_page_fault);
-                __vmwrite(VM_ENTRY_INTR_INFO_FIELD, intr_fields);
-                __vmwrite(VM_ENTRY_EXCEPTION_ERROR_CODE, regs.error_code);
+                vmx_inject_exception(v, TRAP_page_fault, regs.error_code);
                 v->arch.arch_vmx.cpu_cr2 = va;
                 TRACE_3D(TRC_VMX_INT, v->domain->domain_id, TRAP_page_fault, 
va);
             }
@@ -1286,8 +1248,7 @@
             do_nmi(&regs, 0);
             break;
         default:
-            printk("unexpected VMexit for exception vector 0x%x\n", vector);
-            //__vmx_bug(&regs);
+            vmx_reflect_exception(v);
             break;
         }
         break;
diff -r e3dcc10765ea -r 82390e707bb9 xen/arch/x86/vmx_io.c
--- a/xen/arch/x86/vmx_io.c     Fri Jul  1 21:24:09 2005
+++ b/xen/arch/x86/vmx_io.c     Fri Jul  1 21:25:19 2005
@@ -660,11 +660,7 @@
                  return;
              }
 
-             intr_fields = (INTR_INFO_VALID_MASK | INTR_TYPE_EXT_INTR 
-                            | highest_vector);
-             __vmwrite(VM_ENTRY_INTR_INFO_FIELD, intr_fields);
-             __vmwrite(GUEST_INTERRUPTIBILITY_INFO, 0);
-
+             vmx_inject_extint(v, highest_vector, VMX_INVALID_ERROR_CODE);
              TRACE_3D(TRC_VMX_INT, v->domain->domain_id, highest_vector, 0);
              break;
          case VLAPIC_DELIV_MODE_FIXED:

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
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®.