aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/iommu/intel-iommu.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/intel-iommu.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/intel-iommu.c')
-rw-r--r--drivers/iommu/intel-iommu.c151
1 files changed, 151 insertions, 0 deletions
diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index df69618177c5..e8eb4c5302b0 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -3390,6 +3390,151 @@ static void __init init_iommu_pm_ops(void)
3390static inline void init_iommu_pm_ops(void) {} 3390static inline void init_iommu_pm_ops(void) {}
3391#endif /* CONFIG_PM */ 3391#endif /* CONFIG_PM */
3392 3392
3393LIST_HEAD(dmar_rmrr_units);
3394
3395static void __init dmar_register_rmrr_unit(struct dmar_rmrr_unit *rmrr)
3396{
3397 list_add(&rmrr->list, &dmar_rmrr_units);
3398}
3399
3400
3401int __init dmar_parse_one_rmrr(struct acpi_dmar_header *header)
3402{
3403 struct acpi_dmar_reserved_memory *rmrr;
3404 struct dmar_rmrr_unit *rmrru;
3405
3406 rmrru = kzalloc(sizeof(*rmrru), GFP_KERNEL);
3407 if (!rmrru)
3408 return -ENOMEM;
3409
3410 rmrru->hdr = header;
3411 rmrr = (struct acpi_dmar_reserved_memory *)header;
3412 rmrru->base_address = rmrr->base_address;
3413 rmrru->end_address = rmrr->end_address;
3414
3415 dmar_register_rmrr_unit(rmrru);
3416 return 0;
3417}
3418
3419static int __init
3420rmrr_parse_dev(struct dmar_rmrr_unit *rmrru)
3421{
3422 struct acpi_dmar_reserved_memory *rmrr;
3423 int ret;
3424
3425 rmrr = (struct acpi_dmar_reserved_memory *) rmrru->hdr;
3426 ret = dmar_parse_dev_scope((void *)(rmrr + 1),
3427 ((void *)rmrr) + rmrr->header.length,
3428 &rmrru->devices_cnt, &rmrru->devices, rmrr->segment);
3429
3430 if (ret || (rmrru->devices_cnt == 0)) {
3431 list_del(&rmrru->list);
3432 kfree(rmrru);
3433 }
3434 return ret;
3435}
3436
3437static LIST_HEAD(dmar_atsr_units);
3438
3439int __init dmar_parse_one_atsr(struct acpi_dmar_header *hdr)
3440{
3441 struct acpi_dmar_atsr *atsr;
3442 struct dmar_atsr_unit *atsru;
3443
3444 atsr = container_of(hdr, struct acpi_dmar_atsr, header);
3445 atsru = kzalloc(sizeof(*atsru), GFP_KERNEL);
3446 if (!atsru)
3447 return -ENOMEM;
3448
3449 atsru->hdr = hdr;
3450 atsru->include_all = atsr->flags & 0x1;
3451
3452 list_add(&atsru->list, &dmar_atsr_units);
3453
3454 return 0;
3455}
3456
3457static int __init atsr_parse_dev(struct dmar_atsr_unit *atsru)
3458{
3459 int rc;
3460 struct acpi_dmar_atsr *atsr;
3461
3462 if (atsru->include_all)
3463 return 0;
3464
3465 atsr = container_of(atsru->hdr, struct acpi_dmar_atsr, header);
3466 rc = dmar_parse_dev_scope((void *)(atsr + 1),
3467 (void *)atsr + atsr->header.length,
3468 &atsru->devices_cnt, &atsru->devices,
3469 atsr->segment);
3470 if (rc || !atsru->devices_cnt) {
3471 list_del(&atsru->list);
3472 kfree(atsru);
3473 }
3474
3475 return rc;
3476}
3477
3478int dmar_find_matched_atsr_unit(struct pci_dev *dev)
3479{
3480 int i;
3481 struct pci_bus *bus;
3482 struct acpi_dmar_atsr *atsr;
3483 struct dmar_atsr_unit *atsru;
3484
3485 dev = pci_physfn(dev);
3486
3487 list_for_each_entry(atsru, &dmar_atsr_units, list) {
3488 atsr = container_of(atsru->hdr, struct acpi_dmar_atsr, header);
3489 if (atsr->segment == pci_domain_nr(dev->bus))
3490 goto found;
3491 }
3492
3493 return 0;
3494
3495found:
3496 for (bus = dev->bus; bus; bus = bus->parent) {
3497 struct pci_dev *bridge = bus->self;
3498
3499 if (!bridge || !pci_is_pcie(bridge) ||
3500 bridge->pcie_type == PCI_EXP_TYPE_PCI_BRIDGE)
3501 return 0;
3502
3503 if (bridge->pcie_type == PCI_EXP_TYPE_ROOT_PORT) {
3504 for (i = 0; i < atsru->devices_cnt; i++)
3505 if (atsru->devices[i] == bridge)
3506 return 1;
3507 break;
3508 }
3509 }
3510
3511 if (atsru->include_all)
3512 return 1;
3513
3514 return 0;
3515}
3516
3517int dmar_parse_rmrr_atsr_dev(void)
3518{
3519 struct dmar_rmrr_unit *rmrr, *rmrr_n;
3520 struct dmar_atsr_unit *atsr, *atsr_n;
3521 int ret = 0;
3522
3523 list_for_each_entry_safe(rmrr, rmrr_n, &dmar_rmrr_units, list) {
3524 ret = rmrr_parse_dev(rmrr);
3525 if (ret)
3526 return ret;
3527 }
3528
3529 list_for_each_entry_safe(atsr, atsr_n, &dmar_atsr_units, list) {
3530 ret = atsr_parse_dev(atsr);
3531 if (ret)
3532 return ret;
3533 }
3534
3535 return ret;
3536}
3537
3393/* 3538/*
3394 * Here we only respond to action of unbound device from driver. 3539 * Here we only respond to action of unbound device from driver.
3395 * 3540 *
@@ -3454,6 +3599,12 @@ int __init intel_iommu_init(void)
3454 return -ENODEV; 3599 return -ENODEV;
3455 } 3600 }
3456 3601
3602 if (list_empty(&dmar_rmrr_units))
3603 printk(KERN_INFO "DMAR: No RMRR found\n");
3604
3605 if (list_empty(&dmar_atsr_units))
3606 printk(KERN_INFO "DMAR: No ATSR found\n");
3607
3457 if (dmar_init_reserved_ranges()) { 3608 if (dmar_init_reserved_ranges()) {
3458 if (force_on) 3609 if (force_on)
3459 panic("tboot: Failed to reserve iommu ranges\n"); 3610 panic("tboot: Failed to reserve iommu ranges\n");