ChangeSet 1.1385, 2005/04/26 10:31:16+01:00, kaf24@xxxxxxxxxxxxxxxxxxxx
Simple batched writable p.t. support for multi-processor guests.
Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
arch/x86/mm.c | 38 +++++++++++++++++++++++++++-----------
include/asm-x86/mm.h | 2 ++
2 files changed, 29 insertions(+), 11 deletions(-)
diff -Nru a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c
--- a/xen/arch/x86/mm.c 2005-04-26 06:03:15 -04:00
+++ b/xen/arch/x86/mm.c 2005-04-26 06:03:15 -04:00
@@ -2477,9 +2477,11 @@
int i;
unsigned int modified = 0;
- // not supported in combination with various shadow modes!
- ASSERT( !shadow_mode_enabled(d) );
-
+ ASSERT(!shadow_mode_enabled(d));
+
+ if ( unlikely(d->arch.ptwr[which].ed != current) )
+ write_ptbase(d->arch.ptwr[which].ed);
+
l1va = d->arch.ptwr[which].l1va;
ptep = (unsigned long *)&linear_pg_table[l1_linear_offset(l1va)];
@@ -2513,7 +2515,7 @@
/* Ensure that there are no stale writable mappings in any TLB. */
/* NB. INVLPG is a serialising instruction: flushes pending updates. */
- local_flush_tlb_one(l1va); /* XXX Multi-CPU guests? */
+ flush_tlb_one_mask(d->cpuset, l1va);
PTWR_PRINTK("[%c] disconnected_l1va at %p now %lx\n",
PTWR_PRINT_WHICH, ptep, pte);
@@ -2579,6 +2581,9 @@
*/
d->arch.ptwr[which].l1va = 0;
+
+ if ( unlikely(d->arch.ptwr[which].ed != current) )
+ write_ptbase(current);
}
static int ptwr_emulated_update(
@@ -2741,7 +2746,7 @@
page = &frame_table[pfn];
/* We are looking only for read-only mappings of p.t. pages. */
- if ( ((l1e_get_flags(pte) & (_PAGE_RW | _PAGE_PRESENT)) != _PAGE_PRESENT)
||
+ if ( ((l1e_get_flags(pte) & (_PAGE_RW|_PAGE_PRESENT)) != _PAGE_PRESENT) ||
((page->u.inuse.type_info & PGT_type_mask) != PGT_l1_page_table) ||
(page_get_owner(page) != d) )
{
@@ -2753,10 +2758,6 @@
goto emulate;
#endif
- /* Writable pagetables are not yet SMP safe. Use emulator for now. */
- if ( d->exec_domain[0]->ed_next_list != NULL )
- goto emulate;
-
/* Get the L2 index at which this L1 p.t. is always mapped. */
l2_idx = page->u.inuse.type_info & PGT_va_mask;
if ( unlikely(l2_idx >= PGT_va_unknown) )
@@ -2785,7 +2786,21 @@
(l2_idx == d->arch.ptwr[PTWR_PT_ACTIVE].l2_idx)) )
which = PTWR_PT_ACTIVE;
}
-
+
+ /*
+ * If this is a multi-processor guest then ensure that the page is hooked
+ * into at most one L2 table, which must be the one running on this VCPU.
+ */
+ if ( (d->exec_domain[0]->ed_next_list != NULL) &&
+ ((page->u.inuse.type_info & PGT_count_mask) !=
+ (!!(page->u.inuse.type_info & PGT_pinned) +
+ (which == PTWR_PT_ACTIVE))) )
+ {
+ /* Could be conflicting writable mappings from other VCPUs. */
+ cleanup_writable_pagetable(d);
+ goto emulate;
+ }
+
PTWR_PRINTK("[%c] page_fault on l1 pt at va %lx, pt for %08x, "
"pfn %lx\n", PTWR_PRINT_WHICH,
addr, l2_idx << L2_PAGETABLE_SHIFT, pfn);
@@ -2810,12 +2825,13 @@
d->arch.ptwr[which].l1va = addr | 1;
d->arch.ptwr[which].l2_idx = l2_idx;
+ d->arch.ptwr[which].ed = current;
/* For safety, disconnect the L1 p.t. page from current space. */
if ( which == PTWR_PT_ACTIVE )
{
l2e_remove_flags(pl2e, _PAGE_PRESENT);
- local_flush_tlb(); /* XXX Multi-CPU guests? */
+ flush_tlb_mask(d->cpuset);
}
/* Temporarily map the L1 page, and make a copy of it. */
diff -Nru a/xen/include/asm-x86/mm.h b/xen/include/asm-x86/mm.h
--- a/xen/include/asm-x86/mm.h 2005-04-26 06:03:15 -04:00
+++ b/xen/include/asm-x86/mm.h 2005-04-26 06:03:15 -04:00
@@ -301,6 +301,8 @@
unsigned int l2_idx; /* NB. Only used for PTWR_PT_ACTIVE. */
/* Info about last ptwr update batch. */
unsigned int prev_nr_updates;
+ /* Exec domain which created writable mapping. */
+ struct exec_domain *ed;
};
#define PTWR_PT_ACTIVE 0
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|