diff options
author | Weidong Han <weidong.han@intel.com> | 2009-04-17 04:42:14 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-04-19 04:21:43 -0400 |
commit | 937582382c71b75b29fbb92615629494e1a05ac0 (patch) | |
tree | e73af8d10d388fcc78d19534611db66233907a9e /arch/x86/kernel/apic/apic.c | |
parent | 5d0ae2db6deac4f15dac4f42f23bc56448fc8d4d (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.c | 76 |
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; | |||
141 | static int disable_x2apic; | 141 | static int disable_x2apic; |
142 | static __init int setup_nox2apic(char *str) | 142 | static __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 | ||
1349 | void __init enable_IR_x2apic(void) | 1352 | void __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 | ||
1416 | end_restore: | 1413 | end_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 | ||
1428 | end: | 1425 | end: |
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 | |||
1432 | ir_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 | /* |