aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/apic/apic.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kernel/apic/apic.c')
-rw-r--r--arch/x86/kernel/apic/apic.c35
1 files changed, 23 insertions, 12 deletions
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
index f9cecdfd05c5..85eb8e100818 100644
--- a/arch/x86/kernel/apic/apic.c
+++ b/arch/x86/kernel/apic/apic.c
@@ -46,6 +46,7 @@
46#include <asm/idle.h> 46#include <asm/idle.h>
47#include <asm/mtrr.h> 47#include <asm/mtrr.h>
48#include <asm/smp.h> 48#include <asm/smp.h>
49#include <asm/mce.h>
49 50
50unsigned int num_processors; 51unsigned int num_processors;
51 52
@@ -808,7 +809,7 @@ void clear_local_APIC(void)
808 u32 v; 809 u32 v;
809 810
810 /* APIC hasn't been mapped yet */ 811 /* APIC hasn't been mapped yet */
811 if (!apic_phys) 812 if (!x2apic && !apic_phys)
812 return; 813 return;
813 814
814 maxlvt = lapic_get_maxlvt(); 815 maxlvt = lapic_get_maxlvt();
@@ -842,6 +843,14 @@ void clear_local_APIC(void)
842 apic_write(APIC_LVTTHMR, v | APIC_LVT_MASKED); 843 apic_write(APIC_LVTTHMR, v | APIC_LVT_MASKED);
843 } 844 }
844#endif 845#endif
846#ifdef CONFIG_X86_MCE_INTEL
847 if (maxlvt >= 6) {
848 v = apic_read(APIC_LVTCMCI);
849 if (!(v & APIC_LVT_MASKED))
850 apic_write(APIC_LVTCMCI, v | APIC_LVT_MASKED);
851 }
852#endif
853
845 /* 854 /*
846 * Clean APIC state for other OSs: 855 * Clean APIC state for other OSs:
847 */ 856 */
@@ -1241,6 +1250,12 @@ void __cpuinit setup_local_APIC(void)
1241 apic_write(APIC_LVT1, value); 1250 apic_write(APIC_LVT1, value);
1242 1251
1243 preempt_enable(); 1252 preempt_enable();
1253
1254#ifdef CONFIG_X86_MCE_INTEL
1255 /* Recheck CMCI information after local APIC is up on CPU #0 */
1256 if (smp_processor_id() == 0)
1257 cmci_recheck();
1258#endif
1244} 1259}
1245 1260
1246void __cpuinit end_local_APIC_setup(void) 1261void __cpuinit end_local_APIC_setup(void)
@@ -1319,15 +1334,16 @@ void __init enable_IR_x2apic(void)
1319 return; 1334 return;
1320 } 1335 }
1321 1336
1322 local_irq_save(flags); 1337 ret = save_IO_APIC_setup();
1323 mask_8259A();
1324
1325 ret = save_mask_IO_APIC_setup();
1326 if (ret) { 1338 if (ret) {
1327 pr_info("Saving IO-APIC state failed: %d\n", ret); 1339 pr_info("Saving IO-APIC state failed: %d\n", ret);
1328 goto end; 1340 goto end;
1329 } 1341 }
1330 1342
1343 local_irq_save(flags);
1344 mask_IO_APIC_setup();
1345 mask_8259A();
1346
1331 ret = enable_intr_remapping(1); 1347 ret = enable_intr_remapping(1);
1332 1348
1333 if (ret && x2apic_preenabled) { 1349 if (ret && x2apic_preenabled) {
@@ -1352,10 +1368,10 @@ end_restore:
1352 else 1368 else
1353 reinit_intr_remapped_IO_APIC(x2apic_preenabled); 1369 reinit_intr_remapped_IO_APIC(x2apic_preenabled);
1354 1370
1355end:
1356 unmask_8259A(); 1371 unmask_8259A();
1357 local_irq_restore(flags); 1372 local_irq_restore(flags);
1358 1373
1374end:
1359 if (!ret) { 1375 if (!ret) {
1360 if (!x2apic_preenabled) 1376 if (!x2apic_preenabled)
1361 pr_info("Enabled x2apic and interrupt-remapping\n"); 1377 pr_info("Enabled x2apic and interrupt-remapping\n");
@@ -1508,12 +1524,10 @@ void __init early_init_lapic_mapping(void)
1508 */ 1524 */
1509void __init init_apic_mappings(void) 1525void __init init_apic_mappings(void)
1510{ 1526{
1511#ifdef CONFIG_X86_X2APIC
1512 if (x2apic) { 1527 if (x2apic) {
1513 boot_cpu_physical_apicid = read_apic_id(); 1528 boot_cpu_physical_apicid = read_apic_id();
1514 return; 1529 return;
1515 } 1530 }
1516#endif
1517 1531
1518 /* 1532 /*
1519 * If no local APIC can be found then set up a fake all 1533 * If no local APIC can be found then set up a fake all
@@ -1957,12 +1971,9 @@ static int lapic_resume(struct sys_device *dev)
1957 1971
1958 local_irq_save(flags); 1972 local_irq_save(flags);
1959 1973
1960#ifdef CONFIG_X86_X2APIC
1961 if (x2apic) 1974 if (x2apic)
1962 enable_x2apic(); 1975 enable_x2apic();
1963 else 1976 else {
1964#endif
1965 {
1966 /* 1977 /*
1967 * Make sure the APICBASE points to the right address 1978 * Make sure the APICBASE points to the right address
1968 * 1979 *