Commit 893f38d144a4d96d2483cd7c3801d26e1b2c23e9
Committed by
Ingo Molnar
1 parent
ebb682f522
Exists in
master
and in
7 other branches
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
arch/x86/kernel/head64.c
arch/x86/kernel/mpparse.c
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 | /* |