[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] x86: Improve zap_low_mappings.
# HG changeset patch # User Keir Fraser <keir@xxxxxxxxxxxxx> # Date 1178968021 -3600 # Node ID 03a13457d9938c88a54d5eafaa290ca8a11c53c0 # Parent 759d924af6d8ca99bf04b150dc491b23d80936b0 x86: Improve zap_low_mappings. Do it earlier on x86/64, properly free non-superpages on x86/32, and leave a mapping of the boot trampoline (0x90000-0xA0000) in place. Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx> --- xen/arch/x86/domain_build.c | 1 xen/arch/x86/mm.c | 79 ++++++++++++++++++++++++++++++++++++++++++++ xen/arch/x86/setup.c | 5 ++ xen/arch/x86/smpboot.c | 3 - xen/arch/x86/x86_32/mm.c | 31 +++++++---------- xen/arch/x86/x86_64/mm.c | 14 ++++--- xen/include/asm-x86/page.h | 2 - 7 files changed, 107 insertions(+), 28 deletions(-) diff -r 759d924af6d8 -r 03a13457d993 xen/arch/x86/domain_build.c --- a/xen/arch/x86/domain_build.c Sat May 12 10:28:53 2007 +0100 +++ b/xen/arch/x86/domain_build.c Sat May 12 12:07:01 2007 +0100 @@ -902,7 +902,6 @@ int __init construct_dom0( #if defined(__i386__) /* Destroy low mappings - they were only for our convenience. */ zap_low_mappings(l2start); - zap_low_mappings(idle_pg_table_l2); #endif update_domain_wallclock_time(d); diff -r 759d924af6d8 -r 03a13457d993 xen/arch/x86/mm.c --- a/xen/arch/x86/mm.c Sat May 12 10:28:53 2007 +0100 +++ b/xen/arch/x86/mm.c Sat May 12 12:07:01 2007 +0100 @@ -3402,6 +3402,18 @@ int ptwr_do_page_fault(struct vcpu *v, u return 0; } +void free_xen_pagetable(void *v) +{ + extern int early_boot; + + BUG_ON(early_boot); + + if ( is_xen_heap_frame(virt_to_page(v)) ) + free_xenheap_page(v); + else + free_domheap_page(virt_to_page(v)); +} + int map_pages_to_xen( unsigned long virt, unsigned long mfn, @@ -3475,6 +3487,73 @@ int map_pages_to_xen( return 0; } +void destroy_xen_mappings(unsigned long s, unsigned long e) +{ + l2_pgentry_t *pl2e; + l1_pgentry_t *pl1e; + unsigned int i; + unsigned long v = s; + + ASSERT((s & ~PAGE_MASK) == 0); + ASSERT((e & ~PAGE_MASK) == 0); + + while ( v < e ) + { + pl2e = virt_to_xen_l2e(v); + + if ( !(l2e_get_flags(*pl2e) & _PAGE_PRESENT) ) + { + v += PAGE_SIZE; + continue; + } + + if ( l2e_get_flags(*pl2e) & _PAGE_PSE ) + { + if ( (l1_table_offset(v) == 0) && + ((e-v) >= (1UL << L2_PAGETABLE_SHIFT)) ) + { + /* PSE: whole superpage is destroyed. */ + l2e_write_atomic(pl2e, l2e_empty()); + v += 1UL << L2_PAGETABLE_SHIFT; + } + else + { + /* PSE: shatter the superpage and try again. */ + pl1e = alloc_xen_pagetable(); + for ( i = 0; i < L1_PAGETABLE_ENTRIES; i++ ) + l1e_write(&pl1e[i], + l1e_from_pfn(l2e_get_pfn(*pl2e) + i, + l2e_get_flags(*pl2e) & ~_PAGE_PSE)); + l2e_write_atomic(pl2e, l2e_from_pfn(virt_to_mfn(pl1e), + __PAGE_HYPERVISOR)); + } + } + else + { + /* Ordinary 4kB mapping. */ + pl1e = l2e_to_l1e(*pl2e) + l1_table_offset(v); + l1e_write_atomic(pl1e, l1e_empty()); + v += PAGE_SIZE; + + /* If we are done with the L2E, check if it is now empty. */ + if ( (v != e) && (l1_table_offset(v) != 0) ) + continue; + pl1e = l2e_to_l1e(*pl2e); + for ( i = 0; i < L1_PAGETABLE_ENTRIES; i++ ) + if ( l1e_get_intpte(pl1e[i]) != 0 ) + break; + if ( i == L1_PAGETABLE_ENTRIES ) + { + /* Empty: zap the L2E and free the L1 page. */ + l2e_write_atomic(pl2e, l2e_empty()); + free_xen_pagetable(pl1e); + } + } + } + + flush_tlb_all_pge(); +} + void __set_fixmap( enum fixed_addresses idx, unsigned long mfn, unsigned long flags) { diff -r 759d924af6d8 -r 03a13457d993 xen/arch/x86/setup.c --- a/xen/arch/x86/setup.c Sat May 12 10:28:53 2007 +0100 +++ b/xen/arch/x86/setup.c Sat May 12 12:07:01 2007 +0100 @@ -779,6 +779,11 @@ void __init __start_xen(multiboot_info_t if ( smp_found_config ) get_smp_config(); +#ifdef CONFIG_X86_64 + /* Low mappings were only needed for some BIOS table parsing. */ + zap_low_mappings(); +#endif + init_apic_mappings(); init_IRQ(); diff -r 759d924af6d8 -r 03a13457d993 xen/arch/x86/smpboot.c --- a/xen/arch/x86/smpboot.c Sat May 12 10:28:53 2007 +0100 +++ b/xen/arch/x86/smpboot.c Sat May 12 12:07:01 2007 +0100 @@ -1162,9 +1162,6 @@ void __init smp_cpus_done(unsigned int m #ifdef CONFIG_X86_IO_APIC setup_ioapic_dest(); #endif -#ifdef CONFIG_X86_64 - zap_low_mappings(); -#endif #ifndef CONFIG_HOTPLUG_CPU /* * Disable executability of the SMP trampoline: diff -r 759d924af6d8 -r 03a13457d993 xen/arch/x86/x86_32/mm.c --- a/xen/arch/x86/x86_32/mm.c Sat May 12 10:28:53 2007 +0100 +++ b/xen/arch/x86/x86_32/mm.c Sat May 12 12:07:01 2007 +0100 @@ -61,11 +61,6 @@ void *alloc_xen_pagetable(void) return mfn_to_virt(mfn); } -void free_xen_pagetable(void *v) -{ - free_xenheap_page(v); -} - l2_pgentry_t *virt_to_xen_l2e(unsigned long v) { return &idle_pg_table_l2[l2_linear_offset(v)]; @@ -141,22 +136,24 @@ void __init setup_idle_pagetable(void) __PAGE_HYPERVISOR)); } -void __init zap_low_mappings(l2_pgentry_t *base) +void __init zap_low_mappings(l2_pgentry_t *dom0_l2) { int i; - u32 addr; - - for ( i = 0; ; i++ ) - { - addr = i << L2_PAGETABLE_SHIFT; - if ( addr >= HYPERVISOR_VIRT_START ) - break; - if ( l2e_get_paddr(base[i]) != addr ) - continue; - l2e_write(&base[i], l2e_empty()); - } + + /* Clear temporary idle mappings from the dom0 initial l2. */ + for ( i = 0; i < (HYPERVISOR_VIRT_START >> L2_PAGETABLE_SHIFT); i++ ) + if ( l2e_get_intpte(dom0_l2[i]) == + l2e_get_intpte(idle_pg_table_l2[i]) ) + l2e_write(&dom0_l2[i], l2e_empty()); + + /* Now zap mappings in the idle pagetables. */ + destroy_xen_mappings(0, HYPERVISOR_VIRT_START); flush_tlb_all_pge(); + + /* Replace with mapping of the boot trampoline only. */ + map_pages_to_xen(BOOT_TRAMPOLINE, BOOT_TRAMPOLINE >> PAGE_SHIFT, + 0x10, __PAGE_HYPERVISOR); } void __init subarch_init_memory(void) diff -r 759d924af6d8 -r 03a13457d993 xen/arch/x86/x86_64/mm.c --- a/xen/arch/x86/x86_64/mm.c Sat May 12 10:28:53 2007 +0100 +++ b/xen/arch/x86/x86_64/mm.c Sat May 12 12:07:01 2007 +0100 @@ -68,11 +68,6 @@ void *alloc_xen_pagetable(void) mfn = alloc_boot_low_pages(1, 1); /* 0x0 - 0x40000000 */ BUG_ON(mfn == 0); return mfn_to_virt(mfn); -} - -void free_xen_pagetable(void *v) -{ - free_domheap_page(virt_to_page(v)); } l2_pgentry_t *virt_to_xen_l2e(unsigned long v) @@ -209,8 +204,15 @@ void __init setup_idle_pagetable(void) void __init zap_low_mappings(void) { + BUG_ON(num_online_cpus() != 1); + + /* Remove aliased mapping of first 1:1 PML4 entry. */ l4e_write(&idle_pg_table[0], l4e_empty()); - flush_tlb_all_pge(); + local_flush_tlb_pge(); + + /* Replace with mapping of the boot trampoline only. */ + map_pages_to_xen(BOOT_TRAMPOLINE, BOOT_TRAMPOLINE >> PAGE_SHIFT, + 0x10, __PAGE_HYPERVISOR); } void __init subarch_init_memory(void) diff -r 759d924af6d8 -r 03a13457d993 xen/include/asm-x86/page.h --- a/xen/include/asm-x86/page.h Sat May 12 10:28:53 2007 +0100 +++ b/xen/include/asm-x86/page.h Sat May 12 12:07:01 2007 +0100 @@ -1,4 +1,3 @@ - #ifndef __X86_PAGE_H__ #define __X86_PAGE_H__ @@ -369,6 +368,7 @@ map_pages_to_xen( unsigned long mfn, unsigned long nr_mfns, unsigned long flags); +void destroy_xen_mappings(unsigned long v, unsigned long e); #endif /* !__ASSEMBLY__ */ _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |