]> xenbits.xensource.com Git - people/royger/xen.git/commitdiff
x86: use trampoline e820 buffer for BIOS interface only
authorJuergen Gross <jgross@suse.com>
Fri, 24 Mar 2017 13:19:24 +0000 (14:19 +0100)
committerJan Beulich <jbeulich@suse.com>
Fri, 24 Mar 2017 13:19:24 +0000 (14:19 +0100)
Instead of using the E820 raw buffer for BIOS, EFI and multiboot based
memory map information use it for the BIOS interface only. This will
enable us to support more E820 entries than the limited trampoline
located buffer can.

Add a new raw e820 table for common purpose and copy the BIOS buffer
to it. Doing the copying in assembly avoids the need to export the
symbols for the BIOS E820 buffer and number of entries.

Signed-off-by: Juergen Gross <jgross@suse.com>
[jb: eliminate an unneeded local variable]
Reviewed-by: Jan Beulich <jbeulich@suse.com>
xen/arch/x86/boot/mem.S
xen/arch/x86/e820.c
xen/arch/x86/efi/efi-boot.h
xen/arch/x86/setup.c
xen/include/asm-x86/e820.h

index 602ab2cd6711df22a881df9e51f1b7c6e8475286..14dff959994ef7eea649144b63a769fb60054561 100644 (file)
@@ -67,10 +67,27 @@ get_memory_map:
 
         ret
 
+/*
+ * Copy E820 map obtained from BIOS to a buffer allocated by Xen.
+ * Input: %rdi: target address of e820 entry array
+ *        %esi: maximum number of entries to copy
+ * Output: %eax: number of entries copied
+ */
+        .code64
+ENTRY(e820map_copy)
+        mov     %esi, %eax
+        lea     e820map(%rip), %rsi
+        mov     e820nr(%rip), %ecx
+        cmp     %ecx, %eax
+        cmova   %ecx, %eax                      # number of entries to move
+        imul    $5, %eax, %ecx
+        rep movsl                               # do the move
+        ret
+
         .align  4
-GLOBAL(e820map)
+e820map:
         .fill   E820MAX*20,1,0
-GLOBAL(e820nr)
+e820nr:
         .long   0
 GLOBAL(lowmem_kb)
         .long   0
index 76537eae894a81fd96c16ead0e2b6cd7e1ad1df2..bc1544a5141e5bdbda8443aff27bcbcd40f74053 100644 (file)
@@ -33,6 +33,7 @@ static bool_t __initdata e820_verbose;
 boolean_param("e820-verbose", e820_verbose);
 
 struct e820map e820;
+struct e820map __initdata e820_raw;
 
 /*
  * This function checks if the entire range <start,end> is mapped with type.
@@ -75,7 +76,7 @@ static void __init add_memory_region(unsigned long long start,
 
     x = e820.nr_map;
 
-    if (x == E820MAX) {
+    if (x == ARRAY_SIZE(e820.map)) {
         printk(KERN_ERR "Ooops! Too many entries in the memory map!\n");
         return;
     }
@@ -133,7 +134,8 @@ static struct change_member *change_point[2*E820MAX] __initdata;
 static struct e820entry *overlap_list[E820MAX] __initdata;
 static struct e820entry new_bios[E820MAX] __initdata;
 
-static int __init sanitize_e820_map(struct e820entry * biosmap, char * pnr_map)
+static int __init sanitize_e820_map(struct e820entry *biosmap,
+                                    unsigned int *pnr_map)
 {
     struct change_member *change_tmp;
     unsigned long current_type, last_type;
@@ -266,7 +268,7 @@ static int __init sanitize_e820_map(struct e820entry * biosmap, char * pnr_map)
                     change_point[chgidx]->addr - last_addr;
                                /* move forward only if the new size was non-zero */
                 if (new_bios[new_bios_entry].size != 0)
-                    if (++new_bios_entry >= E820MAX)
+                    if (++new_bios_entry >= ARRAY_SIZE(new_bios))
                         break;         /* no more space left for new bios entries */
             }
             if (current_type != 0)     {
@@ -508,17 +510,14 @@ static void __init reserve_dmi_region(void)
     }
 }
 
-static void __init machine_specific_memory_setup(
-    struct e820entry *raw, unsigned int *raw_nr)
+static void __init machine_specific_memory_setup(struct e820map *raw)
 {
     unsigned long mpt_limit, ro_mpt_limit;
     uint64_t top_of_ram, size;
     int i;
 
-    char nr = (char)*raw_nr;
-    sanitize_e820_map(raw, &nr);
-    *raw_nr = nr;
-    (void)copy_e820_map(raw, nr);
+    sanitize_e820_map(raw->map, &raw->nr_map);
+    copy_e820_map(raw->map, raw->nr_map);
 
     if ( opt_mem )
         clip_to_limit(opt_mem, NULL);
@@ -691,16 +690,15 @@ int __init reserve_e820_ram(struct e820map *e820, uint64_t s, uint64_t e)
     return e820_change_range_type(e820, s, e, E820_RAM, E820_RESERVED);
 }
 
-unsigned long __init init_e820(
-    const char *str, struct e820entry *raw, unsigned int *raw_nr)
+unsigned long __init init_e820(const char *str, struct e820map *raw)
 {
     if ( e820_verbose )
     {
         printk("Initial %s RAM map:\n", str);
-        print_e820_memory_map(raw, *raw_nr);
+        print_e820_memory_map(raw->map, raw->nr_map);
     }
 
-    machine_specific_memory_setup(raw, raw_nr);
+    machine_specific_memory_setup(raw);
 
     printk("%s RAM map:\n", str);
     print_e820_memory_map(e820.map, e820.nr_map);
index 0e1c190539ec49104b426610d741204bd44b12b9..34537d4893ae0f3a55da5ff0a314393e10d0a729 100644 (file)
@@ -156,8 +156,8 @@ static void __init efi_arch_process_memory_map(EFI_SYSTEM_TABLE *SystemTable,
     unsigned int i;
 
     /* Populate E820 table and check trampoline area availability. */
-    e = e820map - 1;
-    for ( e820nr = i = 0; i < map_size; i += desc_size )
+    e = e820_raw.map - 1;
+    for ( e820_raw.nr_map = i = 0; i < map_size; i += desc_size )
     {
         EFI_MEMORY_DESCRIPTOR *desc = map + i;
         u64 len = desc->NumberOfPages << EFI_PAGE_SHIFT;
@@ -194,10 +194,10 @@ static void __init efi_arch_process_memory_map(EFI_SYSTEM_TABLE *SystemTable,
             type = E820_NVS;
             break;
         }
-        if ( e820nr && type == e->type &&
+        if ( e820_raw.nr_map && type == e->type &&
              desc->PhysicalStart == e->addr + e->size )
             e->size += len;
-        else if ( !len || e820nr >= E820MAX )
+        else if ( !len || e820_raw.nr_map >= ARRAY_SIZE(e820_raw.map) )
             continue;
         else
         {
@@ -205,7 +205,7 @@ static void __init efi_arch_process_memory_map(EFI_SYSTEM_TABLE *SystemTable,
             e->addr = desc->PhysicalStart;
             e->size = len;
             e->type = type;
-            ++e820nr;
+            ++e820_raw.nr_map;
         }
     }
 
index 1cd290e4657ac80fdc7837ef093bbf7f7b831580..be10a4f32e065f47bd578a2aa8abd94965b51788 100644 (file)
@@ -782,14 +782,17 @@ void __init noreturn __start_xen(unsigned long mbi_p)
     }
     else if ( efi_enabled(EFI_BOOT) )
         memmap_type = "EFI";
-    else if ( e820_raw_nr != 0 )
+    else if ( (e820_raw.nr_map = 
+                   copy_bios_e820(e820_raw.map,
+                                  ARRAY_SIZE(e820_raw.map))) != 0 )
     {
         memmap_type = "Xen-e820";
     }
     else if ( mbi->flags & MBI_MEMMAP )
     {
         memmap_type = "Multiboot-e820";
-        while ( (bytes < mbi->mmap_length) && (e820_raw_nr < E820MAX) )
+        while ( bytes < mbi->mmap_length &&
+                e820_raw.nr_map < ARRAY_SIZE(e820_raw.map) )
         {
             memory_map_t *map = __va(mbi->mmap_addr + bytes);
 
@@ -813,12 +816,12 @@ void __init noreturn __start_xen(unsigned long mbi_p)
                 map->length_high = 0;
             }
 
-            e820_raw[e820_raw_nr].addr = 
+            e820_raw.map[e820_raw.nr_map].addr =
                 ((u64)map->base_addr_high << 32) | (u64)map->base_addr_low;
-            e820_raw[e820_raw_nr].size = 
+            e820_raw.map[e820_raw.nr_map].size =
                 ((u64)map->length_high << 32) | (u64)map->length_low;
-            e820_raw[e820_raw_nr].type = map->type;
-            e820_raw_nr++;
+            e820_raw.map[e820_raw.nr_map].type = map->type;
+            e820_raw.nr_map++;
 
             bytes += map->size + 4;
         }
@@ -826,30 +829,30 @@ void __init noreturn __start_xen(unsigned long mbi_p)
     else if ( bootsym(lowmem_kb) )
     {
         memmap_type = "Xen-e801";
-        e820_raw[0].addr = 0;
-        e820_raw[0].size = bootsym(lowmem_kb) << 10;
-        e820_raw[0].type = E820_RAM;
-        e820_raw[1].addr = 0x100000;
-        e820_raw[1].size = bootsym(highmem_kb) << 10;
-        e820_raw[1].type = E820_RAM;
-        e820_raw_nr = 2;
+        e820_raw.map[0].addr = 0;
+        e820_raw.map[0].size = bootsym(lowmem_kb) << 10;
+        e820_raw.map[0].type = E820_RAM;
+        e820_raw.map[1].addr = 0x100000;
+        e820_raw.map[1].size = bootsym(highmem_kb) << 10;
+        e820_raw.map[1].type = E820_RAM;
+        e820_raw.nr_map = 2;
     }
     else if ( mbi->flags & MBI_MEMLIMITS )
     {
         memmap_type = "Multiboot-e801";
-        e820_raw[0].addr = 0;
-        e820_raw[0].size = mbi->mem_lower << 10;
-        e820_raw[0].type = E820_RAM;
-        e820_raw[1].addr = 0x100000;
-        e820_raw[1].size = mbi->mem_upper << 10;
-        e820_raw[1].type = E820_RAM;
-        e820_raw_nr = 2;
+        e820_raw.map[0].addr = 0;
+        e820_raw.map[0].size = mbi->mem_lower << 10;
+        e820_raw.map[0].type = E820_RAM;
+        e820_raw.map[1].addr = 0x100000;
+        e820_raw.map[1].size = mbi->mem_upper << 10;
+        e820_raw.map[1].type = E820_RAM;
+        e820_raw.nr_map = 2;
     }
     else
         panic("Bootloader provided no memory information.");
 
     /* Sanitise the raw E820 map to produce a final clean version. */
-    max_page = raw_max_page = init_e820(memmap_type, e820_raw, &e820_raw_nr);
+    max_page = raw_max_page = init_e820(memmap_type, &e820_raw);
 
     /* Create a temporary copy of the E820 map. */
     memcpy(&boot_e820, &e820, sizeof(e820));
index d9ff4eb55b7e8ae14b7e99db4d1107989b75d649..a2d468ff73b31d194d0088806da13e5cc487efc3 100644 (file)
@@ -30,15 +30,14 @@ extern int e820_change_range_type(
     uint32_t orig_type, uint32_t new_type);
 extern int e820_add_range(
     struct e820map *, uint64_t s, uint64_t e, uint32_t type);
-extern unsigned long init_e820(const char *, struct e820entry *, unsigned int *);
+extern unsigned long init_e820(const char *, struct e820map *);
 extern struct e820map e820;
+extern struct e820map e820_raw;
 
 /* These symbols live in the boot trampoline. */
-extern struct e820entry e820map[];
-extern unsigned int e820nr;
 extern unsigned int lowmem_kb, highmem_kb;
+unsigned int e820map_copy(struct e820entry *map, unsigned int limit);
 
-#define e820_raw bootsym(e820map)
-#define e820_raw_nr bootsym(e820nr)
+#define copy_bios_e820 bootsym(e820map_copy)
 
 #endif /*__E820_HEADER*/