aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/iommu/intel-iommu.c
diff options
context:
space:
mode:
authorJiang Liu <jiang.liu@linux.intel.com>2014-02-19 01:07:36 -0500
committerJoerg Roedel <joro@8bytes.org>2014-03-04 11:51:06 -0500
commit2e45528930388658603ea24d49cf52867b928d3e (patch)
tree751171aa8f2f9a00f080adb6201cf9d9acd02f94 /drivers/iommu/intel-iommu.c
parent59ce0515cdaf3b7d47893d12f61e51d691863788 (diff)
iommu/vt-d: Unify the way to process DMAR device scope array
Now we have a PCI bus notification based mechanism to update DMAR device scope array, we could extend the mechanism to support boot time initialization too, which will help to unify and simplify the implementation. Signed-off-by: Jiang Liu <jiang.liu@linux.intel.com> Signed-off-by: Joerg Roedel <joro@8bytes.org>
Diffstat (limited to 'drivers/iommu/intel-iommu.c')
-rw-r--r--drivers/iommu/intel-iommu.c71
1 files changed, 18 insertions, 53 deletions
diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index d9c0dc5a5d35..dd576c067d0d 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -3473,11 +3473,6 @@ static void __init init_iommu_pm_ops(void)
3473static inline void init_iommu_pm_ops(void) {} 3473static inline void init_iommu_pm_ops(void) {}
3474#endif /* CONFIG_PM */ 3474#endif /* CONFIG_PM */
3475 3475
3476static void __init dmar_register_rmrr_unit(struct dmar_rmrr_unit *rmrr)
3477{
3478 list_add(&rmrr->list, &dmar_rmrr_units);
3479}
3480
3481 3476
3482int __init dmar_parse_one_rmrr(struct acpi_dmar_header *header) 3477int __init dmar_parse_one_rmrr(struct acpi_dmar_header *header)
3483{ 3478{
@@ -3492,21 +3487,17 @@ int __init dmar_parse_one_rmrr(struct acpi_dmar_header *header)
3492 rmrr = (struct acpi_dmar_reserved_memory *)header; 3487 rmrr = (struct acpi_dmar_reserved_memory *)header;
3493 rmrru->base_address = rmrr->base_address; 3488 rmrru->base_address = rmrr->base_address;
3494 rmrru->end_address = rmrr->end_address; 3489 rmrru->end_address = rmrr->end_address;
3490 rmrru->devices = dmar_alloc_dev_scope((void *)(rmrr + 1),
3491 ((void *)rmrr) + rmrr->header.length,
3492 &rmrru->devices_cnt);
3493 if (rmrru->devices_cnt && rmrru->devices == NULL) {
3494 kfree(rmrru);
3495 return -ENOMEM;
3496 }
3495 3497
3496 dmar_register_rmrr_unit(rmrru); 3498 list_add(&rmrru->list, &dmar_rmrr_units);
3497 return 0;
3498}
3499 3499
3500static int __init 3500 return 0;
3501rmrr_parse_dev(struct dmar_rmrr_unit *rmrru)
3502{
3503 struct acpi_dmar_reserved_memory *rmrr;
3504
3505 rmrr = (struct acpi_dmar_reserved_memory *) rmrru->hdr;
3506 return dmar_parse_dev_scope((void *)(rmrr + 1),
3507 ((void *)rmrr) + rmrr->header.length,
3508 &rmrru->devices_cnt, &rmrru->devices,
3509 rmrr->segment);
3510} 3501}
3511 3502
3512int __init dmar_parse_one_atsr(struct acpi_dmar_header *hdr) 3503int __init dmar_parse_one_atsr(struct acpi_dmar_header *hdr)
@@ -3521,26 +3512,21 @@ int __init dmar_parse_one_atsr(struct acpi_dmar_header *hdr)
3521 3512
3522 atsru->hdr = hdr; 3513 atsru->hdr = hdr;
3523 atsru->include_all = atsr->flags & 0x1; 3514 atsru->include_all = atsr->flags & 0x1;
3515 if (!atsru->include_all) {
3516 atsru->devices = dmar_alloc_dev_scope((void *)(atsr + 1),
3517 (void *)atsr + atsr->header.length,
3518 &atsru->devices_cnt);
3519 if (atsru->devices_cnt && atsru->devices == NULL) {
3520 kfree(atsru);
3521 return -ENOMEM;
3522 }
3523 }
3524 3524
3525 list_add_rcu(&atsru->list, &dmar_atsr_units); 3525 list_add_rcu(&atsru->list, &dmar_atsr_units);
3526 3526
3527 return 0; 3527 return 0;
3528} 3528}
3529 3529
3530static int __init atsr_parse_dev(struct dmar_atsr_unit *atsru)
3531{
3532 struct acpi_dmar_atsr *atsr;
3533
3534 if (atsru->include_all)
3535 return 0;
3536
3537 atsr = container_of(atsru->hdr, struct acpi_dmar_atsr, header);
3538 return dmar_parse_dev_scope((void *)(atsr + 1),
3539 (void *)atsr + atsr->header.length,
3540 &atsru->devices_cnt, &atsru->devices,
3541 atsr->segment);
3542}
3543
3544static void intel_iommu_free_atsr(struct dmar_atsr_unit *atsru) 3530static void intel_iommu_free_atsr(struct dmar_atsr_unit *atsru)
3545{ 3531{
3546 dmar_free_dev_scope(&atsru->devices, &atsru->devices_cnt); 3532 dmar_free_dev_scope(&atsru->devices, &atsru->devices_cnt);
@@ -3604,27 +3590,6 @@ out:
3604 return ret; 3590 return ret;
3605} 3591}
3606 3592
3607int __init dmar_parse_rmrr_atsr_dev(void)
3608{
3609 struct dmar_rmrr_unit *rmrr;
3610 struct dmar_atsr_unit *atsr;
3611 int ret;
3612
3613 list_for_each_entry(rmrr, &dmar_rmrr_units, list) {
3614 ret = rmrr_parse_dev(rmrr);
3615 if (ret)
3616 return ret;
3617 }
3618
3619 list_for_each_entry_rcu(atsr, &dmar_atsr_units, list) {
3620 ret = atsr_parse_dev(atsr);
3621 if (ret)
3622 return ret;
3623 }
3624
3625 return 0;
3626}
3627
3628int dmar_iommu_notify_scope_dev(struct dmar_pci_notify_info *info) 3593int dmar_iommu_notify_scope_dev(struct dmar_pci_notify_info *info)
3629{ 3594{
3630 int ret = 0; 3595 int ret = 0;