Skip to contentSkip to conversation

Refactor guest exception injection code.

PATCH In review Arun Sharma 1 participant 1 message Jul 1, 2005

lore
Share & tools
lore
#0 lore raw

PATCH 4/5 Refactor guest exception injection code.

Refactor guest exception injection code.

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

xen/include/asm-x86/vmx.h +57 -0
diff -r 1c9d6ba65696 -r d7bcd6f56b15 xen/include/asm-x86/vmx.h
@@ -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;
xen/arch/x86/vmx.c +2 -41

67 lines not on this page · raw message

xen/arch/x86/vmx_io.c +1 -5
diff -r 1c9d6ba65696 -r d7bcd6f56b15 xen/arch/x86/vmx_io.c
@@ -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: