aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/apic/apic.c
diff options
context:
space:
mode:
authorWeidong Han <weidong.han@intel.com>2009-04-17 04:42:14 -0400
committerIngo Molnar <mingo@elte.hu>2009-04-19 04:21:43 -0400
commit937582382c71b75b29fbb92615629494e1a05ac0 (patch)
treee73af8d10d388fcc78d19534611db66233907a9e /arch/x86/kernel/apic/apic.c
parent5d0ae2db6deac4f15dac4f42f23bc56448fc8d4d (diff)
x86, intr-remap: enable interrupt remapping early
Currently, when x2apic is not enabled, interrupt remapping will be enabled in init_dmars(), where it is too late to remap ioapic interrupts, that is, ioapic interrupts are really in compatibility mode, not remappable mode. This patch always enables interrupt remapping before ioapic setup, it guarantees all interrupts will be remapped when interrupt remapping is enabled. Thus it doesn't need to set the compatibility interrupt bit. [ Impact: refactor intr-remap init sequence, enable fuller remap mode ] Signed-off-by: Suresh Siddha <suresh.b.siddha@intel.com> Signed-off-by: Weidong Han <weidong.han@intel.com> Acked-by: David Woodhouse <David.Woodhouse@intel.com> Cc: iommu@lists.linux-foundation.org Cc: allen.m.kay@intel.com Cc: fenghua.yu@intel.com LKML-Reference: <1239957736-6161-4-git-send-email-weidong.han@intel.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/kernel/apic/apic.c')
-rw-r--r--arch/x86/kernel/apic/apic.c76
1 files changed, 36 insertions, 40 deletions
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
index 83e47febcc89..0cf1eea750cc 100644
--- a/arch/x86/kernel/apic/apic.c
+++ b/arch/x86/kernel/apic/apic.c
@@ -141,6 +141,8 @@ static int x2apic_preenabled;
141static int disable_x2apic; 141static int disable_x2apic;
142static __init int setup_nox2apic(char *str) 142static __init int setup_nox2apic(char *str)
143{ 143{
144 if (x2apic_enabled())
145 panic("Bios already enabled x2apic, can't enforce nox2apic");
144 disable_x2apic = 1; 146 disable_x2apic = 1;
145 setup_clear_cpu_cap(X86_FEATURE_X2APIC); 147 setup_clear_cpu_cap(X86_FEATURE_X2APIC);
146 return 0; 148 return 0;
@@ -1345,6 +1347,7 @@ void enable_x2apic(void)
1345 wrmsr(MSR_IA32_APICBASE, msr | X2APIC_ENABLE, 0); 1347 wrmsr(MSR_IA32_APICBASE, msr | X2APIC_ENABLE, 0);
1346 } 1348 }
1347} 1349}
1350#endif /* CONFIG_X86_X2APIC */
1348 1351
1349void __init enable_IR_x2apic(void) 1352void __init enable_IR_x2apic(void)
1350{ 1353{
@@ -1353,32 +1356,21 @@ void __init enable_IR_x2apic(void)
1353 unsigned long flags; 1356 unsigned long flags;
1354 struct IO_APIC_route_entry **ioapic_entries = NULL; 1357 struct IO_APIC_route_entry **ioapic_entries = NULL;
1355 1358
1356 if (!cpu_has_x2apic) 1359 ret = dmar_table_init();
1357 return; 1360 if (ret) {
1358 1361 pr_debug("dmar_table_init() failed with %d:\n", ret);
1359 if (!x2apic_preenabled && disable_x2apic) { 1362 goto ir_failed;
1360 pr_info("Skipped enabling x2apic and Interrupt-remapping "
1361 "because of nox2apic\n");
1362 return;
1363 } 1363 }
1364 1364
1365 if (x2apic_preenabled && disable_x2apic) 1365 if (!intr_remapping_supported()) {
1366 panic("Bios already enabled x2apic, can't enforce nox2apic"); 1366 pr_debug("intr-remapping not supported\n");
1367 1367 goto ir_failed;
1368 if (!x2apic_preenabled && skip_ioapic_setup) {
1369 pr_info("Skipped enabling x2apic and Interrupt-remapping "
1370 "because of skipping io-apic setup\n");
1371 return;
1372 } 1368 }
1373 1369
1374 ret = dmar_table_init();
1375 if (ret) {
1376 pr_info("dmar_table_init() failed with %d:\n", ret);
1377 1370
1378 if (x2apic_preenabled) 1371 if (!x2apic_preenabled && skip_ioapic_setup) {
1379 panic("x2apic enabled by bios. But IR enabling failed"); 1372 pr_info("Skipped enabling intr-remap because of skipping "
1380 else 1373 "io-apic setup\n");
1381 pr_info("Not enabling x2apic,Intr-remapping\n");
1382 return; 1374 return;
1383 } 1375 }
1384 1376
@@ -1398,20 +1390,25 @@ void __init enable_IR_x2apic(void)
1398 mask_IO_APIC_setup(ioapic_entries); 1390 mask_IO_APIC_setup(ioapic_entries);
1399 mask_8259A(); 1391 mask_8259A();
1400 1392
1401 ret = enable_intr_remapping(EIM_32BIT_APIC_ID); 1393#ifdef CONFIG_X86_X2APIC
1402 1394 if (cpu_has_x2apic)
1403 if (ret && x2apic_preenabled) { 1395 ret = enable_intr_remapping(EIM_32BIT_APIC_ID);
1404 local_irq_restore(flags); 1396 else
1405 panic("x2apic enabled by bios. But IR enabling failed"); 1397#endif
1406 } 1398 ret = enable_intr_remapping(EIM_8BIT_APIC_ID);
1407 1399
1408 if (ret) 1400 if (ret)
1409 goto end_restore; 1401 goto end_restore;
1410 1402
1411 if (!x2apic) { 1403 pr_info("Enabled Interrupt-remapping\n");
1404
1405#ifdef CONFIG_X86_X2APIC
1406 if (cpu_has_x2apic && !x2apic) {
1412 x2apic = 1; 1407 x2apic = 1;
1413 enable_x2apic(); 1408 enable_x2apic();
1409 pr_info("Enabled x2apic\n");
1414 } 1410 }
1411#endif
1415 1412
1416end_restore: 1413end_restore:
1417 if (ret) 1414 if (ret)
@@ -1426,30 +1423,29 @@ end_restore:
1426 local_irq_restore(flags); 1423 local_irq_restore(flags);
1427 1424
1428end: 1425end:
1429 if (!ret) {
1430 if (!x2apic_preenabled)
1431 pr_info("Enabled x2apic and interrupt-remapping\n");
1432 else
1433 pr_info("Enabled Interrupt-remapping\n");
1434 } else
1435 pr_err("Failed to enable Interrupt-remapping and x2apic\n");
1436 if (ioapic_entries) 1426 if (ioapic_entries)
1437 free_ioapic_entries(ioapic_entries); 1427 free_ioapic_entries(ioapic_entries);
1428
1429 if (!ret)
1430 return;
1431
1432ir_failed:
1433 if (x2apic_preenabled)
1434 panic("x2apic enabled by bios. But IR enabling failed");
1435 else if (cpu_has_x2apic)
1436 pr_info("Not enabling x2apic,Intr-remapping\n");
1438#else 1437#else
1439 if (!cpu_has_x2apic) 1438 if (!cpu_has_x2apic)
1440 return; 1439 return;
1441 1440
1442 if (x2apic_preenabled) 1441 if (x2apic_preenabled)
1443 panic("x2apic enabled prior OS handover," 1442 panic("x2apic enabled prior OS handover,"
1444 " enable CONFIG_INTR_REMAP"); 1443 " enable CONFIG_X86_X2APIC, CONFIG_INTR_REMAP");
1445
1446 pr_info("Enable CONFIG_INTR_REMAP for enabling intr-remapping "
1447 " and x2apic\n");
1448#endif 1444#endif
1449 1445
1450 return; 1446 return;
1451} 1447}
1452#endif /* CONFIG_X86_X2APIC */ 1448
1453 1449
1454#ifdef CONFIG_X86_64 1450#ifdef CONFIG_X86_64
1455/* 1451/*