]> xenbits.xensource.com Git - xen.git/commitdiff
x86/boot: Create the l2_xenmap[] mappings dynamically
authorAndrew Cooper <andrew.cooper3@citrix.com>
Fri, 10 Jan 2020 16:35:14 +0000 (16:35 +0000)
committerAndrew Cooper <andrew.cooper3@citrix.com>
Wed, 22 Jan 2020 19:03:18 +0000 (19:03 +0000)
The build-time construction of l2_xenmap[] imposes an arbitrary limit of 16M
total, which is a limit looking to be lifted.

Adjust both the BIOS and EFI paths to fill it in dynamically, based on the
final linked size of Xen.  l2_xenmap[] stays between __page_tables_{start,end}
(rather than move into .bss.page_aligned) as it is expected to gain a
different pagetable reference shortly.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
xen/arch/x86/boot/head.S
xen/arch/x86/boot/x86_64.S
xen/arch/x86/efi/efi-boot.h
xen/arch/x86/xen.lds.S

index c5acbf56aea526241e14c3f03ecd07a5dc0983c7..ef9f56250504c22326a51d80fe6b2e9fb019824f 100644 (file)
@@ -668,6 +668,20 @@ trampoline_setup:
         add     %esi,sym_fs(__page_tables_start)-8(,%ecx,8)
 2:      loop    1b
 
+        /* Map Xen into the higher mappings using 2M superpages. */
+        lea     _PAGE_PSE + PAGE_HYPERVISOR_RWX + sym_esi(_start), %eax
+        mov     $sym_offs(_start),   %ecx   /* %eax = PTE to write ^      */
+        mov     $sym_offs(_end - 1), %edx
+        shr     $L2_PAGETABLE_SHIFT, %ecx   /* %ecx = First slot to write */
+        shr     $L2_PAGETABLE_SHIFT, %edx   /* %edx = Final slot to write */
+
+1:      mov     %eax, sym_offs(l2_xenmap)(%esi, %ecx, 8)
+        add     $1, %ecx
+        add     $1 << L2_PAGETABLE_SHIFT, %eax
+
+        cmp     %edx, %ecx
+        jbe     1b
+
         /*
          * Map Xen into the directmap (needed for early-boot pagetable
          * handling/walking), and identity map Xen into bootmap (needed for
index aabf561b2303fb98fcea1927531de050b504388f..1cbf5acdfb6da30e89abe3c59fdc5783e6ae5b06 100644 (file)
@@ -81,18 +81,11 @@ GLOBAL(l2_directmap)
         .size l2_directmap, . - l2_directmap
 
 /*
- * L2 mapping the 1GB Xen text/data/bss region.  At boot it maps 16MB from
- * __image_base__, and is modified when Xen relocates itself.  Uses 1x 4k
- * page.
+ * L2 mapping the Xen text/data/bss region, constructed dynamically.  Uses 1x
+ * 4k page.
  */
 GLOBAL(l2_xenmap)
-        .quad 0
-        idx = 1
-        .rept 7
-        .quad sym_offs(__image_base__) + (idx << L2_PAGETABLE_SHIFT) + (PAGE_HYPERVISOR_RWX | _PAGE_PSE)
-        idx = idx + 1
-        .endr
-        .fill L2_PAGETABLE_ENTRIES - 8, 8, 0
+        .fill L2_PAGETABLE_ENTRIES, 8, 0
         .size l2_xenmap, . - l2_xenmap
 
 /* L2 mapping the fixmap.  Uses 1x 4k page. */
index 50d149986716d8fdf420df05eecbfabb5980ff3a..ce07aedf45f573528b839aa31c322e93b21e611e 100644 (file)
@@ -585,6 +585,20 @@ static void __init efi_arch_memory_setup(void)
     if ( !efi_enabled(EFI_LOADER) )
         return;
 
+    /*
+     * Map Xen into the higher mappings, using 2M superpages.
+     *
+     * NB: We are currently in physical mode, so a RIP-relative relocation
+     * against _start/_end result in our arbitrary placement by the bootloader
+     * in memory, rather than the intended high mappings position.  Subtract
+     * xen_phys_start to get the appropriate slots in l2_xenmap[].
+     */
+    for ( i =  l2_table_offset((UINTN)_start   - xen_phys_start);
+          i <= l2_table_offset((UINTN)_end - 1 - xen_phys_start); ++i )
+        l2_xenmap[i] =
+            l2e_from_paddr(xen_phys_start + (i << L2_PAGETABLE_SHIFT),
+                           PAGE_HYPERVISOR_RWX | _PAGE_PSE);
+
     /* Check that there is at least 4G of mapping space in l2_*map[] */
     BUILD_BUG_ON((sizeof(l2_bootmap)   / L2_PAGETABLE_ENTRIES) < 4);
     BUILD_BUG_ON((sizeof(l2_directmap) / L2_PAGETABLE_ENTRIES) < 4);
index 29ef50743244aa981cc6a45495cd7d35a5fe18b2..07c6448dbb9fb1d2d6e4396f454790a1cd1b6750 100644 (file)
@@ -360,6 +360,9 @@ ASSERT(__2M_rwdata_end <= XEN_VIRT_END - XEN_VIRT_START + __XEN_VIRT_START -
 ASSERT(kexec_reloc_size - kexec_reloc <= PAGE_SIZE, "kexec_reloc is too large")
 #endif
 
+/* The Multiboot setup paths relies on this to simplify superpage PTE creation. */
+ASSERT(IS_ALIGNED(_start,            MB(2)), "_start misaligned")
+
 ASSERT(IS_ALIGNED(__2M_text_end,     SECTION_ALIGN), "__2M_text_end misaligned")
 ASSERT(IS_ALIGNED(__2M_rodata_start, SECTION_ALIGN), "__2M_rodata_start misaligned")
 ASSERT(IS_ALIGNED(__2M_rodata_end,   SECTION_ALIGN), "__2M_rodata_end misaligned")