aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/iommu/dmar.c
diff options
context:
space:
mode:
authorSuresh Siddha <suresh.b.siddha@intel.com>2011-08-23 20:05:20 -0400
committerIngo Molnar <mingo@elte.hu>2011-09-21 04:21:54 -0400
commit318fe7df9d8456f778451b01913b5d0dc0a25854 (patch)
treeb134ae443ed05996f98660469590034ff19f76b5 /drivers/iommu/dmar.c
parentc2c7286ac6d996a8ffc8d391d782ba35570b1236 (diff)
iommu: Move IOMMU specific code to intel-iommu.c
Move the IOMMU specific routines to intel-iommu.c leaving the dmar.c to the common ACPI dmar code shared between DMA-remapping and Interrupt-remapping. Signed-off-by: Suresh Siddha <suresh.b.siddha@intel.com> Cc: yinghai@kernel.org Cc: youquan.song@intel.com Cc: joerg.roedel@amd.com Cc: tony.luck@intel.com Cc: dwmw2@infradead.org Link: http://lkml.kernel.org/r/20110824001456.282401285@sbsiddha-desk.sc.intel.com Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'drivers/iommu/dmar.c')
-rw-r--r--drivers/iommu/dmar.c171
1 files changed, 8 insertions, 163 deletions
diff --git a/drivers/iommu/dmar.c b/drivers/iommu/dmar.c
index 17adf1ebcb13..a10ccf2432c8 100644
--- a/drivers/iommu/dmar.c
+++ b/drivers/iommu/dmar.c
@@ -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
@@ -564,30 +433,18 @@ int __init dmar_dev_scope_init(void)
564 if (dmar_dev_scope_initialized) 433 if (dmar_dev_scope_initialized)
565 return dmar_dev_scope_initialized; 434 return dmar_dev_scope_initialized;
566 435
436 if (list_empty(&dmar_drhd_units))
437 goto fail;
438
567 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) {
568 ret = dmar_parse_dev(drhd); 440 ret = dmar_parse_dev(drhd);
569 if (ret) 441 if (ret)
570 goto fail; 442 goto fail;
571 } 443 }
572 444
573#ifdef CONFIG_DMAR 445 ret = dmar_parse_rmrr_atsr_dev();
574 { 446 if (ret)
575 struct dmar_rmrr_unit *rmrr, *rmrr_n; 447 goto fail;
576 struct dmar_atsr_unit *atsr, *atsr_n;
577
578 list_for_each_entry_safe(rmrr, rmrr_n, &dmar_rmrr_units, list) {
579 ret = rmrr_parse_dev(rmrr);
580 if (ret)
581 goto fail;
582 }
583
584 list_for_each_entry_safe(atsr, atsr_n, &dmar_atsr_units, list) {
585 ret = atsr_parse_dev(atsr);
586 if (ret)
587 goto fail;
588 }
589 }
590#endif
591 448
592 dmar_dev_scope_initialized = 1; 449 dmar_dev_scope_initialized = 1;
593 return 0; 450 return 0;
@@ -620,14 +477,6 @@ int __init dmar_table_init(void)
620 return -ENODEV; 477 return -ENODEV;
621 } 478 }
622 479
623#ifdef CONFIG_DMAR
624 if (list_empty(&dmar_rmrr_units))
625 printk(KERN_INFO PREFIX "No RMRR found\n");
626
627 if (list_empty(&dmar_atsr_units))
628 printk(KERN_INFO PREFIX "No ATSR found\n");
629#endif
630
631 return 0; 480 return 0;
632} 481}
633 482
@@ -767,7 +616,6 @@ int alloc_iommu(struct dmar_drhd_unit *drhd)
767 goto err_unmap; 616 goto err_unmap;
768 } 617 }
769 618
770#ifdef CONFIG_DMAR
771 agaw = iommu_calculate_agaw(iommu); 619 agaw = iommu_calculate_agaw(iommu);
772 if (agaw < 0) { 620 if (agaw < 0) {
773 printk(KERN_ERR 621 printk(KERN_ERR
@@ -782,7 +630,6 @@ int alloc_iommu(struct dmar_drhd_unit *drhd)
782 iommu->seq_id); 630 iommu->seq_id);
783 goto err_unmap; 631 goto err_unmap;
784 } 632 }
785#endif
786 iommu->agaw = agaw; 633 iommu->agaw = agaw;
787 iommu->msagaw = msagaw; 634 iommu->msagaw = msagaw;
788 635
@@ -826,9 +673,7 @@ void free_iommu(struct intel_iommu *iommu)
826 if (!iommu) 673 if (!iommu)
827 return; 674 return;
828 675
829#ifdef CONFIG_DMAR
830 free_dmar_iommu(iommu); 676 free_dmar_iommu(iommu);
831#endif
832 677
833 if (iommu->reg) 678 if (iommu->reg)
834 iounmap(iommu->reg); 679 iounmap(iommu->reg);