Commit 893f38d144a4d96d2483cd7c3801d26e1b2c23e9

Authored by Yinghai Lu
Committed by Ingo Molnar
1 parent ebb682f522

x86: Use find_e820() instead of hard coded trampoline address

Jens found the following crash/regression:

[    0.000000] found SMP MP-table at [ffff8800000fdd80] fdd80
[    0.000000] Kernel panic - not syncing: Overlapping early reservations 12-f011 MP-table mpc to 0-fff BIOS data page

and

[    0.000000] Kernel panic - not syncing: Overlapping early reservations 12-f011 MP-table mpc to 6000-7fff TRAMPOLINE

and bisected it to b24c2a9 ("x86: Move find_smp_config()
earlier and avoid bootmem usage").

It turns out the BIOS is using the first 64k for mptable,
without reserving it.

So try to find good range for the real-mode trampoline instead of
hard coding it, in case some bios tries to use that range for sth.

Reported-by: Jens Axboe <jens.axboe@oracle.com>
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Tested-by: Jens Axboe <jens.axboe@oracle.com>
Cc: Randy Dunlap <randy.dunlap@oracle.com>
LKML-Reference: <4B21630A.6000308@kernel.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>

Showing 7 changed files with 27 additions and 25 deletions Side-by-side Diff

arch/x86/include/asm/trampoline.h
... ... @@ -16,7 +16,6 @@
16 16 extern unsigned long initial_gs;
17 17  
18 18 #define TRAMPOLINE_SIZE roundup(trampoline_end - trampoline_data, PAGE_SIZE)
19   -#define TRAMPOLINE_BASE 0x6000
20 19  
21 20 extern unsigned long setup_trampoline(void);
22 21 extern void __init reserve_trampoline_memory(void);
arch/x86/kernel/e820.c
... ... @@ -732,7 +732,16 @@
732 732 char overlap_ok;
733 733 };
734 734 static struct early_res early_res[MAX_EARLY_RES] __initdata = {
735   - { 0, PAGE_SIZE, "BIOS data page" }, /* BIOS data page */
  735 + { 0, PAGE_SIZE, "BIOS data page", 1 }, /* BIOS data page */
  736 +#ifdef CONFIG_X86_32
  737 + /*
  738 + * But first pinch a few for the stack/trampoline stuff
  739 + * FIXME: Don't need the extra page at 4K, but need to fix
  740 + * trampoline before removing it. (see the GDT stuff)
  741 + */
  742 + { PAGE_SIZE, PAGE_SIZE, "EX TRAMPOLINE", 1 },
  743 +#endif
  744 +
736 745 {}
737 746 };
738 747  
arch/x86/kernel/head32.c
... ... @@ -29,8 +29,6 @@
29 29  
30 30 void __init i386_start_kernel(void)
31 31 {
32   - reserve_trampoline_memory();
33   -
34 32 reserve_early(__pa_symbol(&_text), __pa_symbol(&__bss_stop), "TEXT DATA BSS");
35 33  
36 34 #ifdef CONFIG_BLK_DEV_INITRD
arch/x86/kernel/head64.c
... ... @@ -98,8 +98,6 @@
98 98 {
99 99 copy_bootdata(__va(real_mode_data));
100 100  
101   - reserve_trampoline_memory();
102   -
103 101 reserve_early(__pa_symbol(&_text), __pa_symbol(&__bss_stop), "TEXT DATA BSS");
104 102  
105 103 #ifdef CONFIG_BLK_DEV_INITRD
arch/x86/kernel/mpparse.c
... ... @@ -945,9 +945,6 @@
945 945 {
946 946 if (enable_update_mptable && alloc_mptable) {
947 947 u64 startt = 0;
948   -#ifdef CONFIG_X86_TRAMPOLINE
949   - startt = TRAMPOLINE_BASE;
950   -#endif
951 948 mpc_new_phys = early_reserve_e820(startt, mpc_new_length, 4);
952 949 }
953 950 }
arch/x86/kernel/setup.c
... ... @@ -73,6 +73,7 @@
73 73  
74 74 #include <asm/mtrr.h>
75 75 #include <asm/apic.h>
  76 +#include <asm/trampoline.h>
76 77 #include <asm/e820.h>
77 78 #include <asm/mpspec.h>
78 79 #include <asm/setup.h>
... ... @@ -875,6 +876,13 @@
875 876  
876 877 reserve_brk();
877 878  
  879 + /*
  880 + * Find and reserve possible boot-time SMP configuration:
  881 + */
  882 + find_smp_config();
  883 +
  884 + reserve_trampoline_memory();
  885 +
878 886 #ifdef CONFIG_ACPI_SLEEP
879 887 /*
880 888 * Reserve low memory region for sleep support.
... ... @@ -920,11 +928,6 @@
920 928 acpi_boot_table_init();
921 929  
922 930 early_acpi_boot_init();
923   -
924   - /*
925   - * Find and reserve possible boot-time SMP configuration:
926   - */
927   - find_smp_config();
928 931  
929 932 #ifdef CONFIG_ACPI_NUMA
930 933 /*
arch/x86/kernel/trampoline.c
... ... @@ -12,21 +12,19 @@
12 12 #endif
13 13  
14 14 /* ready for x86_64 and x86 */
15   -unsigned char *__trampinitdata trampoline_base = __va(TRAMPOLINE_BASE);
  15 +unsigned char *__trampinitdata trampoline_base;
16 16  
17 17 void __init reserve_trampoline_memory(void)
18 18 {
19   -#ifdef CONFIG_X86_32
20   - /*
21   - * But first pinch a few for the stack/trampoline stuff
22   - * FIXME: Don't need the extra page at 4K, but need to fix
23   - * trampoline before removing it. (see the GDT stuff)
24   - */
25   - reserve_early(PAGE_SIZE, PAGE_SIZE + PAGE_SIZE, "EX TRAMPOLINE");
26   -#endif
  19 + unsigned long mem;
  20 +
27 21 /* Has to be in very low memory so we can execute real-mode AP code. */
28   - reserve_early(TRAMPOLINE_BASE, TRAMPOLINE_BASE + TRAMPOLINE_SIZE,
29   - "TRAMPOLINE");
  22 + mem = find_e820_area(0, 1<<20, TRAMPOLINE_SIZE, PAGE_SIZE);
  23 + if (mem == -1L)
  24 + panic("Cannot allocate trampoline\n");
  25 +
  26 + trampoline_base = __va(mem);
  27 + reserve_early(mem, mem + TRAMPOLINE_SIZE, "TRAMPOLINE");
30 28 }
31 29  
32 30 /*