ia64/xen-unstable

changeset 14079:3f7e8c763b55

hvm: Do not take shadow-emulation path if we are trying to inject an
event into the HVM guest.
Signed-off-by: Keir Fraser <keir@xensource.com>
author kfraser@localhost.localdomain
date Thu Feb 22 12:49:44 2007 +0000 (2007-02-22)
parents 0a970a431bbc
children c0b1a3b54548
files xen/arch/x86/hvm/svm/svm.c xen/arch/x86/hvm/vmx/vmx.c xen/arch/x86/mm/shadow/multi.c xen/include/asm-x86/hvm/hvm.h
line diff
     1.1 --- a/xen/arch/x86/hvm/svm/svm.c	Thu Feb 22 12:21:29 2007 +0000
     1.2 +++ b/xen/arch/x86/hvm/svm/svm.c	Thu Feb 22 12:49:44 2007 +0000
     1.3 @@ -982,6 +982,12 @@ static void svm_hvm_inject_exception(
     1.4          v->arch.hvm_svm.vmcb->cr2 = v->arch.hvm_svm.cpu_cr2 = cr2;
     1.5  }
     1.6  
     1.7 +static int svm_injection_pending(struct vcpu *v)
     1.8 +{
     1.9 +    struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
    1.10 +    return (vmcb->vintr.fields.irq || vmcb->exitintinfo.fields.v);
    1.11 +}
    1.12 +
    1.13  int start_svm(void)
    1.14  {
    1.15      u32 eax, ecx, edx;
    1.16 @@ -1058,6 +1064,8 @@ int start_svm(void)
    1.17      hvm_funcs.init_ap_context = svm_init_ap_context;
    1.18      hvm_funcs.init_hypercall_page = svm_init_hypercall_page;
    1.19  
    1.20 +    hvm_funcs.injection_pending = svm_injection_pending;
    1.21 +
    1.22      hvm_enable();
    1.23  
    1.24      return 1;
     2.1 --- a/xen/arch/x86/hvm/vmx/vmx.c	Thu Feb 22 12:21:29 2007 +0000
     2.2 +++ b/xen/arch/x86/hvm/vmx/vmx.c	Thu Feb 22 12:49:44 2007 +0000
     2.3 @@ -990,6 +990,18 @@ static void vmx_update_vtpr(struct vcpu 
     2.4      /* VMX doesn't have a V_TPR field */
     2.5  }
     2.6  
     2.7 +static int vmx_injection_pending(struct vcpu *v)
     2.8 +{
     2.9 +    unsigned int idtv_info_field;
    2.10 +
    2.11 +    ASSERT(v == current);
    2.12 +
    2.13 +    idtv_info_field = __vmread(IDT_VECTORING_INFO_FIELD);
    2.14 +
    2.15 +    return (v->arch.hvm_vmx.vector_injected ||
    2.16 +            (idtv_info_field & INTR_INFO_VALID_MASK));
    2.17 +}
    2.18 +
    2.19  /* Setup HVM interfaces */
    2.20  static void vmx_setup_hvm_funcs(void)
    2.21  {
    2.22 @@ -1025,6 +1037,8 @@ static void vmx_setup_hvm_funcs(void)
    2.23      hvm_funcs.init_ap_context = vmx_init_ap_context;
    2.24  
    2.25      hvm_funcs.init_hypercall_page = vmx_init_hypercall_page;
    2.26 +
    2.27 +    hvm_funcs.injection_pending = vmx_injection_pending;
    2.28  }
    2.29  
    2.30  int start_vmx(void)
     3.1 --- a/xen/arch/x86/mm/shadow/multi.c	Thu Feb 22 12:21:29 2007 +0000
     3.2 +++ b/xen/arch/x86/mm/shadow/multi.c	Thu Feb 22 12:49:44 2007 +0000
     3.3 @@ -2901,18 +2901,35 @@ static int sh_page_fault(struct vcpu *v,
     3.4          goto not_a_shadow_fault;
     3.5  
     3.6      if ( is_hvm_domain(d) )
     3.7 +    {
     3.8 +        /*
     3.9 +         * If we are in the middle of injecting an exception or interrupt then
    3.10 +         * we should not emulate: it is not the instruction at %eip that caused
    3.11 +         * the fault. Furthermore it is almost certainly the case the handler
    3.12 +         * stack is currently considered to be a page table, so we should
    3.13 +         * unshadow the faulting page before exiting.
    3.14 +         */
    3.15 +        if ( hvm_injection_pending(v) )
    3.16 +        {
    3.17 +            gdprintk(XENLOG_DEBUG, "write to pagetable during event "
    3.18 +                     "injection: cr2=%#lx, mfn=%#lx\n", 
    3.19 +                     va, mfn_x(gmfn));
    3.20 +            sh_remove_shadows(v, gmfn, 0 /* thorough */, 1 /* must succeed */);
    3.21 +            goto done;
    3.22 +        }
    3.23 +
    3.24          hvm_store_cpu_guest_regs(v, regs, NULL);
    3.25 +    }
    3.26 +
    3.27      SHADOW_PRINTK("emulate: eip=%#lx esp=%#lx\n", 
    3.28                    (unsigned long)regs->eip, (unsigned long)regs->esp);
    3.29  
    3.30 -    /* Check whether this looks like a stack operation. */
    3.31 +    /*
    3.32 +     * Check whether this looks like a stack operation.
    3.33 +     * If so, forcibly unshadow and return.
    3.34 +     */
    3.35      if ( (va & PAGE_MASK) == (regs->esp & PAGE_MASK) )
    3.36      {
    3.37 -        /* Forcibly unshadow and return.  It's important to do this before
    3.38 -         * we emulate: if the faulting stack operation was the guest handling
    3.39 -         * an interrupt, then 
    3.40 -         * (a) the instruction at %eip is irrelevant; and
    3.41 -         * (b) we might inject some other fault and mask the real one */
    3.42          gdprintk(XENLOG_DEBUG, "guest stack is on a shadowed frame: "
    3.43                   "%%esp=%#lx, cr2=%#lx, mfn=%#lx\n", 
    3.44                   (unsigned long)regs->esp, va, mfn_x(gmfn));
     4.1 --- a/xen/include/asm-x86/hvm/hvm.h	Thu Feb 22 12:21:29 2007 +0000
     4.2 +++ b/xen/include/asm-x86/hvm/hvm.h	Thu Feb 22 12:49:44 2007 +0000
     4.3 @@ -134,6 +134,8 @@ struct hvm_function_table {
     4.4                              int vcpuid, int trampoline_vector);
     4.5  
     4.6      void (*init_hypercall_page)(struct domain *d, void *hypercall_page);
     4.7 +
     4.8 +    int  (*injection_pending)(struct vcpu *v);
     4.9  };
    4.10  
    4.11  extern struct hvm_function_table hvm_funcs;
    4.12 @@ -262,4 +264,9 @@ hvm_inject_exception(unsigned int trapnr
    4.13  
    4.14  int hvm_bringup_ap(int vcpuid, int trampoline_vector);
    4.15  
    4.16 +static inline int hvm_injection_pending(struct vcpu *v)
    4.17 +{
    4.18 +    return hvm_funcs.injection_pending(v);
    4.19 +}
    4.20 +
    4.21  #endif /* __ASM_X86_HVM_HVM_H__ */