# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxx
# Node ID dd754654d4273ceb4bdaeba96e24152f6a7fe3c5
# Parent 4f03592bc7f5b4bca5744cee298607dde2576ff6
Better fix for flushing conflicting batched ptwr state
before emulating a PT access.
Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
diff -r 4f03592bc7f5 -r dd754654d427 xen/arch/x86/mm.c
--- a/xen/arch/x86/mm.c Mon Nov 14 17:27:11 2005
+++ b/xen/arch/x86/mm.c Mon Nov 14 18:45:32 2005
@@ -3063,7 +3063,7 @@
unsigned int bytes,
unsigned int do_cmpxchg)
{
- unsigned long pfn;
+ unsigned long pfn, l1va;
struct pfn_info *page;
l1_pgentry_t pte, ol1e, nl1e, *pl1e;
struct domain *d = current->domain;
@@ -3100,6 +3100,17 @@
old |= full;
}
+ /*
+ * We must not emulate an update to a PTE that is temporarily marked
+ * writable by the batched ptwr logic, else we can corrupt page refcnts!
+ */
+ if ( ((l1va = d->arch.ptwr[PTWR_PT_ACTIVE].l1va) != 0) &&
+ (l1_linear_offset(l1va) == l1_linear_offset(addr)) )
+ ptwr_flush(d, PTWR_PT_ACTIVE);
+ if ( ((l1va = d->arch.ptwr[PTWR_PT_INACTIVE].l1va) != 0) &&
+ (l1_linear_offset(l1va) == l1_linear_offset(addr)) )
+ ptwr_flush(d, PTWR_PT_INACTIVE);
+
/* Read the PTE that maps the page being updated. */
if (__copy_from_user(&pte, &linear_pg_table[l1_linear_offset(addr)],
sizeof(pte)))
@@ -3358,13 +3369,6 @@
return EXCRET_fault_fixed;
emulate:
- /*
- * Cleaning up avoids emulating an update to a PTE that is temporarily
- * marked writable (_PAGE_RW) by the batched ptwr logic. If this were
- * performance critical then the check could compare addr against l1va's in
- * ptwr_emulated_update(). Without this flush we can corrupt page refcnts!
- */
- cleanup_writable_pagetable(d);
if ( x86_emulate_memop(guest_cpu_user_regs(), addr,
&ptwr_mem_emulator, BITS_PER_LONG/8) )
return 0;
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|