aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/include/asm/apic.h7
-rw-r--r--arch/x86/kernel/apic/apic.c76
-rw-r--r--drivers/pci/intel-iommu.c9
-rw-r--r--drivers/pci/intr_remapping.c28
-rw-r--r--include/linux/dmar.h1
5 files changed, 54 insertions, 67 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/*
diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c
index 001b328adf80..9ce8f0764bef 100644
--- a/drivers/pci/intel-iommu.c
+++ b/drivers/pci/intel-iommu.c
@@ -1968,15 +1968,6 @@ static int __init init_dmars(void)
1968 } 1968 }
1969 } 1969 }
1970 1970
1971#ifdef CONFIG_INTR_REMAP
1972 if (!intr_remapping_enabled) {
1973 ret = enable_intr_remapping(0);
1974 if (ret)
1975 printk(KERN_ERR
1976 "IOMMU: enable interrupt remapping failed\n");
1977 }
1978#endif
1979
1980 /* 1971 /*
1981 * For each rmrr 1972 * For each rmrr
1982 * for each dev attached to rmrr 1973 * for each dev attached to rmrr
diff --git a/drivers/pci/intr_remapping.c b/drivers/pci/intr_remapping.c
index f5e0ea724a6f..5c2142656e96 100644
--- a/drivers/pci/intr_remapping.c
+++ b/drivers/pci/intr_remapping.c
@@ -423,20 +423,6 @@ static void iommu_set_intr_remapping(struct intel_iommu *iommu, int mode)
423 readl, (sts & DMA_GSTS_IRTPS), sts); 423 readl, (sts & DMA_GSTS_IRTPS), sts);
424 spin_unlock_irqrestore(&iommu->register_lock, flags); 424 spin_unlock_irqrestore(&iommu->register_lock, flags);
425 425
426 if (mode == 0) {
427 spin_lock_irqsave(&iommu->register_lock, flags);
428
429 /* enable comaptiblity format interrupt pass through */
430 cmd = iommu->gcmd | DMA_GCMD_CFI;
431 iommu->gcmd |= DMA_GCMD_CFI;
432 writel(cmd, iommu->reg + DMAR_GCMD_REG);
433
434 IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG,
435 readl, (sts & DMA_GSTS_CFIS), sts);
436
437 spin_unlock_irqrestore(&iommu->register_lock, flags);
438 }
439
440 /* 426 /*
441 * global invalidation of interrupt entry cache before enabling 427 * global invalidation of interrupt entry cache before enabling
442 * interrupt-remapping. 428 * interrupt-remapping.
@@ -516,6 +502,20 @@ end:
516 spin_unlock_irqrestore(&iommu->register_lock, flags); 502 spin_unlock_irqrestore(&iommu->register_lock, flags);
517} 503}
518 504
505int __init intr_remapping_supported(void)
506{
507 struct dmar_drhd_unit *drhd;
508
509 for_each_drhd_unit(drhd) {
510 struct intel_iommu *iommu = drhd->iommu;
511
512 if (!ecap_ir_support(iommu->ecap))
513 return 0;
514 }
515
516 return 1;
517}
518
519int __init enable_intr_remapping(int eim) 519int __init enable_intr_remapping(int eim)
520{ 520{
521 struct dmar_drhd_unit *drhd; 521 struct dmar_drhd_unit *drhd;
diff --git a/include/linux/dmar.h b/include/linux/dmar.h
index e397dc342cda..06f592a7f73c 100644
--- a/include/linux/dmar.h
+++ b/include/linux/dmar.h
@@ -108,6 +108,7 @@ struct irte {
108}; 108};
109#ifdef CONFIG_INTR_REMAP 109#ifdef CONFIG_INTR_REMAP
110extern int intr_remapping_enabled; 110extern int intr_remapping_enabled;
111extern int intr_remapping_supported(void);
111extern int enable_intr_remapping(int); 112extern int enable_intr_remapping(int);
112extern void disable_intr_remapping(void); 113extern void disable_intr_remapping(void);
113extern int reenable_intr_remapping(int); 114extern int reenable_intr_remapping(int);