x86/boot: Fix boot failure when SMP MP-table is based at 0
authorTom Lendacky <thomas.lendacky@amd.com>
Mon, 6 Nov 2017 20:17:53 +0000 (14:17 -0600)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 30 Nov 2017 08:40:39 +0000 (08:40 +0000)
commit ac5292e9a294618cecb31109d1ba265e3d027ba2 upstream.

When crosvm is used to boot a kernel as a VM, the SMP MP-table is found
at physical address 0x0. This causes mpf_base to be set to 0 and a
subsequent "if (!mpf_base)" check in default_get_smp_config() results in
the MP-table not being parsed.  Further into the boot this results in an
oops when attempting a read_apic_id().

Add a boolean variable that is set to true when the MP-table is found.
Use this variable for testing if the MP-table was found so that even a
value of 0 for mpf_base will result in continued parsing of the MP-table.

Fixes: 5997efb96756 ("x86/boot: Use memremap() to map the MPF and MPC data")
Reported-by: Tomeu Vizoso <tomeu@tomeuvizoso.net>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Borislav Petkov <bp@alien8.de>
Cc: regression@leemhuis.info
Link: https://lkml.kernel.org/r/20171106201753.23059.86674.stgit@tlendack-t1.amdoffice.net
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
arch/x86/kernel/mpparse.c

index 410c5dadcee31930f8c30ddaeb1b4c940835a081..3a4b12809ab5f810f5a8657bfcc3f7521450e645 100644 (file)
@@ -431,6 +431,7 @@ static inline void __init construct_default_ISA_mptable(int mpc_default_type)
 }
 
 static unsigned long mpf_base;
+static bool mpf_found;
 
 static unsigned long __init get_mpc_size(unsigned long physptr)
 {
@@ -504,7 +505,7 @@ void __init default_get_smp_config(unsigned int early)
        if (!smp_found_config)
                return;
 
-       if (!mpf_base)
+       if (!mpf_found)
                return;
 
        if (acpi_lapic && early)
@@ -593,6 +594,7 @@ static int __init smp_scan_config(unsigned long base, unsigned long length)
                        smp_found_config = 1;
 #endif
                        mpf_base = base;
+                       mpf_found = true;
 
                        pr_info("found SMP MP-table at [mem %#010lx-%#010lx] mapped at [%p]\n",
                                base, base + sizeof(*mpf) - 1, mpf);
@@ -858,7 +860,7 @@ static int __init update_mp_table(void)
        if (!enable_update_mptable)
                return 0;
 
-       if (!mpf_base)
+       if (!mpf_found)
                return 0;
 
        mpf = early_memremap(mpf_base, sizeof(*mpf));