debuggers.hg
changeset 19983:faa216e744ad
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@novell.com>
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@novell.com>
author | Keir Fraser <keir.fraser@citrix.com> |
---|---|
date | Wed Jul 15 13:07:30 2009 +0100 (2009-07-15) |
parents | 034e015088ac |
children | 91407452cdb6 |
files | xen/arch/x86/mm.c |
line diff
1.1 --- a/xen/arch/x86/mm.c Wed Jul 15 10:31:50 2009 +0100 1.2 +++ b/xen/arch/x86/mm.c Wed Jul 15 13:07:30 2009 +0100 1.3 @@ -1159,10 +1159,9 @@ static int alloc_l1_table(struct page_in 1.4 static int create_pae_xen_mappings(struct domain *d, l3_pgentry_t *pl3e) 1.5 { 1.6 struct page_info *page; 1.7 - l2_pgentry_t *pl2e; 1.8 l3_pgentry_t l3e3; 1.9 -#ifndef CONFIG_COMPAT 1.10 - l2_pgentry_t l2e; 1.11 +#ifdef __i386__ 1.12 + l2_pgentry_t *pl2e, l2e; 1.13 int i; 1.14 #endif 1.15 1.16 @@ -1198,17 +1197,9 @@ static int create_pae_xen_mappings(struc 1.17 return 0; 1.18 } 1.19 1.20 - /* Xen private mappings. */ 1.21 +#ifdef __i386__ 1.22 + /* Xen linear pagetable mappings. */ 1.23 pl2e = map_domain_page(l3e_get_pfn(l3e3)); 1.24 -#ifndef CONFIG_COMPAT 1.25 - memcpy(&pl2e[L2_PAGETABLE_FIRST_XEN_SLOT & (L2_PAGETABLE_ENTRIES-1)], 1.26 - &idle_pg_table_l2[L2_PAGETABLE_FIRST_XEN_SLOT], 1.27 - L2_PAGETABLE_XEN_SLOTS * sizeof(l2_pgentry_t)); 1.28 - for ( i = 0; i < PDPT_L2_ENTRIES; i++ ) 1.29 - { 1.30 - l2e = l2e_from_page(perdomain_pt_page(d, i), __PAGE_HYPERVISOR); 1.31 - l2e_write(&pl2e[l2_table_offset(PERDOMAIN_VIRT_START) + i], l2e); 1.32 - } 1.33 for ( i = 0; i < (LINEARPT_MBYTES >> (L2_PAGETABLE_SHIFT - 20)); i++ ) 1.34 { 1.35 l2e = l2e_empty(); 1.36 @@ -1216,13 +1207,8 @@ static int create_pae_xen_mappings(struc 1.37 l2e = l2e_from_pfn(l3e_get_pfn(pl3e[i]), __PAGE_HYPERVISOR); 1.38 l2e_write(&pl2e[l2_table_offset(LINEAR_PT_VIRT_START) + i], l2e); 1.39 } 1.40 -#else 1.41 - memcpy(&pl2e[COMPAT_L2_PAGETABLE_FIRST_XEN_SLOT(d)], 1.42 - &compat_idle_pg_table_l2[ 1.43 - l2_table_offset(HIRO_COMPAT_MPT_VIRT_START)], 1.44 - COMPAT_L2_PAGETABLE_XEN_SLOTS(d) * sizeof(*pl2e)); 1.45 + unmap_domain_page(pl2e); 1.46 #endif 1.47 - unmap_domain_page(pl2e); 1.48 1.49 return 1; 1.50 } 1.51 @@ -1315,6 +1301,27 @@ static int alloc_l2_table(struct page_in 1.52 adjust_guest_l2e(pl2e[i], d); 1.53 } 1.54 1.55 + if ( rc >= 0 && (type & PGT_pae_xen_l2) ) 1.56 + { 1.57 + /* Xen private mappings. */ 1.58 +#if defined(__i386__) 1.59 + memcpy(&pl2e[L2_PAGETABLE_FIRST_XEN_SLOT & (L2_PAGETABLE_ENTRIES-1)], 1.60 + &idle_pg_table_l2[L2_PAGETABLE_FIRST_XEN_SLOT], 1.61 + L2_PAGETABLE_XEN_SLOTS * sizeof(l2_pgentry_t)); 1.62 + for ( i = 0; i < PDPT_L2_ENTRIES; i++ ) 1.63 + l2e_write(&pl2e[l2_table_offset(PERDOMAIN_VIRT_START) + i], 1.64 + l2e_from_page(perdomain_pt_page(d, i), 1.65 + __PAGE_HYPERVISOR)); 1.66 + pl2e[l2_table_offset(LINEAR_PT_VIRT_START)] = 1.67 + l2e_from_pfn(pfn, __PAGE_HYPERVISOR); 1.68 +#elif defined(CONFIG_COMPAT) 1.69 + memcpy(&pl2e[COMPAT_L2_PAGETABLE_FIRST_XEN_SLOT(d)], 1.70 + &compat_idle_pg_table_l2[ 1.71 + l2_table_offset(HIRO_COMPAT_MPT_VIRT_START)], 1.72 + COMPAT_L2_PAGETABLE_XEN_SLOTS(d) * sizeof(*pl2e)); 1.73 +#endif 1.74 + } 1.75 + 1.76 unmap_domain_page(pl2e); 1.77 return rc > 0 ? 0 : rc; 1.78 }