aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86
diff options
context:
space:
mode:
authorAndi Kleen <ak@suse.de>2008-01-30 07:33:17 -0500
committerIngo Molnar <mingo@elte.hu>2008-01-30 07:33:17 -0500
commitd3432896dae72ee97deb850ad7bbc30329d32c0d (patch)
tree73cc99efc6ca0ef5f8caabd6eed1e2a50196ca5e /arch/x86
parentca74a6f84e68b44867022f4a4f3ec17c087c864e (diff)
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>
Diffstat (limited to 'arch/x86')
-rw-r--r--arch/x86/kernel/apic_32.c11
-rw-r--r--arch/x86/kernel/apic_64.c9
2 files changed, 15 insertions, 5 deletions
diff --git a/arch/x86/kernel/apic_32.c b/arch/x86/kernel/apic_32.c
index d07a603807d1..35a568ea8400 100644
--- a/arch/x86/kernel/apic_32.c
+++ b/arch/x86/kernel/apic_32.c
@@ -99,6 +99,8 @@ static DEFINE_PER_CPU(struct clock_event_device, lapic_events);
99/* Local APIC was disabled by the BIOS and enabled by the kernel */ 99/* Local APIC was disabled by the BIOS and enabled by the kernel */
100static int enabled_via_apicbase; 100static int enabled_via_apicbase;
101 101
102static unsigned long apic_phys;
103
102/* 104/*
103 * Get the LAPIC version 105 * Get the LAPIC version
104 */ 106 */
@@ -631,9 +633,14 @@ int setup_profiling_timer(unsigned int multiplier)
631 */ 633 */
632void clear_local_APIC(void) 634void clear_local_APIC(void)
633{ 635{
634 int maxlvt = lapic_get_maxlvt(); 636 int maxlvt;
635 u32 v; 637 u32 v;
636 638
639 /* APIC hasn't been mapped yet */
640 if (!apic_phys)
641 return;
642
643 maxlvt = lapic_get_maxlvt();
637 /* 644 /*
638 * Masking an LVT entry can trigger a local APIC error 645 * Masking an LVT entry can trigger a local APIC error
639 * if the vector is zero. Mask LVTERR first to prevent this. 646 * if the vector is zero. Mask LVTERR first to prevent this.
@@ -1120,8 +1127,6 @@ no_apic:
1120 */ 1127 */
1121void __init init_apic_mappings(void) 1128void __init init_apic_mappings(void)
1122{ 1129{
1123 unsigned long apic_phys;
1124
1125 /* 1130 /*
1126 * If no local APIC can be found then set up a fake all 1131 * If no local APIC can be found then set up a fake all
1127 * zeroes page to simulate the local APIC and another 1132 * zeroes page to simulate the local APIC and another
diff --git a/arch/x86/kernel/apic_64.c b/arch/x86/kernel/apic_64.c
index 85bd3d463cdf..a7a38c9da136 100644
--- a/arch/x86/kernel/apic_64.c
+++ b/arch/x86/kernel/apic_64.c
@@ -81,6 +81,8 @@ static struct clock_event_device lapic_clockevent = {
81}; 81};
82static DEFINE_PER_CPU(struct clock_event_device, lapic_events); 82static DEFINE_PER_CPU(struct clock_event_device, lapic_events);
83 83
84static unsigned long apic_phys;
85
84/* 86/*
85 * Get the LAPIC version 87 * Get the LAPIC version
86 */ 88 */
@@ -525,6 +527,11 @@ void clear_local_APIC(void)
525 int maxlvt = lapic_get_maxlvt(); 527 int maxlvt = lapic_get_maxlvt();
526 u32 v; 528 u32 v;
527 529
530 /* APIC hasn't been mapped yet */
531 if (!apic_phys)
532 return;
533
534 maxlvt = lapic_get_maxlvt();
528 /* 535 /*
529 * Masking an LVT entry can trigger a local APIC error 536 * Masking an LVT entry can trigger a local APIC error
530 * if the vector is zero. Mask LVTERR first to prevent this. 537 * if the vector is zero. Mask LVTERR first to prevent this.
@@ -859,8 +866,6 @@ static int __init detect_init_APIC(void)
859 */ 866 */
860void __init init_apic_mappings(void) 867void __init init_apic_mappings(void)
861{ 868{
862 unsigned long apic_phys;
863
864 /* 869 /*
865 * If no local APIC can be found then set up a fake all 870 * If no local APIC can be found then set up a fake all
866 * zeroes page to simulate the local APIC and another 871 * zeroes page to simulate the local APIC and another