aboutsummaryrefslogtreecommitdiffstats
path: root/arch
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
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')
-rw-r--r--arch/x86/include/asm/apic.h7
-rw-r--r--arch/x86/kernel/apic/apic.c76
2 files changed, 39 insertions, 44 deletions
diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h
index d4cb7e590c06..fbdd65446c7a 100644
--- a/arch/x86/include/asm/apic.h
+++ b/arch/x86/include/asm/apic.h
@@ -169,7 +169,6 @@ static inline u64 native_x2apic_icr_read(void)
169extern int x2apic, x2apic_phys; 169extern int x2apic, x2apic_phys;
170extern void check_x2apic(void); 170extern void check_x2apic(void);
171extern void enable_x2apic(void); 171extern void enable_x2apic(void);
172extern void enable_IR_x2apic(void);
173extern void x2apic_icr_write(u32 low, u32 id); 172extern void x2apic_icr_write(u32 low, u32 id);
174static inline int x2apic_enabled(void) 173static inline int x2apic_enabled(void)
175{ 174{
@@ -190,18 +189,18 @@ static inline void check_x2apic(void)
190static inline void enable_x2apic(void) 189static inline void enable_x2apic(void)
191{ 190{
192} 191}
193static inline void enable_IR_x2apic(void)
194{
195}
196static inline int x2apic_enabled(void) 192static inline int x2apic_enabled(void)
197{ 193{
198 return 0; 194 return 0;
199} 195}
200 196
201#define x2apic 0 197#define x2apic 0
198#define x2apic_preenabled 0
202 199
203#endif 200#endif
204 201
202extern void enable_IR_x2apic(void);
203
205extern int get_physical_broadcast(void); 204extern int get_physical_broadcast(void);
206 205
207extern void apic_disable(void); 206extern void apic_disable(void);
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/*