浏览代码

Merge tag 'iommu-fixes-v4.0-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu

Pull IOMMU fixes from Joerg Roedel:
 "This contains fixes for:

   - a VT-d issue where hardware domain-ids might be freed while still
     in use.

   - an ipmmu-vmsa issue where where the device-table was not zero
     terminated

   - unchecked register access issue in the arm-smmu driver"

* tag 'iommu-fixes-v4.0-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu:
  iommu/vt-d: Remove unused variable
  iommu: ipmmu-vmsa: Add terminating entry for ipmmu_of_ids
  iommu/vt-d: Detach domain *only* from attached iommus
  iommu/arm-smmu: fix ARM_SMMU_FEAT_TRANS_OPS condition
Linus Torvalds 10 年之前
父节点
当前提交
d4039314d0
共有 3 个文件被更改,包括 10 次插入7 次删除
  1. 6 3
      drivers/iommu/arm-smmu.c
  2. 3 4
      drivers/iommu/intel-iommu.c
  3. 1 0
      drivers/iommu/ipmmu-vmsa.c

+ 6 - 3
drivers/iommu/arm-smmu.c

@@ -1288,10 +1288,13 @@ static phys_addr_t arm_smmu_iova_to_phys(struct iommu_domain *domain,
 		return 0;
 		return 0;
 
 
 	spin_lock_irqsave(&smmu_domain->pgtbl_lock, flags);
 	spin_lock_irqsave(&smmu_domain->pgtbl_lock, flags);
-	if (smmu_domain->smmu->features & ARM_SMMU_FEAT_TRANS_OPS)
+	if (smmu_domain->smmu->features & ARM_SMMU_FEAT_TRANS_OPS &&
+			smmu_domain->stage == ARM_SMMU_DOMAIN_S1) {
 		ret = arm_smmu_iova_to_phys_hard(domain, iova);
 		ret = arm_smmu_iova_to_phys_hard(domain, iova);
-	else
+	} else {
 		ret = ops->iova_to_phys(ops, iova);
 		ret = ops->iova_to_phys(ops, iova);
+	}
+
 	spin_unlock_irqrestore(&smmu_domain->pgtbl_lock, flags);
 	spin_unlock_irqrestore(&smmu_domain->pgtbl_lock, flags);
 
 
 	return ret;
 	return ret;
@@ -1556,7 +1559,7 @@ static int arm_smmu_device_cfg_probe(struct arm_smmu_device *smmu)
 		return -ENODEV;
 		return -ENODEV;
 	}
 	}
 
 
-	if (smmu->version == 1 || (!(id & ID0_ATOSNS) && (id & ID0_S1TS))) {
+	if ((id & ID0_S1TS) && ((smmu->version == 1) || (id & ID0_ATOSNS))) {
 		smmu->features |= ARM_SMMU_FEAT_TRANS_OPS;
 		smmu->features |= ARM_SMMU_FEAT_TRANS_OPS;
 		dev_notice(smmu->dev, "\taddress translation ops\n");
 		dev_notice(smmu->dev, "\taddress translation ops\n");
 	}
 	}

+ 3 - 4
drivers/iommu/intel-iommu.c

@@ -1742,9 +1742,8 @@ static int domain_init(struct dmar_domain *domain, int guest_width)
 
 
 static void domain_exit(struct dmar_domain *domain)
 static void domain_exit(struct dmar_domain *domain)
 {
 {
-	struct dmar_drhd_unit *drhd;
-	struct intel_iommu *iommu;
 	struct page *freelist = NULL;
 	struct page *freelist = NULL;
+	int i;
 
 
 	/* Domain 0 is reserved, so dont process it */
 	/* Domain 0 is reserved, so dont process it */
 	if (!domain)
 	if (!domain)
@@ -1764,8 +1763,8 @@ static void domain_exit(struct dmar_domain *domain)
 
 
 	/* clear attached or cached domains */
 	/* clear attached or cached domains */
 	rcu_read_lock();
 	rcu_read_lock();
-	for_each_active_iommu(iommu, drhd)
-		iommu_detach_domain(domain, iommu);
+	for_each_set_bit(i, domain->iommu_bmp, g_num_of_iommus)
+		iommu_detach_domain(domain, g_iommus[i]);
 	rcu_read_unlock();
 	rcu_read_unlock();
 
 
 	dma_free_pagelist(freelist);
 	dma_free_pagelist(freelist);

+ 1 - 0
drivers/iommu/ipmmu-vmsa.c

@@ -851,6 +851,7 @@ static int ipmmu_remove(struct platform_device *pdev)
 
 
 static const struct of_device_id ipmmu_of_ids[] = {
 static const struct of_device_id ipmmu_of_ids[] = {
 	{ .compatible = "renesas,ipmmu-vmsa", },
 	{ .compatible = "renesas,ipmmu-vmsa", },
+	{ }
 };
 };
 
 
 static struct platform_driver ipmmu_driver = {
 static struct platform_driver ipmmu_driver = {