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>
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(&regs);
    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(&regs, 0);
    1.66              break;
    1.67          default:
    1.68 -            printk("unexpected VMexit for exception vector 0x%x\n", vector);
    1.69 -            //__vmx_bug(&regs);
    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;