diff options
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 | /* |