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 1c9d6ba65696 -r d7bcd6f56b15 xen/include/asm-x86/vmx.h
--- a/xen/include/asm-x86/vmx.h Thu Jun 30 20:42:39 2005
+++ b/xen/include/asm-x86/vmx.h Thu Jun 30 22:27:41 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 1c9d6ba65696 -r d7bcd6f56b15 xen/arch/x86/vmx.c
--- a/xen/arch/x86/vmx.c Thu Jun 30 20:42:39 2005
+++ b/xen/arch/x86/vmx.c Thu Jun 30 22:27:41 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(®s);
- 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(®s, 0);
break;
default:
- printk("unexpected VMexit for exception vector 0x%x\n", vector);
- //__vmx_bug(®s);
+ vmx_reflect_exception(v);
break;
}
break;
diff -r 1c9d6ba65696 -r d7bcd6f56b15 xen/arch/x86/vmx_io.c
--- a/xen/arch/x86/vmx_io.c Thu Jun 30 20:42:39 2005
+++ b/xen/arch/x86/vmx_io.c Thu Jun 30 22:27:41 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-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
|