aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/iommu
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-10-26 10:11:53 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-10-26 10:11:53 -0400
commit982653009b883ef1529089e3e6f1ae2fee41cbe2 (patch)
treeeec3b1fe947d442ee204a2d648133bc5223e5c59 /drivers/iommu
parent37d96c28ecf0af1215bb6bbf580dbb1fabb5a6ec (diff)
parentc020570138f5d9cb1fc0a853f9cf9e641178b5c5 (diff)
Merge branch 'core-iommu-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
* 'core-iommu-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: x86, ioapic: Consolidate the explicit EOI code x86, ioapic: Restore the mask bit correctly in eoi_ioapic_irq() x86, kdump, ioapic: Reset remote-IRR in clear_IO_APIC iommu: Rename the DMAR and INTR_REMAP config options x86, ioapic: Define irq_remap_modify_chip_defaults() x86, msi, intr-remap: Use the ioapic set affinity routine iommu: Cleanup ifdefs in detect_intel_iommu() iommu: No need to set dmar_disabled in check_zero_address() iommu: Move IOMMU specific code to intel-iommu.c intr_remap: Call dmar_dev_scope_init() explicitly x86, x2apic: Enable the bios request for x2apic optout
Diffstat (limited to 'drivers/iommu')
-rw-r--r--drivers/iommu/Kconfig25
-rw-r--r--drivers/iommu/Makefile5
-rw-r--r--drivers/iommu/dmar.c198
-rw-r--r--drivers/iommu/intel-iommu.c167
-rw-r--r--drivers/iommu/intr_remapping.c53
5 files changed, 244 insertions, 204 deletions
diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index b57b3fa492f3..7d7eaa15e773 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -59,10 +59,14 @@ config AMD_IOMMU_STATS
59 If unsure, say N. 59 If unsure, say N.
60 60
61# Intel IOMMU support 61# Intel IOMMU support
62config DMAR 62config DMAR_TABLE
63 bool "Support for DMA Remapping Devices" 63 bool
64
65config INTEL_IOMMU
66 bool "Support for Intel IOMMU using DMA Remapping Devices"
64 depends on PCI_MSI && ACPI && (X86 || IA64_GENERIC) 67 depends on PCI_MSI && ACPI && (X86 || IA64_GENERIC)
65 select IOMMU_API 68 select IOMMU_API
69 select DMAR_TABLE
66 help 70 help
67 DMA remapping (DMAR) devices support enables independent address 71 DMA remapping (DMAR) devices support enables independent address
68 translations for Direct Memory Access (DMA) from devices. 72 translations for Direct Memory Access (DMA) from devices.
@@ -70,18 +74,18 @@ config DMAR
70 and include PCI device scope covered by these DMA 74 and include PCI device scope covered by these DMA
71 remapping devices. 75 remapping devices.
72 76
73config DMAR_DEFAULT_ON 77config INTEL_IOMMU_DEFAULT_ON
74 def_bool y 78 def_bool y
75 prompt "Enable DMA Remapping Devices by default" 79 prompt "Enable Intel DMA Remapping Devices by default"
76 depends on DMAR 80 depends on INTEL_IOMMU
77 help 81 help
78 Selecting this option will enable a DMAR device at boot time if 82 Selecting this option will enable a DMAR device at boot time if
79 one is found. If this option is not selected, DMAR support can 83 one is found. If this option is not selected, DMAR support can
80 be enabled by passing intel_iommu=on to the kernel. 84 be enabled by passing intel_iommu=on to the kernel.
81 85
82config DMAR_BROKEN_GFX_WA 86config INTEL_IOMMU_BROKEN_GFX_WA
83 bool "Workaround broken graphics drivers (going away soon)" 87 bool "Workaround broken graphics drivers (going away soon)"
84 depends on DMAR && BROKEN && X86 88 depends on INTEL_IOMMU && BROKEN && X86
85 ---help--- 89 ---help---
86 Current Graphics drivers tend to use physical address 90 Current Graphics drivers tend to use physical address
87 for DMA and avoid using DMA APIs. Setting this config 91 for DMA and avoid using DMA APIs. Setting this config
@@ -90,18 +94,19 @@ config DMAR_BROKEN_GFX_WA
90 to use physical addresses for DMA, at least until this 94 to use physical addresses for DMA, at least until this
91 option is removed in the 2.6.32 kernel. 95 option is removed in the 2.6.32 kernel.
92 96
93config DMAR_FLOPPY_WA 97config INTEL_IOMMU_FLOPPY_WA
94 def_bool y 98 def_bool y
95 depends on DMAR && X86 99 depends on INTEL_IOMMU && X86
96 ---help--- 100 ---help---
97 Floppy disk drivers are known to bypass DMA API calls 101 Floppy disk drivers are known to bypass DMA API calls
98 thereby failing to work when IOMMU is enabled. This 102 thereby failing to work when IOMMU is enabled. This
99 workaround will setup a 1:1 mapping for the first 103 workaround will setup a 1:1 mapping for the first
100 16MiB to make floppy (an ISA device) work. 104 16MiB to make floppy (an ISA device) work.
101 105
102config INTR_REMAP 106config IRQ_REMAP
103 bool "Support for Interrupt Remapping (EXPERIMENTAL)" 107 bool "Support for Interrupt Remapping (EXPERIMENTAL)"
104 depends on X86_64 && X86_IO_APIC && PCI_MSI && ACPI && EXPERIMENTAL 108 depends on X86_64 && X86_IO_APIC && PCI_MSI && ACPI && EXPERIMENTAL
109 select DMAR_TABLE
105 ---help--- 110 ---help---
106 Supports Interrupt remapping for IO-APIC and MSI devices. 111 Supports Interrupt remapping for IO-APIC and MSI devices.
107 To use x2apic mode in the CPU's which support x2APIC enhancements or 112 To use x2apic mode in the CPU's which support x2APIC enhancements or
diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile
index 4d4d77df7cac..6394994a2b9d 100644
--- a/drivers/iommu/Makefile
+++ b/drivers/iommu/Makefile
@@ -1,5 +1,6 @@
1obj-$(CONFIG_IOMMU_API) += iommu.o 1obj-$(CONFIG_IOMMU_API) += iommu.o
2obj-$(CONFIG_MSM_IOMMU) += msm_iommu.o msm_iommu_dev.o 2obj-$(CONFIG_MSM_IOMMU) += msm_iommu.o msm_iommu_dev.o
3obj-$(CONFIG_AMD_IOMMU) += amd_iommu.o amd_iommu_init.o 3obj-$(CONFIG_AMD_IOMMU) += amd_iommu.o amd_iommu_init.o
4obj-$(CONFIG_DMAR) += dmar.o iova.o intel-iommu.o 4obj-$(CONFIG_DMAR_TABLE) += dmar.o
5obj-$(CONFIG_INTR_REMAP) += dmar.o intr_remapping.o 5obj-$(CONFIG_INTEL_IOMMU) += iova.o intel-iommu.o
6obj-$(CONFIG_IRQ_REMAP) += intr_remapping.o
diff --git a/drivers/iommu/dmar.c b/drivers/iommu/dmar.c
index 6dcc7e2d54de..587e8f2d38d8 100644
--- a/drivers/iommu/dmar.c
+++ b/drivers/iommu/dmar.c
@@ -46,7 +46,7 @@
46 */ 46 */
47LIST_HEAD(dmar_drhd_units); 47LIST_HEAD(dmar_drhd_units);
48 48
49static struct acpi_table_header * __initdata dmar_tbl; 49struct acpi_table_header * __initdata dmar_tbl;
50static acpi_size dmar_tbl_size; 50static acpi_size dmar_tbl_size;
51 51
52static void __init dmar_register_drhd_unit(struct dmar_drhd_unit *drhd) 52static void __init dmar_register_drhd_unit(struct dmar_drhd_unit *drhd)
@@ -118,8 +118,8 @@ static int __init dmar_parse_one_dev_scope(struct acpi_dmar_device_scope *scope,
118 return 0; 118 return 0;
119} 119}
120 120
121static int __init dmar_parse_dev_scope(void *start, void *end, int *cnt, 121int __init dmar_parse_dev_scope(void *start, void *end, int *cnt,
122 struct pci_dev ***devices, u16 segment) 122 struct pci_dev ***devices, u16 segment)
123{ 123{
124 struct acpi_dmar_device_scope *scope; 124 struct acpi_dmar_device_scope *scope;
125 void * tmp = start; 125 void * tmp = start;
@@ -217,133 +217,6 @@ static int __init dmar_parse_dev(struct dmar_drhd_unit *dmaru)
217 return ret; 217 return ret;
218} 218}
219 219
220#ifdef CONFIG_DMAR
221LIST_HEAD(dmar_rmrr_units);
222
223static void __init dmar_register_rmrr_unit(struct dmar_rmrr_unit *rmrr)
224{
225 list_add(&rmrr->list, &dmar_rmrr_units);
226}
227
228
229static int __init
230dmar_parse_one_rmrr(struct acpi_dmar_header *header)
231{
232 struct acpi_dmar_reserved_memory *rmrr;
233 struct dmar_rmrr_unit *rmrru;
234
235 rmrru = kzalloc(sizeof(*rmrru), GFP_KERNEL);
236 if (!rmrru)
237 return -ENOMEM;
238
239 rmrru->hdr = header;
240 rmrr = (struct acpi_dmar_reserved_memory *)header;
241 rmrru->base_address = rmrr->base_address;
242 rmrru->end_address = rmrr->end_address;
243
244 dmar_register_rmrr_unit(rmrru);
245 return 0;
246}
247
248static int __init
249rmrr_parse_dev(struct dmar_rmrr_unit *rmrru)
250{
251 struct acpi_dmar_reserved_memory *rmrr;
252 int ret;
253
254 rmrr = (struct acpi_dmar_reserved_memory *) rmrru->hdr;
255 ret = dmar_parse_dev_scope((void *)(rmrr + 1),
256 ((void *)rmrr) + rmrr->header.length,
257 &rmrru->devices_cnt, &rmrru->devices, rmrr->segment);
258
259 if (ret || (rmrru->devices_cnt == 0)) {
260 list_del(&rmrru->list);
261 kfree(rmrru);
262 }
263 return ret;
264}
265
266static LIST_HEAD(dmar_atsr_units);
267
268static int __init dmar_parse_one_atsr(struct acpi_dmar_header *hdr)
269{
270 struct acpi_dmar_atsr *atsr;
271 struct dmar_atsr_unit *atsru;
272
273 atsr = container_of(hdr, struct acpi_dmar_atsr, header);
274 atsru = kzalloc(sizeof(*atsru), GFP_KERNEL);
275 if (!atsru)
276 return -ENOMEM;
277
278 atsru->hdr = hdr;
279 atsru->include_all = atsr->flags & 0x1;
280
281 list_add(&atsru->list, &dmar_atsr_units);
282
283 return 0;
284}
285
286static int __init atsr_parse_dev(struct dmar_atsr_unit *atsru)
287{
288 int rc;
289 struct acpi_dmar_atsr *atsr;
290
291 if (atsru->include_all)
292 return 0;
293
294 atsr = container_of(atsru->hdr, struct acpi_dmar_atsr, header);
295 rc = dmar_parse_dev_scope((void *)(atsr + 1),
296 (void *)atsr + atsr->header.length,
297 &atsru->devices_cnt, &atsru->devices,
298 atsr->segment);
299 if (rc || !atsru->devices_cnt) {
300 list_del(&atsru->list);
301 kfree(atsru);
302 }
303
304 return rc;
305}
306
307int dmar_find_matched_atsr_unit(struct pci_dev *dev)
308{
309 int i;
310 struct pci_bus *bus;
311 struct acpi_dmar_atsr *atsr;
312 struct dmar_atsr_unit *atsru;
313
314 dev = pci_physfn(dev);
315
316 list_for_each_entry(atsru, &dmar_atsr_units, list) {
317 atsr = container_of(atsru->hdr, struct acpi_dmar_atsr, header);
318 if (atsr->segment == pci_domain_nr(dev->bus))
319 goto found;
320 }
321
322 return 0;
323
324found:
325 for (bus = dev->bus; bus; bus = bus->parent) {
326 struct pci_dev *bridge = bus->self;
327
328 if (!bridge || !pci_is_pcie(bridge) ||
329 bridge->pcie_type == PCI_EXP_TYPE_PCI_BRIDGE)
330 return 0;
331
332 if (bridge->pcie_type == PCI_EXP_TYPE_ROOT_PORT) {
333 for (i = 0; i < atsru->devices_cnt; i++)
334 if (atsru->devices[i] == bridge)
335 return 1;
336 break;
337 }
338 }
339
340 if (atsru->include_all)
341 return 1;
342
343 return 0;
344}
345#endif
346
347#ifdef CONFIG_ACPI_NUMA 220#ifdef CONFIG_ACPI_NUMA
348static int __init 221static int __init
349dmar_parse_one_rhsa(struct acpi_dmar_header *header) 222dmar_parse_one_rhsa(struct acpi_dmar_header *header)
@@ -484,14 +357,10 @@ parse_dmar_table(void)
484 ret = dmar_parse_one_drhd(entry_header); 357 ret = dmar_parse_one_drhd(entry_header);
485 break; 358 break;
486 case ACPI_DMAR_TYPE_RESERVED_MEMORY: 359 case ACPI_DMAR_TYPE_RESERVED_MEMORY:
487#ifdef CONFIG_DMAR
488 ret = dmar_parse_one_rmrr(entry_header); 360 ret = dmar_parse_one_rmrr(entry_header);
489#endif
490 break; 361 break;
491 case ACPI_DMAR_TYPE_ATSR: 362 case ACPI_DMAR_TYPE_ATSR:
492#ifdef CONFIG_DMAR
493 ret = dmar_parse_one_atsr(entry_header); 363 ret = dmar_parse_one_atsr(entry_header);
494#endif
495 break; 364 break;
496 case ACPI_DMAR_HARDWARE_AFFINITY: 365 case ACPI_DMAR_HARDWARE_AFFINITY:
497#ifdef CONFIG_ACPI_NUMA 366#ifdef CONFIG_ACPI_NUMA
@@ -557,34 +426,31 @@ dmar_find_matched_drhd_unit(struct pci_dev *dev)
557 426
558int __init dmar_dev_scope_init(void) 427int __init dmar_dev_scope_init(void)
559{ 428{
429 static int dmar_dev_scope_initialized;
560 struct dmar_drhd_unit *drhd, *drhd_n; 430 struct dmar_drhd_unit *drhd, *drhd_n;
561 int ret = -ENODEV; 431 int ret = -ENODEV;
562 432
433 if (dmar_dev_scope_initialized)
434 return dmar_dev_scope_initialized;
435
436 if (list_empty(&dmar_drhd_units))
437 goto fail;
438
563 list_for_each_entry_safe(drhd, drhd_n, &dmar_drhd_units, list) { 439 list_for_each_entry_safe(drhd, drhd_n, &dmar_drhd_units, list) {
564 ret = dmar_parse_dev(drhd); 440 ret = dmar_parse_dev(drhd);
565 if (ret) 441 if (ret)
566 return ret; 442 goto fail;
567 } 443 }
568 444
569#ifdef CONFIG_DMAR 445 ret = dmar_parse_rmrr_atsr_dev();
570 { 446 if (ret)
571 struct dmar_rmrr_unit *rmrr, *rmrr_n; 447 goto fail;
572 struct dmar_atsr_unit *atsr, *atsr_n;
573
574 list_for_each_entry_safe(rmrr, rmrr_n, &dmar_rmrr_units, list) {
575 ret = rmrr_parse_dev(rmrr);
576 if (ret)
577 return ret;
578 }
579 448
580 list_for_each_entry_safe(atsr, atsr_n, &dmar_atsr_units, list) { 449 dmar_dev_scope_initialized = 1;
581 ret = atsr_parse_dev(atsr); 450 return 0;
582 if (ret)
583 return ret;
584 }
585 }
586#endif
587 451
452fail:
453 dmar_dev_scope_initialized = ret;
588 return ret; 454 return ret;
589} 455}
590 456
@@ -611,14 +477,6 @@ int __init dmar_table_init(void)
611 return -ENODEV; 477 return -ENODEV;
612 } 478 }
613 479
614#ifdef CONFIG_DMAR
615 if (list_empty(&dmar_rmrr_units))
616 printk(KERN_INFO PREFIX "No RMRR found\n");
617
618 if (list_empty(&dmar_atsr_units))
619 printk(KERN_INFO PREFIX "No ATSR found\n");
620#endif
621
622 return 0; 480 return 0;
623} 481}
624 482
@@ -682,9 +540,6 @@ int __init check_zero_address(void)
682 return 1; 540 return 1;
683 541
684failed: 542failed:
685#ifdef CONFIG_DMAR
686 dmar_disabled = 1;
687#endif
688 return 0; 543 return 0;
689} 544}
690 545
@@ -696,22 +551,21 @@ int __init detect_intel_iommu(void)
696 if (ret) 551 if (ret)
697 ret = check_zero_address(); 552 ret = check_zero_address();
698 { 553 {
699#ifdef CONFIG_INTR_REMAP
700 struct acpi_table_dmar *dmar; 554 struct acpi_table_dmar *dmar;
701 555
702 dmar = (struct acpi_table_dmar *) dmar_tbl; 556 dmar = (struct acpi_table_dmar *) dmar_tbl;
703 if (ret && cpu_has_x2apic && dmar->flags & 0x1) 557
558 if (ret && intr_remapping_enabled && cpu_has_x2apic &&
559 dmar->flags & 0x1)
704 printk(KERN_INFO 560 printk(KERN_INFO
705 "Queued invalidation will be enabled to support " 561 "Queued invalidation will be enabled to support x2apic and Intr-remapping.\n");
706 "x2apic and Intr-remapping.\n"); 562
707#endif
708#ifdef CONFIG_DMAR
709 if (ret && !no_iommu && !iommu_detected && !dmar_disabled) { 563 if (ret && !no_iommu && !iommu_detected && !dmar_disabled) {
710 iommu_detected = 1; 564 iommu_detected = 1;
711 /* Make sure ACS will be enabled */ 565 /* Make sure ACS will be enabled */
712 pci_request_acs(); 566 pci_request_acs();
713 } 567 }
714#endif 568
715#ifdef CONFIG_X86 569#ifdef CONFIG_X86
716 if (ret) 570 if (ret)
717 x86_init.iommu.iommu_init = intel_iommu_init; 571 x86_init.iommu.iommu_init = intel_iommu_init;
@@ -758,7 +612,6 @@ int alloc_iommu(struct dmar_drhd_unit *drhd)
758 goto err_unmap; 612 goto err_unmap;
759 } 613 }
760 614
761#ifdef CONFIG_DMAR
762 agaw = iommu_calculate_agaw(iommu); 615 agaw = iommu_calculate_agaw(iommu);
763 if (agaw < 0) { 616 if (agaw < 0) {
764 printk(KERN_ERR 617 printk(KERN_ERR
@@ -773,7 +626,6 @@ int alloc_iommu(struct dmar_drhd_unit *drhd)
773 iommu->seq_id); 626 iommu->seq_id);
774 goto err_unmap; 627 goto err_unmap;
775 } 628 }
776#endif
777 iommu->agaw = agaw; 629 iommu->agaw = agaw;
778 iommu->msagaw = msagaw; 630 iommu->msagaw = msagaw;
779 631
@@ -817,9 +669,7 @@ void free_iommu(struct intel_iommu *iommu)
817 if (!iommu) 669 if (!iommu)
818 return; 670 return;
819 671
820#ifdef CONFIG_DMAR
821 free_dmar_iommu(iommu); 672 free_dmar_iommu(iommu);
822#endif
823 673
824 if (iommu->reg) 674 if (iommu->reg)
825 iounmap(iommu->reg); 675 iounmap(iommu->reg);
diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index a88f3cbb100b..f28d933c7927 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -398,11 +398,11 @@ static long list_size;
398 398
399static void domain_remove_dev_info(struct dmar_domain *domain); 399static void domain_remove_dev_info(struct dmar_domain *domain);
400 400
401#ifdef CONFIG_DMAR_DEFAULT_ON 401#ifdef CONFIG_INTEL_IOMMU_DEFAULT_ON
402int dmar_disabled = 0; 402int dmar_disabled = 0;
403#else 403#else
404int dmar_disabled = 1; 404int dmar_disabled = 1;
405#endif /*CONFIG_DMAR_DEFAULT_ON*/ 405#endif /*CONFIG_INTEL_IOMMU_DEFAULT_ON*/
406 406
407static int dmar_map_gfx = 1; 407static int dmar_map_gfx = 1;
408static int dmar_forcedac; 408static int dmar_forcedac;
@@ -2157,7 +2157,7 @@ static inline int iommu_prepare_rmrr_dev(struct dmar_rmrr_unit *rmrr,
2157 rmrr->end_address); 2157 rmrr->end_address);
2158} 2158}
2159 2159
2160#ifdef CONFIG_DMAR_FLOPPY_WA 2160#ifdef CONFIG_INTEL_IOMMU_FLOPPY_WA
2161static inline void iommu_prepare_isa(void) 2161static inline void iommu_prepare_isa(void)
2162{ 2162{
2163 struct pci_dev *pdev; 2163 struct pci_dev *pdev;
@@ -2180,7 +2180,7 @@ static inline void iommu_prepare_isa(void)
2180{ 2180{
2181 return; 2181 return;
2182} 2182}
2183#endif /* !CONFIG_DMAR_FLPY_WA */ 2183#endif /* !CONFIG_INTEL_IOMMU_FLPY_WA */
2184 2184
2185static int md_domain_init(struct dmar_domain *domain, int guest_width); 2185static int md_domain_init(struct dmar_domain *domain, int guest_width);
2186 2186
@@ -2491,7 +2491,7 @@ static int __init init_dmars(void)
2491 if (iommu_pass_through) 2491 if (iommu_pass_through)
2492 iommu_identity_mapping |= IDENTMAP_ALL; 2492 iommu_identity_mapping |= IDENTMAP_ALL;
2493 2493
2494#ifdef CONFIG_DMAR_BROKEN_GFX_WA 2494#ifdef CONFIG_INTEL_IOMMU_BROKEN_GFX_WA
2495 iommu_identity_mapping |= IDENTMAP_GFX; 2495 iommu_identity_mapping |= IDENTMAP_GFX;
2496#endif 2496#endif
2497 2497
@@ -3399,6 +3399,151 @@ static void __init init_iommu_pm_ops(void)
3399static inline void init_iommu_pm_ops(void) {} 3399static inline void init_iommu_pm_ops(void) {}
3400#endif /* CONFIG_PM */ 3400#endif /* CONFIG_PM */
3401 3401
3402LIST_HEAD(dmar_rmrr_units);
3403
3404static void __init dmar_register_rmrr_unit(struct dmar_rmrr_unit *rmrr)
3405{
3406 list_add(&rmrr->list, &dmar_rmrr_units);
3407}
3408
3409
3410int __init dmar_parse_one_rmrr(struct acpi_dmar_header *header)
3411{
3412 struct acpi_dmar_reserved_memory *rmrr;
3413 struct dmar_rmrr_unit *rmrru;
3414
3415 rmrru = kzalloc(sizeof(*rmrru), GFP_KERNEL);
3416 if (!rmrru)
3417 return -ENOMEM;
3418
3419 rmrru->hdr = header;
3420 rmrr = (struct acpi_dmar_reserved_memory *)header;
3421 rmrru->base_address = rmrr->base_address;
3422 rmrru->end_address = rmrr->end_address;
3423
3424 dmar_register_rmrr_unit(rmrru);
3425 return 0;
3426}
3427
3428static int __init
3429rmrr_parse_dev(struct dmar_rmrr_unit *rmrru)
3430{
3431 struct acpi_dmar_reserved_memory *rmrr;
3432 int ret;
3433
3434 rmrr = (struct acpi_dmar_reserved_memory *) rmrru->hdr;
3435 ret = dmar_parse_dev_scope((void *)(rmrr + 1),
3436 ((void *)rmrr) + rmrr->header.length,
3437 &rmrru->devices_cnt, &rmrru->devices, rmrr->segment);
3438
3439 if (ret || (rmrru->devices_cnt == 0)) {
3440 list_del(&rmrru->list);
3441 kfree(rmrru);
3442 }
3443 return ret;
3444}
3445
3446static LIST_HEAD(dmar_atsr_units);
3447
3448int __init dmar_parse_one_atsr(struct acpi_dmar_header *hdr)
3449{
3450 struct acpi_dmar_atsr *atsr;
3451 struct dmar_atsr_unit *atsru;
3452
3453 atsr = container_of(hdr, struct acpi_dmar_atsr, header);
3454 atsru = kzalloc(sizeof(*atsru), GFP_KERNEL);
3455 if (!atsru)
3456 return -ENOMEM;
3457
3458 atsru->hdr = hdr;
3459 atsru->include_all = atsr->flags & 0x1;
3460
3461 list_add(&atsru->list, &dmar_atsr_units);
3462
3463 return 0;
3464}
3465
3466static int __init atsr_parse_dev(struct dmar_atsr_unit *atsru)
3467{
3468 int rc;
3469 struct acpi_dmar_atsr *atsr;
3470
3471 if (atsru->include_all)
3472 return 0;
3473
3474 atsr = container_of(atsru->hdr, struct acpi_dmar_atsr, header);
3475 rc = dmar_parse_dev_scope((void *)(atsr + 1),
3476 (void *)atsr + atsr->header.length,
3477 &atsru->devices_cnt, &atsru->devices,
3478 atsr->segment);
3479 if (rc || !atsru->devices_cnt) {
3480 list_del(&atsru->list);
3481 kfree(atsru);
3482 }
3483
3484 return rc;
3485}
3486
3487int dmar_find_matched_atsr_unit(struct pci_dev *dev)
3488{
3489 int i;
3490 struct pci_bus *bus;
3491 struct acpi_dmar_atsr *atsr;
3492 struct dmar_atsr_unit *atsru;
3493
3494 dev = pci_physfn(dev);
3495
3496 list_for_each_entry(atsru, &dmar_atsr_units, list) {
3497 atsr = container_of(atsru->hdr, struct acpi_dmar_atsr, header);
3498 if (atsr->segment == pci_domain_nr(dev->bus))
3499 goto found;
3500 }
3501
3502 return 0;
3503
3504found:
3505 for (bus = dev->bus; bus; bus = bus->parent) {
3506 struct pci_dev *bridge = bus->self;
3507
3508 if (!bridge || !pci_is_pcie(bridge) ||
3509 bridge->pcie_type == PCI_EXP_TYPE_PCI_BRIDGE)
3510 return 0;
3511
3512 if (bridge->pcie_type == PCI_EXP_TYPE_ROOT_PORT) {
3513 for (i = 0; i < atsru->devices_cnt; i++)
3514 if (atsru->devices[i] == bridge)
3515 return 1;
3516 break;
3517 }
3518 }
3519
3520 if (atsru->include_all)
3521 return 1;
3522
3523 return 0;
3524}
3525
3526int dmar_parse_rmrr_atsr_dev(void)
3527{
3528 struct dmar_rmrr_unit *rmrr, *rmrr_n;
3529 struct dmar_atsr_unit *atsr, *atsr_n;
3530 int ret = 0;
3531
3532 list_for_each_entry_safe(rmrr, rmrr_n, &dmar_rmrr_units, list) {
3533 ret = rmrr_parse_dev(rmrr);
3534 if (ret)
3535 return ret;
3536 }
3537
3538 list_for_each_entry_safe(atsr, atsr_n, &dmar_atsr_units, list) {
3539 ret = atsr_parse_dev(atsr);
3540 if (ret)
3541 return ret;
3542 }
3543
3544 return ret;
3545}
3546
3402/* 3547/*
3403 * Here we only respond to action of unbound device from driver. 3548 * Here we only respond to action of unbound device from driver.
3404 * 3549 *
@@ -3448,16 +3593,12 @@ int __init intel_iommu_init(void)
3448 return -ENODEV; 3593 return -ENODEV;
3449 } 3594 }
3450 3595
3451 if (dmar_dev_scope_init()) { 3596 if (dmar_dev_scope_init() < 0) {
3452 if (force_on) 3597 if (force_on)
3453 panic("tboot: Failed to initialize DMAR device scope\n"); 3598 panic("tboot: Failed to initialize DMAR device scope\n");
3454 return -ENODEV; 3599 return -ENODEV;
3455 } 3600 }
3456 3601
3457 /*
3458 * Check the need for DMA-remapping initialization now.
3459 * Above initialization will also be used by Interrupt-remapping.
3460 */
3461 if (no_iommu || dmar_disabled) 3602 if (no_iommu || dmar_disabled)
3462 return -ENODEV; 3603 return -ENODEV;
3463 3604
@@ -3467,6 +3608,12 @@ int __init intel_iommu_init(void)
3467 return -ENODEV; 3608 return -ENODEV;
3468 } 3609 }
3469 3610
3611 if (list_empty(&dmar_rmrr_units))
3612 printk(KERN_INFO "DMAR: No RMRR found\n");
3613
3614 if (list_empty(&dmar_atsr_units))
3615 printk(KERN_INFO "DMAR: No ATSR found\n");
3616
3470 if (dmar_init_reserved_ranges()) { 3617 if (dmar_init_reserved_ranges()) {
3471 if (force_on) 3618 if (force_on)
3472 panic("tboot: Failed to reserve iommu ranges\n"); 3619 panic("tboot: Failed to reserve iommu ranges\n");
diff --git a/drivers/iommu/intr_remapping.c b/drivers/iommu/intr_remapping.c
index 1a89d4a2cadf..cfb0dd4bf0b6 100644
--- a/drivers/iommu/intr_remapping.c
+++ b/drivers/iommu/intr_remapping.c
@@ -21,6 +21,7 @@ int intr_remapping_enabled;
21 21
22static int disable_intremap; 22static int disable_intremap;
23static int disable_sourceid_checking; 23static int disable_sourceid_checking;
24static int no_x2apic_optout;
24 25
25static __init int setup_nointremap(char *str) 26static __init int setup_nointremap(char *str)
26{ 27{
@@ -34,12 +35,20 @@ static __init int setup_intremap(char *str)
34 if (!str) 35 if (!str)
35 return -EINVAL; 36 return -EINVAL;
36 37
37 if (!strncmp(str, "on", 2)) 38 while (*str) {
38 disable_intremap = 0; 39 if (!strncmp(str, "on", 2))
39 else if (!strncmp(str, "off", 3)) 40 disable_intremap = 0;
40 disable_intremap = 1; 41 else if (!strncmp(str, "off", 3))
41 else if (!strncmp(str, "nosid", 5)) 42 disable_intremap = 1;
42 disable_sourceid_checking = 1; 43 else if (!strncmp(str, "nosid", 5))
44 disable_sourceid_checking = 1;
45 else if (!strncmp(str, "no_x2apic_optout", 16))
46 no_x2apic_optout = 1;
47
48 str += strcspn(str, ",");
49 while (*str == ',')
50 str++;
51 }
43 52
44 return 0; 53 return 0;
45} 54}
@@ -501,6 +510,15 @@ end:
501 spin_unlock_irqrestore(&iommu->register_lock, flags); 510 spin_unlock_irqrestore(&iommu->register_lock, flags);
502} 511}
503 512
513static int __init dmar_x2apic_optout(void)
514{
515 struct acpi_table_dmar *dmar;
516 dmar = (struct acpi_table_dmar *)dmar_tbl;
517 if (!dmar || no_x2apic_optout)
518 return 0;
519 return dmar->flags & DMAR_X2APIC_OPT_OUT;
520}
521
504int __init intr_remapping_supported(void) 522int __init intr_remapping_supported(void)
505{ 523{
506 struct dmar_drhd_unit *drhd; 524 struct dmar_drhd_unit *drhd;
@@ -521,16 +539,25 @@ int __init intr_remapping_supported(void)
521 return 1; 539 return 1;
522} 540}
523 541
524int __init enable_intr_remapping(int eim) 542int __init enable_intr_remapping(void)
525{ 543{
526 struct dmar_drhd_unit *drhd; 544 struct dmar_drhd_unit *drhd;
527 int setup = 0; 545 int setup = 0;
546 int eim = 0;
528 547
529 if (parse_ioapics_under_ir() != 1) { 548 if (parse_ioapics_under_ir() != 1) {
530 printk(KERN_INFO "Not enable interrupt remapping\n"); 549 printk(KERN_INFO "Not enable interrupt remapping\n");
531 return -1; 550 return -1;
532 } 551 }
533 552
553 if (x2apic_supported()) {
554 eim = !dmar_x2apic_optout();
555 WARN(!eim, KERN_WARNING
556 "Your BIOS is broken and requested that x2apic be disabled\n"
557 "This will leave your machine vulnerable to irq-injection attacks\n"
558 "Use 'intremap=no_x2apic_optout' to override BIOS request\n");
559 }
560
534 for_each_drhd_unit(drhd) { 561 for_each_drhd_unit(drhd) {
535 struct intel_iommu *iommu = drhd->iommu; 562 struct intel_iommu *iommu = drhd->iommu;
536 563
@@ -606,8 +633,9 @@ int __init enable_intr_remapping(int eim)
606 goto error; 633 goto error;
607 634
608 intr_remapping_enabled = 1; 635 intr_remapping_enabled = 1;
636 pr_info("Enabled IRQ remapping in %s mode\n", eim ? "x2apic" : "xapic");
609 637
610 return 0; 638 return eim ? IRQ_REMAP_X2APIC_MODE : IRQ_REMAP_XAPIC_MODE;
611 639
612error: 640error:
613 /* 641 /*
@@ -745,6 +773,15 @@ int __init parse_ioapics_under_ir(void)
745 return ir_supported; 773 return ir_supported;
746} 774}
747 775
776int ir_dev_scope_init(void)
777{
778 if (!intr_remapping_enabled)
779 return 0;
780
781 return dmar_dev_scope_init();
782}
783rootfs_initcall(ir_dev_scope_init);
784
748void disable_intr_remapping(void) 785void disable_intr_remapping(void)
749{ 786{
750 struct dmar_drhd_unit *drhd; 787 struct dmar_drhd_unit *drhd;