diff options
| author | Yinghai Lu <yinghai@kernel.org> | 2009-12-10 16:07:22 -0500 |
|---|---|---|
| committer | Ingo Molnar <mingo@elte.hu> | 2009-12-11 03:28:22 -0500 |
| commit | 893f38d144a4d96d2483cd7c3801d26e1b2c23e9 (patch) | |
| tree | a21107699f5b9938db07697ed2b0ff3c725bf266 /arch | |
| parent | ebb682f522411abbe358059a256a8672ec0bd55b (diff) | |
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>
Diffstat (limited to 'arch')
| -rw-r--r-- | arch/x86/include/asm/trampoline.h | 1 | ||||
| -rw-r--r-- | arch/x86/kernel/e820.c | 11 | ||||
| -rw-r--r-- | arch/x86/kernel/head32.c | 2 | ||||
| -rw-r--r-- | arch/x86/kernel/head64.c | 2 | ||||
| -rw-r--r-- | arch/x86/kernel/mpparse.c | 3 | ||||
| -rw-r--r-- | arch/x86/kernel/setup.c | 13 | ||||
| -rw-r--r-- | arch/x86/kernel/trampoline.c | 20 |
7 files changed, 27 insertions, 25 deletions
diff --git a/arch/x86/include/asm/trampoline.h b/arch/x86/include/asm/trampoline.h index 90f06c25221d..cb507bb05d79 100644 --- a/arch/x86/include/asm/trampoline.h +++ b/arch/x86/include/asm/trampoline.h | |||
| @@ -16,7 +16,6 @@ extern unsigned long initial_code; | |||
| 16 | extern unsigned long initial_gs; | 16 | extern unsigned long initial_gs; |
| 17 | 17 | ||
| 18 | #define TRAMPOLINE_SIZE roundup(trampoline_end - trampoline_data, PAGE_SIZE) | 18 | #define TRAMPOLINE_SIZE roundup(trampoline_end - trampoline_data, PAGE_SIZE) |
| 19 | #define TRAMPOLINE_BASE 0x6000 | ||
| 20 | 19 | ||
| 21 | extern unsigned long setup_trampoline(void); | 20 | extern unsigned long setup_trampoline(void); |
| 22 | extern void __init reserve_trampoline_memory(void); | 21 | extern void __init reserve_trampoline_memory(void); |
diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c index d17d482a04f4..f50447d961c0 100644 --- a/arch/x86/kernel/e820.c +++ b/arch/x86/kernel/e820.c | |||
| @@ -732,7 +732,16 @@ struct early_res { | |||
| 732 | char overlap_ok; | 732 | char overlap_ok; |
| 733 | }; | 733 | }; |
| 734 | static struct early_res early_res[MAX_EARLY_RES] __initdata = { | 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 | ||
diff --git a/arch/x86/kernel/head32.c b/arch/x86/kernel/head32.c index 4f8e2507e8f3..5051b94c9069 100644 --- a/arch/x86/kernel/head32.c +++ b/arch/x86/kernel/head32.c | |||
| @@ -29,8 +29,6 @@ static void __init i386_default_early_setup(void) | |||
| 29 | 29 | ||
| 30 | void __init i386_start_kernel(void) | 30 | void __init i386_start_kernel(void) |
| 31 | { | 31 | { |
| 32 | reserve_trampoline_memory(); | ||
| 33 | |||
| 34 | reserve_early(__pa_symbol(&_text), __pa_symbol(&__bss_stop), "TEXT DATA BSS"); | 32 | reserve_early(__pa_symbol(&_text), __pa_symbol(&__bss_stop), "TEXT DATA BSS"); |
| 35 | 33 | ||
| 36 | #ifdef CONFIG_BLK_DEV_INITRD | 34 | #ifdef CONFIG_BLK_DEV_INITRD |
diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c index 0b06cd778fd9..b5a9896ca1e7 100644 --- a/arch/x86/kernel/head64.c +++ b/arch/x86/kernel/head64.c | |||
| @@ -98,8 +98,6 @@ void __init x86_64_start_reservations(char *real_mode_data) | |||
| 98 | { | 98 | { |
| 99 | copy_bootdata(__va(real_mode_data)); | 99 | copy_bootdata(__va(real_mode_data)); |
| 100 | 100 | ||
| 101 | reserve_trampoline_memory(); | ||
| 102 | |||
| 103 | reserve_early(__pa_symbol(&_text), __pa_symbol(&__bss_stop), "TEXT DATA BSS"); | 101 | reserve_early(__pa_symbol(&_text), __pa_symbol(&__bss_stop), "TEXT DATA BSS"); |
| 104 | 102 | ||
| 105 | #ifdef CONFIG_BLK_DEV_INITRD | 103 | #ifdef CONFIG_BLK_DEV_INITRD |
diff --git a/arch/x86/kernel/mpparse.c b/arch/x86/kernel/mpparse.c index 35a57c963df9..40b54ceb68b5 100644 --- a/arch/x86/kernel/mpparse.c +++ b/arch/x86/kernel/mpparse.c | |||
| @@ -945,9 +945,6 @@ void __init early_reserve_e820_mpc_new(void) | |||
| 945 | { | 945 | { |
| 946 | if (enable_update_mptable && alloc_mptable) { | 946 | if (enable_update_mptable && alloc_mptable) { |
| 947 | u64 startt = 0; | 947 | u64 startt = 0; |
| 948 | #ifdef CONFIG_X86_TRAMPOLINE | ||
| 949 | startt = TRAMPOLINE_BASE; | ||
| 950 | #endif | ||
| 951 | mpc_new_phys = early_reserve_e820(startt, mpc_new_length, 4); | 948 | mpc_new_phys = early_reserve_e820(startt, mpc_new_length, 4); |
| 952 | } | 949 | } |
| 953 | } | 950 | } |
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index 946a311a25c9..f7b8b9894b22 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c | |||
| @@ -73,6 +73,7 @@ | |||
| 73 | 73 | ||
| 74 | #include <asm/mtrr.h> | 74 | #include <asm/mtrr.h> |
| 75 | #include <asm/apic.h> | 75 | #include <asm/apic.h> |
| 76 | #include <asm/trampoline.h> | ||
| 76 | #include <asm/e820.h> | 77 | #include <asm/e820.h> |
| 77 | #include <asm/mpspec.h> | 78 | #include <asm/mpspec.h> |
| 78 | #include <asm/setup.h> | 79 | #include <asm/setup.h> |
| @@ -875,6 +876,13 @@ void __init setup_arch(char **cmdline_p) | |||
| 875 | 876 | ||
| 876 | reserve_brk(); | 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 | #ifdef CONFIG_ACPI_SLEEP | 886 | #ifdef CONFIG_ACPI_SLEEP |
| 879 | /* | 887 | /* |
| 880 | * Reserve low memory region for sleep support. | 888 | * Reserve low memory region for sleep support. |
| @@ -921,11 +929,6 @@ void __init setup_arch(char **cmdline_p) | |||
| 921 | 929 | ||
| 922 | early_acpi_boot_init(); | 930 | early_acpi_boot_init(); |
| 923 | 931 | ||
| 924 | /* | ||
| 925 | * Find and reserve possible boot-time SMP configuration: | ||
| 926 | */ | ||
| 927 | find_smp_config(); | ||
| 928 | |||
| 929 | #ifdef CONFIG_ACPI_NUMA | 932 | #ifdef CONFIG_ACPI_NUMA |
| 930 | /* | 933 | /* |
| 931 | * Parse SRAT to discover nodes. | 934 | * Parse SRAT to discover nodes. |
diff --git a/arch/x86/kernel/trampoline.c b/arch/x86/kernel/trampoline.c index cd022121cab6..c652ef62742d 100644 --- a/arch/x86/kernel/trampoline.c +++ b/arch/x86/kernel/trampoline.c | |||
| @@ -12,21 +12,19 @@ | |||
| 12 | #endif | 12 | #endif |
| 13 | 13 | ||
| 14 | /* ready for x86_64 and x86 */ | 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 | void __init reserve_trampoline_memory(void) | 17 | void __init reserve_trampoline_memory(void) |
| 18 | { | 18 | { |
| 19 | #ifdef CONFIG_X86_32 | 19 | unsigned long mem; |
| 20 | /* | 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 | ||
| 27 | /* Has to be in very low memory so we can execute real-mode AP code. */ | 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, | 22 | mem = find_e820_area(0, 1<<20, TRAMPOLINE_SIZE, PAGE_SIZE); |
| 29 | "TRAMPOLINE"); | 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 | /* |
