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: Andi Kleen <ak@suse.de> Signed-off-by: Ingo Molnar <mingo@elte.hu> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
This commit is contained in:
Родитель
ca74a6f84e
Коммит
d3432896da
|
@ -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)
|
||||||
*/
|
*/
|
||||||
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:
|
||||||
*/
|
*/
|
||||||
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 = {
|
||||||
};
|
};
|
||||||
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)
|
||||||
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)
|
||||||
*/
|
*/
|
||||||
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
|
||||||
|
|
Загрузка…
Ссылка в новой задаче