ia64/xen-unstable

changeset 14080:c0b1a3b54548

hvm: Turn stack-pointer comparison on shadow-emulate path into a
heuristic which we can allow to fail.
Signed-off-by: Keir Fraser <keir@xensource.com>
author kfraser@localhost.localdomain
date Thu Feb 22 13:03:49 2007 +0000 (2007-02-22)
parents 3f7e8c763b55
children 644e9e18d2ef
files xen/arch/x86/mm/shadow/multi.c
line diff
     1.1 --- a/xen/arch/x86/mm/shadow/multi.c	Thu Feb 22 12:49:44 2007 +0000
     1.2 +++ b/xen/arch/x86/mm/shadow/multi.c	Thu Feb 22 13:03:49 2007 +0000
     1.3 @@ -2909,7 +2909,7 @@ static int sh_page_fault(struct vcpu *v,
     1.4           * stack is currently considered to be a page table, so we should
     1.5           * unshadow the faulting page before exiting.
     1.6           */
     1.7 -        if ( hvm_injection_pending(v) )
     1.8 +        if ( unlikely(hvm_injection_pending(v)) )
     1.9          {
    1.10              gdprintk(XENLOG_DEBUG, "write to pagetable during event "
    1.11                       "injection: cr2=%#lx, mfn=%#lx\n", 
    1.12 @@ -2925,16 +2925,20 @@ static int sh_page_fault(struct vcpu *v,
    1.13                    (unsigned long)regs->eip, (unsigned long)regs->esp);
    1.14  
    1.15      /*
    1.16 -     * Check whether this looks like a stack operation.
    1.17 -     * If so, forcibly unshadow and return.
    1.18 +     * Check whether this looks like a stack operation. If so, unshadow the
    1.19 +     * faulting page. We can allow this to fail: if it does fail then we
    1.20 +     * carry on and emulate, otherwise we bail immediately. Failure is
    1.21 +     * tolerated because this is only a heuristic (e.g., stack segment base
    1.22 +     * address is ignored).
    1.23       */
    1.24 -    if ( (va & PAGE_MASK) == (regs->esp & PAGE_MASK) )
    1.25 +    if ( unlikely((va & PAGE_MASK) == (regs->esp & PAGE_MASK)) )
    1.26      {
    1.27          gdprintk(XENLOG_DEBUG, "guest stack is on a shadowed frame: "
    1.28                   "%%esp=%#lx, cr2=%#lx, mfn=%#lx\n", 
    1.29                   (unsigned long)regs->esp, va, mfn_x(gmfn));
    1.30 -        sh_remove_shadows(v, gmfn, 0 /* thorough */, 1 /* must succeed */);
    1.31 -        goto done;
    1.32 +        sh_remove_shadows(v, gmfn, 0 /* thorough */, 0 /* can fail */);
    1.33 +        if ( !(mfn_to_page(gmfn)->count_info & PGC_page_table) )
    1.34 +            goto done;
    1.35      }
    1.36  
    1.37      emul_ops = shadow_init_emulation(&emul_ctxt, regs);