# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1247660810 -3600
# Node ID 22ef8e900a6d126f908fdd406754515558d1aa0a
# Parent 466708397aac442fe29b519dd09e4ac56ddc5f0d
i386: fix handling of Xen entries in final L2 page table
Running Xen on top of KVM exposed an issue that latently also exists
on real hardware: So far, updating any L3 entry resulted in the Xen
owned part of the L2 table referenced by the final L3 one to be re-
initialized. This was not only unnecessary, it actually resulted in
Xen relying on the TLB entry which maps the L2 page that's being
updated not going away intermediately, since as a first step the full
range of Xen owned entries in the L2 were replaced by the respective
ones from the idle page table, and only then the per-domain entries
got re- written to their intended values.
This part of the initialization really is sufficient to be done once,
when the page becomes an L2-with-Xen-entries (PGT_pae_xen_l2) one,
i.e. can be moved to alloc_l2_table(). Only the linear page table
setup has to remain where it always was.
Signed-off-by: Jan Beulich <jbeulich@xxxxxxxxxx>
xen-unstable changeset: 19945:faa216e744ad
xen-unstable date: Wed Jul 15 13:07:30 2009 +0100
---
xen/arch/x86/mm.c | 47 ++++++++++++++++++++++++++---------------------
1 files changed, 26 insertions(+), 21 deletions(-)
diff -r 466708397aac -r 22ef8e900a6d xen/arch/x86/mm.c
--- a/xen/arch/x86/mm.c Wed Jul 15 09:17:04 2009 +0100
+++ b/xen/arch/x86/mm.c Wed Jul 15 13:26:50 2009 +0100
@@ -1145,10 +1145,9 @@ static int create_pae_xen_mappings(struc
static int create_pae_xen_mappings(struct domain *d, l3_pgentry_t *pl3e)
{
struct page_info *page;
- l2_pgentry_t *pl2e;
l3_pgentry_t l3e3;
-#ifndef CONFIG_COMPAT
- l2_pgentry_t l2e;
+#ifdef __i386__
+ l2_pgentry_t *pl2e, l2e;
int i;
#endif
@@ -1184,19 +1183,9 @@ static int create_pae_xen_mappings(struc
return 0;
}
- /* Xen private mappings. */
+#ifdef __i386__
+ /* Xen linear pagetable mappings. */
pl2e = map_domain_page(l3e_get_pfn(l3e3));
-#ifndef CONFIG_COMPAT
- memcpy(&pl2e[L2_PAGETABLE_FIRST_XEN_SLOT & (L2_PAGETABLE_ENTRIES-1)],
- &idle_pg_table_l2[L2_PAGETABLE_FIRST_XEN_SLOT],
- L2_PAGETABLE_XEN_SLOTS * sizeof(l2_pgentry_t));
- for ( i = 0; i < PDPT_L2_ENTRIES; i++ )
- {
- l2e = l2e_from_page(
- virt_to_page(d->arch.mm_perdomain_pt) + i,
- __PAGE_HYPERVISOR);
- l2e_write(&pl2e[l2_table_offset(PERDOMAIN_VIRT_START) + i], l2e);
- }
for ( i = 0; i < (LINEARPT_MBYTES >> (L2_PAGETABLE_SHIFT - 20)); i++ )
{
l2e = l2e_empty();
@@ -1204,13 +1193,8 @@ static int create_pae_xen_mappings(struc
l2e = l2e_from_pfn(l3e_get_pfn(pl3e[i]), __PAGE_HYPERVISOR);
l2e_write(&pl2e[l2_table_offset(LINEAR_PT_VIRT_START) + i], l2e);
}
-#else
- memcpy(&pl2e[COMPAT_L2_PAGETABLE_FIRST_XEN_SLOT(d)],
- &compat_idle_pg_table_l2[
- l2_table_offset(HIRO_COMPAT_MPT_VIRT_START)],
- COMPAT_L2_PAGETABLE_XEN_SLOTS(d) * sizeof(*pl2e));
+ unmap_domain_page(pl2e);
#endif
- unmap_domain_page(pl2e);
return 1;
}
@@ -1301,6 +1285,27 @@ static int alloc_l2_table(struct page_in
}
adjust_guest_l2e(pl2e[i], d);
+ }
+
+ if ( rc >= 0 && (type & PGT_pae_xen_l2) )
+ {
+ /* Xen private mappings. */
+#if defined(__i386__)
+ memcpy(&pl2e[L2_PAGETABLE_FIRST_XEN_SLOT & (L2_PAGETABLE_ENTRIES-1)],
+ &idle_pg_table_l2[L2_PAGETABLE_FIRST_XEN_SLOT],
+ L2_PAGETABLE_XEN_SLOTS * sizeof(l2_pgentry_t));
+ for ( i = 0; i < PDPT_L2_ENTRIES; i++ )
+ l2e_write(&pl2e[l2_table_offset(PERDOMAIN_VIRT_START) + i],
+ l2e_from_page(virt_to_page(d->arch.mm_perdomain_pt) + i,
+ __PAGE_HYPERVISOR));
+ pl2e[l2_table_offset(LINEAR_PT_VIRT_START)] =
+ l2e_from_pfn(pfn, __PAGE_HYPERVISOR);
+#elif defined(CONFIG_COMPAT)
+ memcpy(&pl2e[COMPAT_L2_PAGETABLE_FIRST_XEN_SLOT(d)],
+ &compat_idle_pg_table_l2[
+ l2_table_offset(HIRO_COMPAT_MPT_VIRT_START)],
+ COMPAT_L2_PAGETABLE_XEN_SLOTS(d) * sizeof(*pl2e));
+#endif
}
unmap_domain_page(pl2e);
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|