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>
This commit is contained in:
parent
ebb682f522
commit
893f38d144
|
@ -16,7 +16,6 @@ extern unsigned long initial_code;
|
||||||
extern unsigned long initial_gs;
|
extern unsigned long initial_gs;
|
||||||
|
|
||||||
#define TRAMPOLINE_SIZE roundup(trampoline_end - trampoline_data, PAGE_SIZE)
|
#define TRAMPOLINE_SIZE roundup(trampoline_end - trampoline_data, PAGE_SIZE)
|
||||||
#define TRAMPOLINE_BASE 0x6000
|
|
||||||
|
|
||||||
extern unsigned long setup_trampoline(void);
|
extern unsigned long setup_trampoline(void);
|
||||||
extern void __init reserve_trampoline_memory(void);
|
extern void __init reserve_trampoline_memory(void);
|
||||||
|
|
|
@ -732,7 +732,16 @@ struct early_res {
|
||||||
char overlap_ok;
|
char overlap_ok;
|
||||||
};
|
};
|
||||||
static struct early_res early_res[MAX_EARLY_RES] __initdata = {
|
static struct early_res early_res[MAX_EARLY_RES] __initdata = {
|
||||||
{ 0, PAGE_SIZE, "BIOS data page" }, /* BIOS data page */
|
{ 0, PAGE_SIZE, "BIOS data page", 1 }, /* BIOS data page */
|
||||||
|
#ifdef CONFIG_X86_32
|
||||||
|
/*
|
||||||
|
* But first pinch a few for the stack/trampoline stuff
|
||||||
|
* FIXME: Don't need the extra page at 4K, but need to fix
|
||||||
|
* trampoline before removing it. (see the GDT stuff)
|
||||||
|
*/
|
||||||
|
{ PAGE_SIZE, PAGE_SIZE, "EX TRAMPOLINE", 1 },
|
||||||
|
#endif
|
||||||
|
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -29,8 +29,6 @@ static void __init i386_default_early_setup(void)
|
||||||
|
|
||||||
void __init i386_start_kernel(void)
|
void __init i386_start_kernel(void)
|
||||||
{
|
{
|
||||||
reserve_trampoline_memory();
|
|
||||||
|
|
||||||
reserve_early(__pa_symbol(&_text), __pa_symbol(&__bss_stop), "TEXT DATA BSS");
|
reserve_early(__pa_symbol(&_text), __pa_symbol(&__bss_stop), "TEXT DATA BSS");
|
||||||
|
|
||||||
#ifdef CONFIG_BLK_DEV_INITRD
|
#ifdef CONFIG_BLK_DEV_INITRD
|
||||||
|
|
|
@ -98,8 +98,6 @@ void __init x86_64_start_reservations(char *real_mode_data)
|
||||||
{
|
{
|
||||||
copy_bootdata(__va(real_mode_data));
|
copy_bootdata(__va(real_mode_data));
|
||||||
|
|
||||||
reserve_trampoline_memory();
|
|
||||||
|
|
||||||
reserve_early(__pa_symbol(&_text), __pa_symbol(&__bss_stop), "TEXT DATA BSS");
|
reserve_early(__pa_symbol(&_text), __pa_symbol(&__bss_stop), "TEXT DATA BSS");
|
||||||
|
|
||||||
#ifdef CONFIG_BLK_DEV_INITRD
|
#ifdef CONFIG_BLK_DEV_INITRD
|
||||||
|
|
|
@ -945,9 +945,6 @@ void __init early_reserve_e820_mpc_new(void)
|
||||||
{
|
{
|
||||||
if (enable_update_mptable && alloc_mptable) {
|
if (enable_update_mptable && alloc_mptable) {
|
||||||
u64 startt = 0;
|
u64 startt = 0;
|
||||||
#ifdef CONFIG_X86_TRAMPOLINE
|
|
||||||
startt = TRAMPOLINE_BASE;
|
|
||||||
#endif
|
|
||||||
mpc_new_phys = early_reserve_e820(startt, mpc_new_length, 4);
|
mpc_new_phys = early_reserve_e820(startt, mpc_new_length, 4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,6 +73,7 @@
|
||||||
|
|
||||||
#include <asm/mtrr.h>
|
#include <asm/mtrr.h>
|
||||||
#include <asm/apic.h>
|
#include <asm/apic.h>
|
||||||
|
#include <asm/trampoline.h>
|
||||||
#include <asm/e820.h>
|
#include <asm/e820.h>
|
||||||
#include <asm/mpspec.h>
|
#include <asm/mpspec.h>
|
||||||
#include <asm/setup.h>
|
#include <asm/setup.h>
|
||||||
|
@ -875,6 +876,13 @@ void __init setup_arch(char **cmdline_p)
|
||||||
|
|
||||||
reserve_brk();
|
reserve_brk();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Find and reserve possible boot-time SMP configuration:
|
||||||
|
*/
|
||||||
|
find_smp_config();
|
||||||
|
|
||||||
|
reserve_trampoline_memory();
|
||||||
|
|
||||||
#ifdef CONFIG_ACPI_SLEEP
|
#ifdef CONFIG_ACPI_SLEEP
|
||||||
/*
|
/*
|
||||||
* Reserve low memory region for sleep support.
|
* Reserve low memory region for sleep support.
|
||||||
|
@ -921,11 +929,6 @@ void __init setup_arch(char **cmdline_p)
|
||||||
|
|
||||||
early_acpi_boot_init();
|
early_acpi_boot_init();
|
||||||
|
|
||||||
/*
|
|
||||||
* Find and reserve possible boot-time SMP configuration:
|
|
||||||
*/
|
|
||||||
find_smp_config();
|
|
||||||
|
|
||||||
#ifdef CONFIG_ACPI_NUMA
|
#ifdef CONFIG_ACPI_NUMA
|
||||||
/*
|
/*
|
||||||
* Parse SRAT to discover nodes.
|
* Parse SRAT to discover nodes.
|
||||||
|
|
|
@ -12,21 +12,19 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* ready for x86_64 and x86 */
|
/* ready for x86_64 and x86 */
|
||||||
unsigned char *__trampinitdata trampoline_base = __va(TRAMPOLINE_BASE);
|
unsigned char *__trampinitdata trampoline_base;
|
||||||
|
|
||||||
void __init reserve_trampoline_memory(void)
|
void __init reserve_trampoline_memory(void)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_X86_32
|
unsigned long mem;
|
||||||
/*
|
|
||||||
* But first pinch a few for the stack/trampoline stuff
|
|
||||||
* FIXME: Don't need the extra page at 4K, but need to fix
|
|
||||||
* trampoline before removing it. (see the GDT stuff)
|
|
||||||
*/
|
|
||||||
reserve_early(PAGE_SIZE, PAGE_SIZE + PAGE_SIZE, "EX TRAMPOLINE");
|
|
||||||
#endif
|
|
||||||
/* Has to be in very low memory so we can execute real-mode AP code. */
|
/* Has to be in very low memory so we can execute real-mode AP code. */
|
||||||
reserve_early(TRAMPOLINE_BASE, TRAMPOLINE_BASE + TRAMPOLINE_SIZE,
|
mem = find_e820_area(0, 1<<20, TRAMPOLINE_SIZE, PAGE_SIZE);
|
||||||
"TRAMPOLINE");
|
if (mem == -1L)
|
||||||
|
panic("Cannot allocate trampoline\n");
|
||||||
|
|
||||||
|
trampoline_base = __va(mem);
|
||||||
|
reserve_early(mem, mem + TRAMPOLINE_SIZE, "TRAMPOLINE");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in New Issue