x86: move reserve_setup_data to setup.c
authorYinghai Lu <yhlu.kernel@gmail.com>
Mon, 30 Jun 2008 23:20:54 +0000 (16:20 -0700)
committerIngo Molnar <mingo@elte.hu>
Tue, 8 Jul 2008 11:16:14 +0000 (13:16 +0200)
Ying Huang would like setup_data to be reserved, but not included in the
no save range.

Here we try to modify the e820 table to reserve that range early.
also add that in early_res in case bootloader messes up with the ramdisk.

other solution would be
1. add early_res_to_highmem...
2. early_res_to_e820...
but they could reserve another type memory wrongly, if early_res has some
resource reserved early, and not needed later, but it is not removed from
early_res in time. Like the RAMDISK (already handled).

Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com>
Cc: andi@firstfloor.org
Tested-by: Huang, Ying <ying.huang@intel.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
arch/x86/kernel/e820.c
arch/x86/kernel/head.c
arch/x86/kernel/head64.c
arch/x86/kernel/setup.c
include/asm-x86/bootparam.h
include/asm-x86/e820.h

index ba5ac880ea1ed5605174e0696b3b4a363be5a337..e03b89ac8f2b93d4b9218db5a829a25a7951904c 100644 (file)
@@ -120,6 +120,7 @@ void __init e820_print_map(char *who)
                       (e820.map[i].addr + e820.map[i].size));
                switch (e820.map[i].type) {
                case E820_RAM:
+               case E820_RESERVED_KERN:
                        printk(KERN_CONT "(usable)\n");
                        break;
                case E820_RESERVED:
@@ -611,7 +612,7 @@ void __init e820_mark_nosave_regions(unsigned long limit_pfn)
                        register_nosave_region(pfn, PFN_UP(ei->addr));
 
                pfn = PFN_DOWN(ei->addr + ei->size);
-               if (ei->type != E820_RAM)
+               if (ei->type != E820_RAM && ei->type != E820_RESERVED_KERN)
                        register_nosave_region(PFN_UP(ei->addr), pfn);
 
                if (pfn >= limit_pfn)
@@ -1207,6 +1208,7 @@ void __init e820_reserve_resources(void)
        res = alloc_bootmem_low(sizeof(struct resource) * e820.nr_map);
        for (i = 0; i < e820.nr_map; i++) {
                switch (e820.map[i].type) {
+               case E820_RESERVED_KERN:
                case E820_RAM:  res->name = "System RAM"; break;
                case E820_ACPI: res->name = "ACPI Tables"; break;
                case E820_NVS:  res->name = "ACPI Non-volatile Storage"; break;
index a6816be01cd65fdb8914f0f8fc7a7df89a5f43a5..3e66bd364a9db3cf8f3fb624f96eeb7075364d78 100644 (file)
@@ -53,21 +53,3 @@ void __init reserve_ebda_region(void)
        /* reserve all memory between lowmem and the 1MB mark */
        reserve_early_overlap_ok(lowmem, 0x100000, "BIOS reserved");
 }
-
-void __init reserve_setup_data(void)
-{
-       struct setup_data *data;
-       u64 pa_data;
-       char buf[32];
-
-       if (boot_params.hdr.version < 0x0209)
-               return;
-       pa_data = boot_params.hdr.setup_data;
-       while (pa_data) {
-               data = early_ioremap(pa_data, sizeof(*data));
-               sprintf(buf, "setup data %x", data->type);
-               reserve_early(pa_data, pa_data+sizeof(*data)+data->len, buf);
-               pa_data = data->next;
-               early_iounmap(data, sizeof(*data));
-       }
-}
index f684e3b3de4e6986d156db09dc1134ab619ac594..c9781982914693cbb6ba98bf7cea94b1a291c8a5 100644 (file)
@@ -128,7 +128,6 @@ void __init x86_64_start_reservations(char *real_mode_data)
 #endif
 
        reserve_ebda_region();
-       reserve_setup_data();
 
        /*
         * At this point everything still needed from the boot loader
index caec79fb83a3cceb498191ce926430f2d85d8d14..2ca12d4c88fb462f7f698ac8da94a2db8a2a493b 100644 (file)
@@ -389,14 +389,34 @@ static void __init parse_setup_data(void)
                default:
                        break;
                }
-#ifndef CONFIG_DEBUG_BOOT_PARAMS
-               free_early(pa_data, pa_data+sizeof(*data)+data->len);
-#endif
                pa_data = data->next;
                early_iounmap(data, PAGE_SIZE);
        }
 }
 
+static void __init reserve_setup_data(void)
+{
+       struct setup_data *data;
+       u64 pa_data;
+       char buf[32];
+
+       if (boot_params.hdr.version < 0x0209)
+               return;
+       pa_data = boot_params.hdr.setup_data;
+       while (pa_data) {
+               data = early_ioremap(pa_data, sizeof(*data));
+               sprintf(buf, "setup data %x", data->type);
+               reserve_early(pa_data, pa_data+sizeof(*data)+data->len, buf);
+               e820_update_range(pa_data, sizeof(*data)+data->len,
+                        E820_RAM, E820_RESERVED_KERN);
+               pa_data = data->next;
+               early_iounmap(data, sizeof(*data));
+       }
+       sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &e820.nr_map);
+       printk(KERN_INFO "extended physical RAM map:\n");
+       e820_print_map("reserve setup_data");
+}
+
 /*
  * --------- Crashkernel reservation ------------------------------
  */
@@ -523,7 +543,6 @@ void __init setup_arch(char **cmdline_p)
        memcpy(&boot_cpu_data, &new_cpu_data, sizeof(new_cpu_data));
        pre_setup_arch_hook();
        early_cpu_init();
-       reserve_setup_data();
 #else
        printk(KERN_INFO "Command line: %s\n", boot_command_line);
 #endif
@@ -567,6 +586,8 @@ void __init setup_arch(char **cmdline_p)
        ARCH_SETUP
 
        setup_memory_map();
+       parse_setup_data();
+
        copy_edd();
 
        if (!boot_params.hdr.root_flags)
@@ -593,10 +614,11 @@ void __init setup_arch(char **cmdline_p)
        strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE);
        *cmdline_p = command_line;
 
-       parse_setup_data();
-
        parse_early_param();
 
+       /* after early param, so could get panic from serial */
+       reserve_setup_data();
+
        if (acpi_mps_check()) {
 #ifdef CONFIG_X86_LOCAL_APIC
                disable_apic = 1;
index 6eeba3b2812b8b1b3196590f836da0c94f4ff7a7..ae22bdf0ab14a74c4b9d01f91fb07230047e1cee 100644 (file)
@@ -108,6 +108,4 @@ struct boot_params {
        __u8  _pad9[276];                               /* 0xeec */
 } __attribute__((packed));
 
-void reserve_setup_data(void);
-
 #endif /* _ASM_BOOTPARAM_H */
index f622685c9af8ddba31398b83364569762578ec3d..45e904fe407686862888f8742189cd7c951805b7 100644 (file)
@@ -44,6 +44,9 @@
 #define E820_ACPI      3
 #define E820_NVS       4
 
+/* reserved RAM used by kernel itself */
+#define E820_RESERVED_KERN        128
+
 #ifndef __ASSEMBLY__
 struct e820entry {
        __u64 addr;     /* start of memory segment */