direct-io.hg
changeset 5646:82390e707bb9
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@intel.com>
Signed-off-by: Arun Sharma <arun.sharma@intel.com>
- 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@intel.com>
Signed-off-by: Arun Sharma <arun.sharma@intel.com>
author | kaf24@firebug.cl.cam.ac.uk |
---|---|
date | Fri Jul 01 21:25:19 2005 +0000 (2005-07-01) |
parents | e3dcc10765ea |
children | 6f462a11a08e |
files | xen/arch/x86/vmx.c xen/arch/x86/vmx_io.c xen/include/asm-x86/vmx.h |
line diff
1.1 --- a/xen/arch/x86/vmx.c Fri Jul 01 21:24:09 2005 +0000 1.2 +++ b/xen/arch/x86/vmx.c Fri Jul 01 21:25:19 2005 +0000 1.3 @@ -178,32 +178,6 @@ static void vmx_do_no_device_fault(void) 1.4 __vm_clear_bit(EXCEPTION_BITMAP, EXCEPTION_BITMAP_NM); 1.5 } 1.6 1.7 -static void vmx_do_general_protection_fault(struct cpu_user_regs *regs) 1.8 -{ 1.9 - unsigned long eip, error_code; 1.10 - unsigned long intr_fields; 1.11 - 1.12 - __vmread(GUEST_RIP, &eip); 1.13 - __vmread(VM_EXIT_INTR_ERROR_CODE, &error_code); 1.14 - 1.15 - VMX_DBG_LOG(DBG_LEVEL_1, 1.16 - "vmx_general_protection_fault: eip = %lx, erro_code = %lx", 1.17 - eip, error_code); 1.18 - 1.19 - VMX_DBG_LOG(DBG_LEVEL_1, 1.20 - "eax=%lx, ebx=%lx, ecx=%lx, edx=%lx, esi=%lx, edi=%lx", 1.21 - (unsigned long)regs->eax, (unsigned long)regs->ebx, 1.22 - (unsigned long)regs->ecx, (unsigned long)regs->edx, 1.23 - (unsigned long)regs->esi, (unsigned long)regs->edi); 1.24 - 1.25 - /* Reflect it back into the guest */ 1.26 - intr_fields = (INTR_INFO_VALID_MASK | 1.27 - INTR_TYPE_EXCEPTION | 1.28 - INTR_INFO_DELIEVER_CODE_MASK | 1.29 - TRAP_gp_fault); 1.30 - __vmwrite(VM_ENTRY_INTR_INFO_FIELD, intr_fields); 1.31 - __vmwrite(VM_ENTRY_EXCEPTION_ERROR_CODE, error_code); 1.32 -} 1.33 1.34 static void vmx_vmexit_do_cpuid(unsigned long input, struct cpu_user_regs *regs) 1.35 { 1.36 @@ -1249,11 +1223,6 @@ asmlinkage void vmx_vmexit_handler(struc 1.37 vmx_do_no_device_fault(); 1.38 break; 1.39 } 1.40 - case TRAP_gp_fault: 1.41 - { 1.42 - vmx_do_general_protection_fault(®s); 1.43 - break; 1.44 - } 1.45 case TRAP_page_fault: 1.46 { 1.47 __vmread(EXIT_QUALIFICATION, &va); 1.48 @@ -1269,14 +1238,7 @@ asmlinkage void vmx_vmexit_handler(struc 1.49 /* 1.50 * Inject #PG using Interruption-Information Fields 1.51 */ 1.52 - unsigned long intr_fields; 1.53 - 1.54 - intr_fields = (INTR_INFO_VALID_MASK | 1.55 - INTR_TYPE_EXCEPTION | 1.56 - INTR_INFO_DELIEVER_CODE_MASK | 1.57 - TRAP_page_fault); 1.58 - __vmwrite(VM_ENTRY_INTR_INFO_FIELD, intr_fields); 1.59 - __vmwrite(VM_ENTRY_EXCEPTION_ERROR_CODE, regs.error_code); 1.60 + vmx_inject_exception(v, TRAP_page_fault, regs.error_code); 1.61 v->arch.arch_vmx.cpu_cr2 = va; 1.62 TRACE_3D(TRC_VMX_INT, v->domain->domain_id, TRAP_page_fault, va); 1.63 } 1.64 @@ -1286,8 +1248,7 @@ asmlinkage void vmx_vmexit_handler(struc 1.65 do_nmi(®s, 0); 1.66 break; 1.67 default: 1.68 - printk("unexpected VMexit for exception vector 0x%x\n", vector); 1.69 - //__vmx_bug(®s); 1.70 + vmx_reflect_exception(v); 1.71 break; 1.72 } 1.73 break;
2.1 --- a/xen/arch/x86/vmx_io.c Fri Jul 01 21:24:09 2005 +0000 2.2 +++ b/xen/arch/x86/vmx_io.c Fri Jul 01 21:25:19 2005 +0000 2.3 @@ -660,11 +660,7 @@ void vmx_intr_assist(struct vcpu *v) 2.4 return; 2.5 } 2.6 2.7 - intr_fields = (INTR_INFO_VALID_MASK | INTR_TYPE_EXT_INTR 2.8 - | highest_vector); 2.9 - __vmwrite(VM_ENTRY_INTR_INFO_FIELD, intr_fields); 2.10 - __vmwrite(GUEST_INTERRUPTIBILITY_INFO, 0); 2.11 - 2.12 + vmx_inject_extint(v, highest_vector, VMX_INVALID_ERROR_CODE); 2.13 TRACE_3D(TRC_VMX_INT, v->domain->domain_id, highest_vector, 0); 2.14 break; 2.15 case VLAPIC_DELIV_MODE_FIXED:
3.1 --- a/xen/include/asm-x86/vmx.h Fri Jul 01 21:24:09 2005 +0000 3.2 +++ b/xen/include/asm-x86/vmx.h Fri Jul 01 21:25:19 2005 +0000 3.3 @@ -339,6 +339,63 @@ static inline int vmx_paging_enabled(str 3.4 return (cr0 & X86_CR0_PE) && (cr0 & X86_CR0_PG); 3.5 } 3.6 3.7 +#define VMX_INVALID_ERROR_CODE -1 3.8 + 3.9 +static inline int __vmx_inject_exception(struct vcpu *v, int trap, int type, 3.10 + int error_code) 3.11 +{ 3.12 + unsigned long intr_fields; 3.13 + 3.14 + /* Reflect it back into the guest */ 3.15 + intr_fields = (INTR_INFO_VALID_MASK | type | trap); 3.16 + if (error_code != VMX_INVALID_ERROR_CODE) { 3.17 + __vmwrite(VM_ENTRY_EXCEPTION_ERROR_CODE, error_code); 3.18 + intr_fields |= INTR_INFO_DELIEVER_CODE_MASK; 3.19 + } 3.20 + 3.21 + __vmwrite(VM_ENTRY_INTR_INFO_FIELD, intr_fields); 3.22 + return 0; 3.23 +} 3.24 + 3.25 +static inline int vmx_inject_exception(struct vcpu *v, int trap, int error_code) 3.26 +{ 3.27 + return __vmx_inject_exception(v, trap, INTR_TYPE_EXCEPTION, error_code); 3.28 +} 3.29 + 3.30 +static inline int vmx_inject_extint(struct vcpu *v, int trap, int error_code) 3.31 +{ 3.32 + __vmx_inject_exception(v, trap, INTR_TYPE_EXT_INTR, error_code); 3.33 + __vmwrite(GUEST_INTERRUPTIBILITY_INFO, 0); 3.34 + 3.35 + return 0; 3.36 +} 3.37 + 3.38 +static inline int vmx_reflect_exception(struct vcpu *v) 3.39 +{ 3.40 + int error_code, vector; 3.41 + 3.42 + __vmread(VM_EXIT_INTR_INFO, &vector); 3.43 + if (vector & INTR_INFO_DELIEVER_CODE_MASK) 3.44 + __vmread(VM_EXIT_INTR_ERROR_CODE, &error_code); 3.45 + else 3.46 + error_code = VMX_INVALID_ERROR_CODE; 3.47 + vector &= 0xff; 3.48 + 3.49 +#ifndef NDEBUG 3.50 + { 3.51 + unsigned long eip; 3.52 + 3.53 + __vmread(GUEST_RIP, &eip); 3.54 + VMX_DBG_LOG(DBG_LEVEL_1, 3.55 + "vmx_reflect_exception: eip = %lx, error_code = %x", 3.56 + eip, error_code); 3.57 + } 3.58 +#endif /* NDEBUG */ 3.59 + 3.60 + vmx_inject_exception(v, vector, error_code); 3.61 + return 0; 3.62 +} 3.63 + 3.64 static inline shared_iopage_t *get_sp(struct domain *d) 3.65 { 3.66 return (shared_iopage_t *) d->arch.vmx_platform.shared_page_va;