aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/include/asm/apic.h7
-rw-r--r--arch/x86/kernel/apic/apic.c83
-rw-r--r--arch/x86/kernel/apic/probe_64.c6
3 files changed, 56 insertions, 40 deletions
diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h
index bb7d47925847..586b7adb8e53 100644
--- a/arch/x86/include/asm/apic.h
+++ b/arch/x86/include/asm/apic.h
@@ -183,6 +183,10 @@ static inline int x2apic_enabled(void)
183} 183}
184 184
185#define x2apic_supported() (cpu_has_x2apic) 185#define x2apic_supported() (cpu_has_x2apic)
186static inline void x2apic_force_phys(void)
187{
188 x2apic_phys = 1;
189}
186#else 190#else
187static inline void check_x2apic(void) 191static inline void check_x2apic(void)
188{ 192{
@@ -194,6 +198,9 @@ static inline int x2apic_enabled(void)
194{ 198{
195 return 0; 199 return 0;
196} 200}
201static inline void x2apic_force_phys(void)
202{
203}
197 204
198#define x2apic_preenabled 0 205#define x2apic_preenabled 0
199#define x2apic_supported() 0 206#define x2apic_supported() 0
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
index 0b021c56e822..de039fcdd053 100644
--- a/arch/x86/kernel/apic/apic.c
+++ b/arch/x86/kernel/apic/apic.c
@@ -49,6 +49,7 @@
49#include <asm/mtrr.h> 49#include <asm/mtrr.h>
50#include <asm/smp.h> 50#include <asm/smp.h>
51#include <asm/mce.h> 51#include <asm/mce.h>
52#include <asm/kvm_para.h>
52 53
53unsigned int num_processors; 54unsigned int num_processors;
54 55
@@ -1361,52 +1362,76 @@ void enable_x2apic(void)
1361} 1362}
1362#endif /* CONFIG_X86_X2APIC */ 1363#endif /* CONFIG_X86_X2APIC */
1363 1364
1364void __init enable_IR_x2apic(void) 1365int __init enable_IR(void)
1365{ 1366{
1366#ifdef CONFIG_INTR_REMAP 1367#ifdef CONFIG_INTR_REMAP
1367 int ret; 1368 int ret;
1368 unsigned long flags;
1369 struct IO_APIC_route_entry **ioapic_entries = NULL;
1370 1369
1371 ret = dmar_table_init(); 1370 ret = dmar_table_init();
1372 if (ret) { 1371 if (ret) {
1373 pr_debug("dmar_table_init() failed with %d:\n", ret); 1372 pr_debug("dmar_table_init() failed with %d:\n", ret);
1374 goto ir_failed; 1373 return 0;
1375 } 1374 }
1376 1375
1377 if (!intr_remapping_supported()) { 1376 if (!intr_remapping_supported()) {
1378 pr_debug("intr-remapping not supported\n"); 1377 pr_debug("intr-remapping not supported\n");
1379 goto ir_failed; 1378 return 0;
1380 } 1379 }
1381 1380
1382
1383 if (!x2apic_preenabled && skip_ioapic_setup) { 1381 if (!x2apic_preenabled && skip_ioapic_setup) {
1384 pr_info("Skipped enabling intr-remap because of skipping " 1382 pr_info("Skipped enabling intr-remap because of skipping "
1385 "io-apic setup\n"); 1383 "io-apic setup\n");
1386 return; 1384 return 0;
1387 } 1385 }
1388 1386
1387 if (enable_intr_remapping(x2apic_supported()))
1388 return 0;
1389
1390 pr_info("Enabled Interrupt-remapping\n");
1391
1392 return 1;
1393
1394#endif
1395 return 0;
1396}
1397
1398void __init enable_IR_x2apic(void)
1399{
1400 unsigned long flags;
1401 struct IO_APIC_route_entry **ioapic_entries = NULL;
1402 int ret, x2apic_enabled = 0;
1403
1389 ioapic_entries = alloc_ioapic_entries(); 1404 ioapic_entries = alloc_ioapic_entries();
1390 if (!ioapic_entries) { 1405 if (!ioapic_entries) {
1391 pr_info("Allocate ioapic_entries failed: %d\n", ret); 1406 pr_err("Allocate ioapic_entries failed\n");
1392 goto end; 1407 goto out;
1393 } 1408 }
1394 1409
1395 ret = save_IO_APIC_setup(ioapic_entries); 1410 ret = save_IO_APIC_setup(ioapic_entries);
1396 if (ret) { 1411 if (ret) {
1397 pr_info("Saving IO-APIC state failed: %d\n", ret); 1412 pr_info("Saving IO-APIC state failed: %d\n", ret);
1398 goto end; 1413 goto out;
1399 } 1414 }
1400 1415
1401 local_irq_save(flags); 1416 local_irq_save(flags);
1402 mask_IO_APIC_setup(ioapic_entries);
1403 mask_8259A(); 1417 mask_8259A();
1418 mask_IO_APIC_setup(ioapic_entries);
1404 1419
1405 ret = enable_intr_remapping(x2apic_supported()); 1420 ret = enable_IR();
1406 if (ret) 1421 if (!ret) {
1407 goto end_restore; 1422 /* IR is required if there is APIC ID > 255 even when running
1423 * under KVM
1424 */
1425 if (max_physical_apicid > 255 || !kvm_para_available())
1426 goto nox2apic;
1427 /*
1428 * without IR all CPUs can be addressed by IOAPIC/MSI
1429 * only in physical mode
1430 */
1431 x2apic_force_phys();
1432 }
1408 1433
1409 pr_info("Enabled Interrupt-remapping\n"); 1434 x2apic_enabled = 1;
1410 1435
1411 if (x2apic_supported() && !x2apic_mode) { 1436 if (x2apic_supported() && !x2apic_mode) {
1412 x2apic_mode = 1; 1437 x2apic_mode = 1;
@@ -1414,41 +1439,25 @@ void __init enable_IR_x2apic(void)
1414 pr_info("Enabled x2apic\n"); 1439 pr_info("Enabled x2apic\n");
1415 } 1440 }
1416 1441
1417end_restore: 1442nox2apic:
1418 if (ret) 1443 if (!ret) /* IR enabling failed */
1419 /*
1420 * IR enabling failed
1421 */
1422 restore_IO_APIC_setup(ioapic_entries); 1444 restore_IO_APIC_setup(ioapic_entries);
1423
1424 unmask_8259A(); 1445 unmask_8259A();
1425 local_irq_restore(flags); 1446 local_irq_restore(flags);
1426 1447
1427end: 1448out:
1428 if (ioapic_entries) 1449 if (ioapic_entries)
1429 free_ioapic_entries(ioapic_entries); 1450 free_ioapic_entries(ioapic_entries);
1430 1451
1431 if (!ret) 1452 if (x2apic_enabled)
1432 return; 1453 return;
1433 1454
1434ir_failed:
1435 if (x2apic_preenabled) 1455 if (x2apic_preenabled)
1436 panic("x2apic enabled by bios. But IR enabling failed"); 1456 panic("x2apic: enabled by BIOS but kernel init failed.");
1437 else if (cpu_has_x2apic) 1457 else if (cpu_has_x2apic)
1438 pr_info("Not enabling x2apic,Intr-remapping\n"); 1458 pr_info("Not enabling x2apic, Intr-remapping init failed.\n");
1439#else
1440 if (!cpu_has_x2apic)
1441 return;
1442
1443 if (x2apic_preenabled)
1444 panic("x2apic enabled prior OS handover,"
1445 " enable CONFIG_X86_X2APIC, CONFIG_INTR_REMAP");
1446#endif
1447
1448 return;
1449} 1459}
1450 1460
1451
1452#ifdef CONFIG_X86_64 1461#ifdef CONFIG_X86_64
1453/* 1462/*
1454 * Detect and enable local APICs on non-SMP boards. 1463 * Detect and enable local APICs on non-SMP boards.
diff --git a/arch/x86/kernel/apic/probe_64.c b/arch/x86/kernel/apic/probe_64.c
index bc3e880f9b82..f3b1037076e4 100644
--- a/arch/x86/kernel/apic/probe_64.c
+++ b/arch/x86/kernel/apic/probe_64.c
@@ -50,11 +50,11 @@ static struct apic *apic_probe[] __initdata = {
50void __init default_setup_apic_routing(void) 50void __init default_setup_apic_routing(void)
51{ 51{
52#ifdef CONFIG_X86_X2APIC 52#ifdef CONFIG_X86_X2APIC
53 if (x2apic_mode && (apic != &apic_x2apic_phys && 53 if (x2apic_mode
54#ifdef CONFIG_X86_UV 54#ifdef CONFIG_X86_UV
55 apic != &apic_x2apic_uv_x && 55 && apic != &apic_x2apic_uv_x
56#endif 56#endif
57 apic != &apic_x2apic_cluster)) { 57 ) {
58 if (x2apic_phys) 58 if (x2apic_phys)
59 apic = &apic_x2apic_phys; 59 apic = &apic_x2apic_phys;
60 else 60 else