Commit d3432896 authored by Andi Kleen's avatar Andi Kleen Committed by Ingo Molnar

x86: don't disable the APIC if it hasn't been mapped yet

When the kernel panics early for some unrelated reason
there would be eventually an early exception inside panic because
clear_local_APIC tried to disable the not yet mapped APIC.
Check for that explicitely.
Signed-off-by: default avatarAndi Kleen <ak@suse.de>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
parent ca74a6f8
...@@ -99,6 +99,8 @@ static DEFINE_PER_CPU(struct clock_event_device, lapic_events); ...@@ -99,6 +99,8 @@ static DEFINE_PER_CPU(struct clock_event_device, lapic_events);
/* Local APIC was disabled by the BIOS and enabled by the kernel */ /* Local APIC was disabled by the BIOS and enabled by the kernel */
static int enabled_via_apicbase; static int enabled_via_apicbase;
static unsigned long apic_phys;
/* /*
* Get the LAPIC version * Get the LAPIC version
*/ */
...@@ -631,9 +633,14 @@ int setup_profiling_timer(unsigned int multiplier) ...@@ -631,9 +633,14 @@ int setup_profiling_timer(unsigned int multiplier)
*/ */
void clear_local_APIC(void) void clear_local_APIC(void)
{ {
int maxlvt = lapic_get_maxlvt(); int maxlvt;
u32 v; u32 v;
/* APIC hasn't been mapped yet */
if (!apic_phys)
return;
maxlvt = lapic_get_maxlvt();
/* /*
* Masking an LVT entry can trigger a local APIC error * Masking an LVT entry can trigger a local APIC error
* if the vector is zero. Mask LVTERR first to prevent this. * if the vector is zero. Mask LVTERR first to prevent this.
...@@ -1120,8 +1127,6 @@ no_apic: ...@@ -1120,8 +1127,6 @@ no_apic:
*/ */
void __init init_apic_mappings(void) void __init init_apic_mappings(void)
{ {
unsigned long apic_phys;
/* /*
* If no local APIC can be found then set up a fake all * If no local APIC can be found then set up a fake all
* zeroes page to simulate the local APIC and another * zeroes page to simulate the local APIC and another
......
...@@ -81,6 +81,8 @@ static struct clock_event_device lapic_clockevent = { ...@@ -81,6 +81,8 @@ static struct clock_event_device lapic_clockevent = {
}; };
static DEFINE_PER_CPU(struct clock_event_device, lapic_events); static DEFINE_PER_CPU(struct clock_event_device, lapic_events);
static unsigned long apic_phys;
/* /*
* Get the LAPIC version * Get the LAPIC version
*/ */
...@@ -525,6 +527,11 @@ void clear_local_APIC(void) ...@@ -525,6 +527,11 @@ void clear_local_APIC(void)
int maxlvt = lapic_get_maxlvt(); int maxlvt = lapic_get_maxlvt();
u32 v; u32 v;
/* APIC hasn't been mapped yet */
if (!apic_phys)
return;
maxlvt = lapic_get_maxlvt();
/* /*
* Masking an LVT entry can trigger a local APIC error * Masking an LVT entry can trigger a local APIC error
* if the vector is zero. Mask LVTERR first to prevent this. * if the vector is zero. Mask LVTERR first to prevent this.
...@@ -859,8 +866,6 @@ static int __init detect_init_APIC(void) ...@@ -859,8 +866,6 @@ static int __init detect_init_APIC(void)
*/ */
void __init init_apic_mappings(void) void __init init_apic_mappings(void)
{ {
unsigned long apic_phys;
/* /*
* If no local APIC can be found then set up a fake all * If no local APIC can be found then set up a fake all
* zeroes page to simulate the local APIC and another * zeroes page to simulate the local APIC and another
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment