diff --git a/xen/arch/x86/boot/head.S b/xen/arch/x86/boot/head.S index 250587fdf0..d152af4542 100644 --- a/xen/arch/x86/boot/head.S +++ b/xen/arch/x86/boot/head.S @@ -661,15 +661,9 @@ trampoline_setup: mov %eax,sym_fs(boot_tsc_stamp) mov %edx,sym_fs(boot_tsc_stamp)+4 - /* - * Update frame addresses in page tables excluding l2_identmap - * without its first entry which points to l1_identmap. - */ + /* Relocate pagetables to point at Xen's current location in memory. */ mov $((__page_tables_end-__page_tables_start)/8),%ecx - mov $(((l2_identmap-__page_tables_start)/8)+1),%edx -1: cmp $((l2_identmap+l2_identmap_sizeof-__page_tables_start)/8),%ecx - cmove %edx,%ecx - testl $_PAGE_PRESENT,sym_fs(__page_tables_start)-8(,%ecx,8) +1: testl $_PAGE_PRESENT,sym_fs(__page_tables_start)-8(,%ecx,8) jz 2f add %esi,sym_fs(__page_tables_start)-8(,%ecx,8) 2: loop 1b diff --git a/xen/arch/x86/boot/x86_64.S b/xen/arch/x86/boot/x86_64.S index 0acf5e860c..de555f87f4 100644 --- a/xen/arch/x86/boot/x86_64.S +++ b/xen/arch/x86/boot/x86_64.S @@ -65,24 +65,19 @@ l1_identmap: .size l1_identmap, . - l1_identmap /* - * __page_tables_start does not cover l1_identmap because it (l1_identmap) - * contains 1-1 mappings. This means that frame addresses of these mappings - * are static and should not be updated at runtime. + * __page_tables_{start,end} cover the range of pagetables which need + * relocating as Xen moves around physical memory. i.e. each sym_offs() + * reference to a different pagetable in the Xen image. */ GLOBAL(__page_tables_start) /* - * Space for mapping the first 4GB of memory, with the first 16 megabytes - * actualy mapped (mostly using superpages). Uses 4x 4k pages. + * Space for 4G worth of 2M mappings, first 2M actually mapped via + * l1_identmap[]. Uses 4x 4k pages. */ GLOBAL(l2_identmap) .quad sym_offs(l1_identmap) + __PAGE_HYPERVISOR - idx = 1 - .rept 7 - .quad (idx << L2_PAGETABLE_SHIFT) | PAGE_HYPERVISOR | _PAGE_PSE - idx = idx + 1 - .endr - .fill 4 * L2_PAGETABLE_ENTRIES - 8, 8, 0 + .fill 4 * L2_PAGETABLE_ENTRIES - 1, 8, 0 .size l2_identmap, . - l2_identmap /* diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c index ed54f79fea..62adc9e2a8 100644 --- a/xen/arch/x86/setup.c +++ b/xen/arch/x86/setup.c @@ -678,6 +678,9 @@ static unsigned int __init copy_bios_e820(struct e820entry *map, unsigned int li return n; } +/* How much of the directmap is prebuilt at compile time. */ +#define PREBUILT_MAP_LIMIT (1 << L2_PAGETABLE_SHIFT) + void __init noreturn __start_xen(unsigned long mbi_p) { char *memmap_type = NULL; @@ -1020,7 +1023,7 @@ void __init noreturn __start_xen(unsigned long mbi_p) * * We require superpage alignment because the boot allocator is * not yet initialised. Hence we can only map superpages in the - * address range BOOTSTRAP_MAP_BASE to 4GB, as this is guaranteed + * address range PREBUILT_MAP_LIMIT to 4GB, as this is guaranteed * not to require dynamic allocation of pagetables. * * As well as mapping superpages in that range, in preparation for @@ -1036,10 +1039,10 @@ void __init noreturn __start_xen(unsigned long mbi_p) if ( boot_e820.map[i].type != E820_RAM ) continue; - /* Superpage-aligned chunks from BOOTSTRAP_MAP_BASE. */ + /* Superpage-aligned chunks from PREBUILT_MAP_LIMIT. */ s = (boot_e820.map[i].addr + mask) & ~mask; e = (boot_e820.map[i].addr + boot_e820.map[i].size) & ~mask; - s = max_t(uint64_t, s, BOOTSTRAP_MAP_BASE); + s = max_t(uint64_t, s, PREBUILT_MAP_LIMIT); if ( s >= e ) continue; @@ -1346,8 +1349,8 @@ void __init noreturn __start_xen(unsigned long mbi_p) set_pdx_range(s >> PAGE_SHIFT, e >> PAGE_SHIFT); - /* Need to create mappings above BOOTSTRAP_MAP_BASE. */ - map_s = max_t(uint64_t, s, BOOTSTRAP_MAP_BASE); + /* Need to create mappings above PREBUILT_MAP_LIMIT. */ + map_s = max_t(uint64_t, s, PREBUILT_MAP_LIMIT); map_e = min_t(uint64_t, e, ARRAY_SIZE(l2_identmap) << L2_PAGETABLE_SHIFT); diff --git a/xen/arch/x86/x86_64/asm-offsets.c b/xen/arch/x86/x86_64/asm-offsets.c index f9cb78cfdb..07d2155bf5 100644 --- a/xen/arch/x86/x86_64/asm-offsets.c +++ b/xen/arch/x86/x86_64/asm-offsets.c @@ -165,8 +165,5 @@ void __dummy__(void) OFFSET(MB2_efi64_ih, multiboot2_tag_efi64_ih_t, pointer); BLANK(); - DEFINE(l2_identmap_sizeof, sizeof(l2_identmap)); - BLANK(); - OFFSET(DOMAIN_vm_assist, struct domain, vm_assist); }