[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] hvm: Do not take shadow-emulation path if we are trying to inject an
# HG changeset patch # User kfraser@xxxxxxxxxxxxxxxxxxxxx # Date 1172148584 0 # Node ID 3f7e8c763b55b0a805928adcd43d7e2ea321b3e4 # Parent 0a970a431bbcbf91162698580f6cbd7578fe8114 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@xxxxxxxxxxxxx> --- xen/arch/x86/hvm/svm/svm.c | 8 ++++++++ xen/arch/x86/hvm/vmx/vmx.c | 14 ++++++++++++++ xen/arch/x86/mm/shadow/multi.c | 29 +++++++++++++++++++++++------ xen/include/asm-x86/hvm/hvm.h | 7 +++++++ 4 files changed, 52 insertions(+), 6 deletions(-) diff -r 0a970a431bbc -r 3f7e8c763b55 xen/arch/x86/hvm/svm/svm.c --- a/xen/arch/x86/hvm/svm/svm.c Thu Feb 22 12:21:29 2007 +0000 +++ b/xen/arch/x86/hvm/svm/svm.c Thu Feb 22 12:49:44 2007 +0000 @@ -982,6 +982,12 @@ static void svm_hvm_inject_exception( v->arch.hvm_svm.vmcb->cr2 = v->arch.hvm_svm.cpu_cr2 = cr2; } +static int svm_injection_pending(struct vcpu *v) +{ + struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb; + return (vmcb->vintr.fields.irq || vmcb->exitintinfo.fields.v); +} + int start_svm(void) { u32 eax, ecx, edx; @@ -1057,6 +1063,8 @@ int start_svm(void) hvm_funcs.init_ap_context = svm_init_ap_context; hvm_funcs.init_hypercall_page = svm_init_hypercall_page; + + hvm_funcs.injection_pending = svm_injection_pending; hvm_enable(); diff -r 0a970a431bbc -r 3f7e8c763b55 xen/arch/x86/hvm/vmx/vmx.c --- a/xen/arch/x86/hvm/vmx/vmx.c Thu Feb 22 12:21:29 2007 +0000 +++ b/xen/arch/x86/hvm/vmx/vmx.c Thu Feb 22 12:49:44 2007 +0000 @@ -990,6 +990,18 @@ static void vmx_update_vtpr(struct vcpu /* VMX doesn't have a V_TPR field */ } +static int vmx_injection_pending(struct vcpu *v) +{ + unsigned int idtv_info_field; + + ASSERT(v == current); + + idtv_info_field = __vmread(IDT_VECTORING_INFO_FIELD); + + return (v->arch.hvm_vmx.vector_injected || + (idtv_info_field & INTR_INFO_VALID_MASK)); +} + /* Setup HVM interfaces */ static void vmx_setup_hvm_funcs(void) { @@ -1025,6 +1037,8 @@ static void vmx_setup_hvm_funcs(void) hvm_funcs.init_ap_context = vmx_init_ap_context; hvm_funcs.init_hypercall_page = vmx_init_hypercall_page; + + hvm_funcs.injection_pending = vmx_injection_pending; } int start_vmx(void) diff -r 0a970a431bbc -r 3f7e8c763b55 xen/arch/x86/mm/shadow/multi.c --- a/xen/arch/x86/mm/shadow/multi.c Thu Feb 22 12:21:29 2007 +0000 +++ b/xen/arch/x86/mm/shadow/multi.c Thu Feb 22 12:49:44 2007 +0000 @@ -2901,18 +2901,35 @@ static int sh_page_fault(struct vcpu *v, goto not_a_shadow_fault; if ( is_hvm_domain(d) ) + { + /* + * If we are in the middle of injecting an exception or interrupt then + * we should not emulate: it is not the instruction at %eip that caused + * the fault. Furthermore it is almost certainly the case the handler + * stack is currently considered to be a page table, so we should + * unshadow the faulting page before exiting. + */ + if ( hvm_injection_pending(v) ) + { + gdprintk(XENLOG_DEBUG, "write to pagetable during event " + "injection: cr2=%#lx, mfn=%#lx\n", + va, mfn_x(gmfn)); + sh_remove_shadows(v, gmfn, 0 /* thorough */, 1 /* must succeed */); + goto done; + } + hvm_store_cpu_guest_regs(v, regs, NULL); + } + SHADOW_PRINTK("emulate: eip=%#lx esp=%#lx\n", (unsigned long)regs->eip, (unsigned long)regs->esp); - /* Check whether this looks like a stack operation. */ + /* + * Check whether this looks like a stack operation. + * If so, forcibly unshadow and return. + */ if ( (va & PAGE_MASK) == (regs->esp & PAGE_MASK) ) { - /* Forcibly unshadow and return. It's important to do this before - * we emulate: if the faulting stack operation was the guest handling - * an interrupt, then - * (a) the instruction at %eip is irrelevant; and - * (b) we might inject some other fault and mask the real one */ gdprintk(XENLOG_DEBUG, "guest stack is on a shadowed frame: " "%%esp=%#lx, cr2=%#lx, mfn=%#lx\n", (unsigned long)regs->esp, va, mfn_x(gmfn)); diff -r 0a970a431bbc -r 3f7e8c763b55 xen/include/asm-x86/hvm/hvm.h --- a/xen/include/asm-x86/hvm/hvm.h Thu Feb 22 12:21:29 2007 +0000 +++ b/xen/include/asm-x86/hvm/hvm.h Thu Feb 22 12:49:44 2007 +0000 @@ -134,6 +134,8 @@ struct hvm_function_table { int vcpuid, int trampoline_vector); void (*init_hypercall_page)(struct domain *d, void *hypercall_page); + + int (*injection_pending)(struct vcpu *v); }; extern struct hvm_function_table hvm_funcs; @@ -262,4 +264,9 @@ hvm_inject_exception(unsigned int trapnr int hvm_bringup_ap(int vcpuid, int trampoline_vector); +static inline int hvm_injection_pending(struct vcpu *v) +{ + return hvm_funcs.injection_pending(v); +} + #endif /* __ASM_X86_HVM_HVM_H__ */ _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |