diff options
author | Jiang Liu <jiang.liu@linux.intel.com> | 2014-07-11 02:19:37 -0400 |
---|---|---|
committer | Joerg Roedel <jroedel@suse.de> | 2014-07-23 10:04:47 -0400 |
commit | 161f693460772ef269ab35cbd145b6431e935eac (patch) | |
tree | 47ed588294459adf8521a6af63129a5130bf737b /drivers/iommu/intel-iommu.c | |
parent | a156ef99e874f3701367cc192aa604bcf8c0a236 (diff) |
iommu/vt-d: Fix issue in computing domain's iommu_snooping flag
IOMMU units may dynamically attached to/detached from domains,
so we should scan all active IOMMU units when computing iommu_snooping
flag for a domain instead of only scanning IOMMU units associated
with the domain.
Also check snooping and superpage capabilities when hot-adding DMAR units.
Signed-off-by: Jiang Liu <jiang.liu@linux.intel.com>
Signed-off-by: Joerg Roedel <jroedel@suse.de>
Diffstat (limited to 'drivers/iommu/intel-iommu.c')
-rw-r--r-- | drivers/iommu/intel-iommu.c | 42 |
1 files changed, 24 insertions, 18 deletions
diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c index cd1ba24c766a..58cc2b75d7ae 100644 --- a/drivers/iommu/intel-iommu.c +++ b/drivers/iommu/intel-iommu.c | |||
@@ -633,50 +633,56 @@ static void domain_update_iommu_coherency(struct dmar_domain *domain) | |||
633 | rcu_read_unlock(); | 633 | rcu_read_unlock(); |
634 | } | 634 | } |
635 | 635 | ||
636 | static void domain_update_iommu_snooping(struct dmar_domain *domain) | 636 | static int domain_update_iommu_snooping(struct intel_iommu *skip) |
637 | { | 637 | { |
638 | int i; | 638 | struct dmar_drhd_unit *drhd; |
639 | 639 | struct intel_iommu *iommu; | |
640 | domain->iommu_snooping = 1; | 640 | int ret = 1; |
641 | 641 | ||
642 | for_each_set_bit(i, domain->iommu_bmp, g_num_of_iommus) { | 642 | rcu_read_lock(); |
643 | if (!ecap_sc_support(g_iommus[i]->ecap)) { | 643 | for_each_active_iommu(iommu, drhd) { |
644 | domain->iommu_snooping = 0; | 644 | if (iommu != skip) { |
645 | break; | 645 | if (!ecap_sc_support(iommu->ecap)) { |
646 | ret = 0; | ||
647 | break; | ||
648 | } | ||
646 | } | 649 | } |
647 | } | 650 | } |
651 | rcu_read_unlock(); | ||
652 | |||
653 | return ret; | ||
648 | } | 654 | } |
649 | 655 | ||
650 | static void domain_update_iommu_superpage(struct dmar_domain *domain) | 656 | static int domain_update_iommu_superpage(struct intel_iommu *skip) |
651 | { | 657 | { |
652 | struct dmar_drhd_unit *drhd; | 658 | struct dmar_drhd_unit *drhd; |
653 | struct intel_iommu *iommu = NULL; | 659 | struct intel_iommu *iommu; |
654 | int mask = 0xf; | 660 | int mask = 0xf; |
655 | 661 | ||
656 | if (!intel_iommu_superpage) { | 662 | if (!intel_iommu_superpage) { |
657 | domain->iommu_superpage = 0; | 663 | return 0; |
658 | return; | ||
659 | } | 664 | } |
660 | 665 | ||
661 | /* set iommu_superpage to the smallest common denominator */ | 666 | /* set iommu_superpage to the smallest common denominator */ |
662 | rcu_read_lock(); | 667 | rcu_read_lock(); |
663 | for_each_active_iommu(iommu, drhd) { | 668 | for_each_active_iommu(iommu, drhd) { |
664 | mask &= cap_super_page_val(iommu->cap); | 669 | if (iommu != skip) { |
665 | if (!mask) { | 670 | mask &= cap_super_page_val(iommu->cap); |
666 | break; | 671 | if (!mask) |
672 | break; | ||
667 | } | 673 | } |
668 | } | 674 | } |
669 | rcu_read_unlock(); | 675 | rcu_read_unlock(); |
670 | 676 | ||
671 | domain->iommu_superpage = fls(mask); | 677 | return fls(mask); |
672 | } | 678 | } |
673 | 679 | ||
674 | /* Some capabilities may be different across iommus */ | 680 | /* Some capabilities may be different across iommus */ |
675 | static void domain_update_iommu_cap(struct dmar_domain *domain) | 681 | static void domain_update_iommu_cap(struct dmar_domain *domain) |
676 | { | 682 | { |
677 | domain_update_iommu_coherency(domain); | 683 | domain_update_iommu_coherency(domain); |
678 | domain_update_iommu_snooping(domain); | 684 | domain->iommu_snooping = domain_update_iommu_snooping(NULL); |
679 | domain_update_iommu_superpage(domain); | 685 | domain->iommu_superpage = domain_update_iommu_superpage(NULL); |
680 | } | 686 | } |
681 | 687 | ||
682 | static struct intel_iommu *device_to_iommu(struct device *dev, u8 *bus, u8 *devfn) | 688 | static struct intel_iommu *device_to_iommu(struct device *dev, u8 *bus, u8 *devfn) |