aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-07-01 17:44:22 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2015-07-01 17:44:22 -0400
commit44b061f77f70e21031444e3611dfddbb80b4defc (patch)
tree9bb5bb46f8015c856fdf2957a9d0d260f0f19e15
parentf822dcc63f966fc79b11a8254fa0942b1aa8c71e (diff)
parent7a5a566eab48da7522f601f96aef3af102178046 (diff)
Merge tag 'iommu-fixes-v4.2' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu
Pul IOMMU fixes from Joerg Roedel: "Four fixes have queued up to fix regressions introduced after v4.1: - Don't fail IOMMU driver initialization when the add_device call-back returns -ENODEV, as that just means that the device is not translated by the IOMMU. This is pretty common on ARM. - Two fixes for the ARM-SMMU driver for a wrong feature check and to remove a redundant NULL check. - A fix for the AMD IOMMU driver to fix a boot panic on systems where the BIOS requests Unity Mappings in the IVRS table" * tag 'iommu-fixes-v4.2' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu: iommu/amd: Introduce protection_domain_init() function iommu/arm-smmu: Delete an unnecessary check before the function call "free_io_pgtable_ops" iommu/arm-smmu: Fix broken ATOS check iommu: Ignore -ENODEV errors from add_device call-back
-rw-r--r--drivers/iommu/amd_iommu.c26
-rw-r--r--drivers/iommu/arm-smmu-v3.c3
-rw-r--r--drivers/iommu/arm-smmu.c2
-rw-r--r--drivers/iommu/iommu.c13
4 files changed, 30 insertions, 14 deletions
diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c
index d3e5e9abe3b6..a57e9b749895 100644
--- a/drivers/iommu/amd_iommu.c
+++ b/drivers/iommu/amd_iommu.c
@@ -117,6 +117,7 @@ struct kmem_cache *amd_iommu_irq_cache;
117 117
118static void update_domain(struct protection_domain *domain); 118static void update_domain(struct protection_domain *domain);
119static int alloc_passthrough_domain(void); 119static int alloc_passthrough_domain(void);
120static int protection_domain_init(struct protection_domain *domain);
120 121
121/**************************************************************************** 122/****************************************************************************
122 * 123 *
@@ -1881,12 +1882,9 @@ static struct dma_ops_domain *dma_ops_domain_alloc(void)
1881 if (!dma_dom) 1882 if (!dma_dom)
1882 return NULL; 1883 return NULL;
1883 1884
1884 spin_lock_init(&dma_dom->domain.lock); 1885 if (protection_domain_init(&dma_dom->domain))
1885
1886 dma_dom->domain.id = domain_id_alloc();
1887 if (dma_dom->domain.id == 0)
1888 goto free_dma_dom; 1886 goto free_dma_dom;
1889 INIT_LIST_HEAD(&dma_dom->domain.dev_list); 1887
1890 dma_dom->domain.mode = PAGE_MODE_2_LEVEL; 1888 dma_dom->domain.mode = PAGE_MODE_2_LEVEL;
1891 dma_dom->domain.pt_root = (void *)get_zeroed_page(GFP_KERNEL); 1889 dma_dom->domain.pt_root = (void *)get_zeroed_page(GFP_KERNEL);
1892 dma_dom->domain.flags = PD_DMA_OPS_MASK; 1890 dma_dom->domain.flags = PD_DMA_OPS_MASK;
@@ -2916,6 +2914,18 @@ static void protection_domain_free(struct protection_domain *domain)
2916 kfree(domain); 2914 kfree(domain);
2917} 2915}
2918 2916
2917static int protection_domain_init(struct protection_domain *domain)
2918{
2919 spin_lock_init(&domain->lock);
2920 mutex_init(&domain->api_lock);
2921 domain->id = domain_id_alloc();
2922 if (!domain->id)
2923 return -ENOMEM;
2924 INIT_LIST_HEAD(&domain->dev_list);
2925
2926 return 0;
2927}
2928
2919static struct protection_domain *protection_domain_alloc(void) 2929static struct protection_domain *protection_domain_alloc(void)
2920{ 2930{
2921 struct protection_domain *domain; 2931 struct protection_domain *domain;
@@ -2924,12 +2934,8 @@ static struct protection_domain *protection_domain_alloc(void)
2924 if (!domain) 2934 if (!domain)
2925 return NULL; 2935 return NULL;
2926 2936
2927 spin_lock_init(&domain->lock); 2937 if (protection_domain_init(domain))
2928 mutex_init(&domain->api_lock);
2929 domain->id = domain_id_alloc();
2930 if (!domain->id)
2931 goto out_err; 2938 goto out_err;
2932 INIT_LIST_HEAD(&domain->dev_list);
2933 2939
2934 add_domain_to_list(domain); 2940 add_domain_to_list(domain);
2935 2941
diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c
index f14130121298..8e9ec81ce4bb 100644
--- a/drivers/iommu/arm-smmu-v3.c
+++ b/drivers/iommu/arm-smmu-v3.c
@@ -1389,8 +1389,7 @@ static void arm_smmu_domain_free(struct iommu_domain *domain)
1389 struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain); 1389 struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
1390 struct arm_smmu_device *smmu = smmu_domain->smmu; 1390 struct arm_smmu_device *smmu = smmu_domain->smmu;
1391 1391
1392 if (smmu_domain->pgtbl_ops) 1392 free_io_pgtable_ops(smmu_domain->pgtbl_ops);
1393 free_io_pgtable_ops(smmu_domain->pgtbl_ops);
1394 1393
1395 /* Free the CD and ASID, if we allocated them */ 1394 /* Free the CD and ASID, if we allocated them */
1396 if (smmu_domain->stage == ARM_SMMU_DOMAIN_S1) { 1395 if (smmu_domain->stage == ARM_SMMU_DOMAIN_S1) {
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index dce041b1c139..4cd0c29cb585 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -1566,7 +1566,7 @@ static int arm_smmu_device_cfg_probe(struct arm_smmu_device *smmu)
1566 return -ENODEV; 1566 return -ENODEV;
1567 } 1567 }
1568 1568
1569 if ((id & ID0_S1TS) && ((smmu->version == 1) || (id & ID0_ATOSNS))) { 1569 if ((id & ID0_S1TS) && ((smmu->version == 1) || !(id & ID0_ATOSNS))) {
1570 smmu->features |= ARM_SMMU_FEAT_TRANS_OPS; 1570 smmu->features |= ARM_SMMU_FEAT_TRANS_OPS;
1571 dev_notice(smmu->dev, "\taddress translation ops\n"); 1571 dev_notice(smmu->dev, "\taddress translation ops\n");
1572 } 1572 }
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 49e7542510d1..f286090931cc 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -847,13 +847,24 @@ static int add_iommu_group(struct device *dev, void *data)
847{ 847{
848 struct iommu_callback_data *cb = data; 848 struct iommu_callback_data *cb = data;
849 const struct iommu_ops *ops = cb->ops; 849 const struct iommu_ops *ops = cb->ops;
850 int ret;
850 851
851 if (!ops->add_device) 852 if (!ops->add_device)
852 return 0; 853 return 0;
853 854
854 WARN_ON(dev->iommu_group); 855 WARN_ON(dev->iommu_group);
855 856
856 return ops->add_device(dev); 857 ret = ops->add_device(dev);
858
859 /*
860 * We ignore -ENODEV errors for now, as they just mean that the
861 * device is not translated by an IOMMU. We still care about
862 * other errors and fail to initialize when they happen.
863 */
864 if (ret == -ENODEV)
865 ret = 0;
866
867 return ret;
857} 868}
858 869
859static int remove_iommu_group(struct device *dev, void *data) 870static int remove_iommu_group(struct device *dev, void *data)