# HG changeset patch
# User kfraser@xxxxxxxxxxxxxxxxxxxxx
# Date 1172157736 0
# Node ID 9e35371a3caa3fa3be2af51f48c88c99932d6141
# Parent 644e9e18d2efbf4ad8f56f78e21a438e83302c79
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@xxxxxxxxxxxxx>
---
xen/arch/x86/mm/shadow/common.c | 4 ++++
xen/arch/x86/mm/shadow/multi.c | 17 -----------------
xen/include/asm-x86/perfc_defn.h | 1 +
3 files changed, 5 insertions(+), 17 deletions(-)
diff -r 644e9e18d2ef -r 9e35371a3caa xen/arch/x86/mm/shadow/common.c
--- a/xen/arch/x86/mm/shadow/common.c Thu Feb 22 14:58:26 2007 +0000
+++ b/xen/arch/x86/mm/shadow/common.c Thu Feb 22 15:22:16 2007 +0000
@@ -274,6 +274,10 @@ hvm_emulate_write(enum x86_segment seg,
struct vcpu *v = current;
unsigned long addr;
int rc;
+
+ /* How many emulations could we save if we unshadowed on stack writes? */
+ if ( seg == x86_seg_ss )
+ perfc_incrc(shadow_fault_emulate_stack);
rc = hvm_translate_linear_addr(
seg, offset, bytes, hvm_access_write, sh_ctxt, &addr);
diff -r 644e9e18d2ef -r 9e35371a3caa xen/arch/x86/mm/shadow/multi.c
--- a/xen/arch/x86/mm/shadow/multi.c Thu Feb 22 14:58:26 2007 +0000
+++ b/xen/arch/x86/mm/shadow/multi.c Thu Feb 22 15:22:16 2007 +0000
@@ -2924,23 +2924,6 @@ static int sh_page_fault(struct vcpu *v,
SHADOW_PRINTK("emulate: eip=%#lx esp=%#lx\n",
(unsigned long)regs->eip, (unsigned long)regs->esp);
- /*
- * Check whether this looks like a stack operation. If so, unshadow the
- * faulting page. We can allow this to fail: if it does fail then we
- * carry on and emulate, otherwise we bail immediately. Failure is
- * tolerated because this is only a heuristic (e.g., stack segment base
- * address is ignored).
- */
- if ( unlikely((va & PAGE_MASK) == (regs->esp & PAGE_MASK)) )
- {
- 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));
- sh_remove_shadows(v, gmfn, 0 /* thorough */, 0 /* can fail */);
- if ( !(mfn_to_page(gmfn)->count_info & PGC_page_table) )
- goto done;
- }
-
emul_ops = shadow_init_emulation(&emul_ctxt, regs);
/*
diff -r 644e9e18d2ef -r 9e35371a3caa xen/include/asm-x86/perfc_defn.h
--- a/xen/include/asm-x86/perfc_defn.h Thu Feb 22 14:58:26 2007 +0000
+++ b/xen/include/asm-x86/perfc_defn.h Thu Feb 22 15:22:16 2007 +0000
@@ -56,6 +56,7 @@ PERFCOUNTER_CPU(shadow_fault_emulate_rea
PERFCOUNTER_CPU(shadow_fault_emulate_read, "shadow_fault emulates a read")
PERFCOUNTER_CPU(shadow_fault_emulate_write, "shadow_fault emulates a write")
PERFCOUNTER_CPU(shadow_fault_emulate_failed, "shadow_fault emulator fails")
+PERFCOUNTER_CPU(shadow_fault_emulate_stack, "shadow_fault emulate stack write")
PERFCOUNTER_CPU(shadow_fault_mmio, "shadow_fault handled as mmio")
PERFCOUNTER_CPU(shadow_fault_fixed, "shadow_fault fixed fault")
PERFCOUNTER_CPU(shadow_ptwr_emulate, "shadow causes ptwr to emulate")
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|