ia64/xen-unstable

changeset 14082:9e35371a3caa

x86: Detect shadow-emulate write to stack from inside the write
handler, where we can quite conveniently check whether the access
segment is SS. This will only give a false positive for non-stack
writes that override the destination segment to SS, which it is
probably safe to assume will never happen when the destination is a
legitimate page table!

For now, instead of bailing and unshadowing just increment a perfctr
and we'll see if that increases fast under any reasonable workload.

Signed-off-by: Keir Fraser <keir@xensource.com>
author kfraser@localhost.localdomain
date Thu Feb 22 15:22:16 2007 +0000 (2007-02-22)
parents 644e9e18d2ef
children 3746b3d4f301
files xen/arch/x86/mm/shadow/common.c xen/arch/x86/mm/shadow/multi.c xen/include/asm-x86/perfc_defn.h
line diff
     1.1 --- a/xen/arch/x86/mm/shadow/common.c	Thu Feb 22 14:58:26 2007 +0000
     1.2 +++ b/xen/arch/x86/mm/shadow/common.c	Thu Feb 22 15:22:16 2007 +0000
     1.3 @@ -275,6 +275,10 @@ hvm_emulate_write(enum x86_segment seg,
     1.4      unsigned long addr;
     1.5      int rc;
     1.6  
     1.7 +    /* How many emulations could we save if we unshadowed on stack writes? */
     1.8 +    if ( seg == x86_seg_ss )
     1.9 +        perfc_incrc(shadow_fault_emulate_stack);
    1.10 +
    1.11      rc = hvm_translate_linear_addr(
    1.12          seg, offset, bytes, hvm_access_write, sh_ctxt, &addr);
    1.13      if ( rc )
     2.1 --- a/xen/arch/x86/mm/shadow/multi.c	Thu Feb 22 14:58:26 2007 +0000
     2.2 +++ b/xen/arch/x86/mm/shadow/multi.c	Thu Feb 22 15:22:16 2007 +0000
     2.3 @@ -2924,23 +2924,6 @@ static int sh_page_fault(struct vcpu *v,
     2.4      SHADOW_PRINTK("emulate: eip=%#lx esp=%#lx\n", 
     2.5                    (unsigned long)regs->eip, (unsigned long)regs->esp);
     2.6  
     2.7 -    /*
     2.8 -     * Check whether this looks like a stack operation. If so, unshadow the
     2.9 -     * faulting page. We can allow this to fail: if it does fail then we
    2.10 -     * carry on and emulate, otherwise we bail immediately. Failure is
    2.11 -     * tolerated because this is only a heuristic (e.g., stack segment base
    2.12 -     * address is ignored).
    2.13 -     */
    2.14 -    if ( unlikely((va & PAGE_MASK) == (regs->esp & PAGE_MASK)) )
    2.15 -    {
    2.16 -        gdprintk(XENLOG_DEBUG, "guest stack is on a shadowed frame: "
    2.17 -                 "%%esp=%#lx, cr2=%#lx, mfn=%#lx\n", 
    2.18 -                 (unsigned long)regs->esp, va, mfn_x(gmfn));
    2.19 -        sh_remove_shadows(v, gmfn, 0 /* thorough */, 0 /* can fail */);
    2.20 -        if ( !(mfn_to_page(gmfn)->count_info & PGC_page_table) )
    2.21 -            goto done;
    2.22 -    }
    2.23 -
    2.24      emul_ops = shadow_init_emulation(&emul_ctxt, regs);
    2.25  
    2.26      /*
     3.1 --- a/xen/include/asm-x86/perfc_defn.h	Thu Feb 22 14:58:26 2007 +0000
     3.2 +++ b/xen/include/asm-x86/perfc_defn.h	Thu Feb 22 15:22:16 2007 +0000
     3.3 @@ -56,6 +56,7 @@ PERFCOUNTER_CPU(shadow_fault_bail_user_s
     3.4  PERFCOUNTER_CPU(shadow_fault_emulate_read, "shadow_fault emulates a read")
     3.5  PERFCOUNTER_CPU(shadow_fault_emulate_write, "shadow_fault emulates a write")
     3.6  PERFCOUNTER_CPU(shadow_fault_emulate_failed, "shadow_fault emulator fails")
     3.7 +PERFCOUNTER_CPU(shadow_fault_emulate_stack, "shadow_fault emulate stack write")
     3.8  PERFCOUNTER_CPU(shadow_fault_mmio,     "shadow_fault handled as mmio")
     3.9  PERFCOUNTER_CPU(shadow_fault_fixed,    "shadow_fault fixed fault")
    3.10  PERFCOUNTER_CPU(shadow_ptwr_emulate,   "shadow causes ptwr to emulate")