Commit 13c6bba6 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'iommu-fixes-v6.11-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/iommu/linux

Pull iommu fixes from Joerg Roedel:

 - Fix a device-stall problem in bad io-page-fault setups (faults
   received from devices with no supporting domain attached).

 - Context flush fix for Intel VT-d.

 - Do not allow non-read+non-write mapping through iommufd as most
   implementations can not handle that.

 - Fix a possible infinite-loop issue in map_pages() path.

 - Add Jean-Philippe as reviewer for SMMUv3 SVA support

* tag 'iommu-fixes-v6.11-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/iommu/linux:
  MAINTAINERS: Add Jean-Philippe as SMMUv3 SVA reviewer
  iommu: Do not return 0 from map_pages if it doesn't do anything
  iommufd: Do not allow creating areas without READ or WRITE
  iommu/vt-d: Fix incorrect domain ID in context flush helper
  iommu: Handle iommu faults for a bad iopf setup
parents 20371ba1 51eeef9a
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -1880,6 +1880,10 @@ F: Documentation/devicetree/bindings/iommu/arm,smmu*
F:	drivers/iommu/arm/
F:	drivers/iommu/io-pgtable-arm*
ARM SMMU SVA SUPPORT
R:	Jean-Philippe Brucker <jean-philippe@linaro.org>
F:	drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c
ARM SUB-ARCHITECTURES
L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
S:	Maintained
+1 −1
Original line number Diff line number Diff line
@@ -1777,7 +1777,7 @@ static int arm_smmu_handle_evt(struct arm_smmu_device *smmu, u64 *evt)
		goto out_unlock;
	}

	iommu_report_device_fault(master->dev, &fault_evt);
	ret = iommu_report_device_fault(master->dev, &fault_evt);
out_unlock:
	mutex_unlock(&smmu->streams_mutex);
	return ret;
+6 −2
Original line number Diff line number Diff line
@@ -1944,6 +1944,7 @@ static void domain_context_clear_one(struct device_domain_info *info, u8 bus, u8
{
	struct intel_iommu *iommu = info->iommu;
	struct context_entry *context;
	u16 did;

	spin_lock(&iommu->lock);
	context = iommu_context_addr(iommu, bus, devfn, 0);
@@ -1952,10 +1953,11 @@ static void domain_context_clear_one(struct device_domain_info *info, u8 bus, u8
		return;
	}

	did = context_domain_id(context);
	context_clear_entry(context);
	__iommu_flush_cache(iommu, context, sizeof(*context));
	spin_unlock(&iommu->lock);
	intel_context_flush_present(info, context, true);
	intel_context_flush_present(info, context, did, true);
}

static int domain_setup_first_level(struct intel_iommu *iommu,
@@ -4249,6 +4251,7 @@ static int context_flip_pri(struct device_domain_info *info, bool enable)
	struct intel_iommu *iommu = info->iommu;
	u8 bus = info->bus, devfn = info->devfn;
	struct context_entry *context;
	u16 did;

	spin_lock(&iommu->lock);
	if (context_copied(iommu, bus, devfn)) {
@@ -4261,6 +4264,7 @@ static int context_flip_pri(struct device_domain_info *info, bool enable)
		spin_unlock(&iommu->lock);
		return -ENODEV;
	}
	did = context_domain_id(context);

	if (enable)
		context_set_sm_pre(context);
@@ -4269,7 +4273,7 @@ static int context_flip_pri(struct device_domain_info *info, bool enable)

	if (!ecap_coherent(iommu->ecap))
		clflush_cache_range(context, sizeof(*context));
	intel_context_flush_present(info, context, true);
	intel_context_flush_present(info, context, did, true);
	spin_unlock(&iommu->lock);

	return 0;
+1 −1
Original line number Diff line number Diff line
@@ -1154,7 +1154,7 @@ void cache_tag_flush_range_np(struct dmar_domain *domain, unsigned long start,

void intel_context_flush_present(struct device_domain_info *info,
				 struct context_entry *context,
				 bool affect_domains);
				 u16 did, bool affect_domains);

#ifdef CONFIG_INTEL_IOMMU_SVM
void intel_svm_check(struct intel_iommu *iommu);
+4 −3
Original line number Diff line number Diff line
@@ -683,6 +683,7 @@ static void device_pasid_table_teardown(struct device *dev, u8 bus, u8 devfn)
	struct device_domain_info *info = dev_iommu_priv_get(dev);
	struct intel_iommu *iommu = info->iommu;
	struct context_entry *context;
	u16 did;

	spin_lock(&iommu->lock);
	context = iommu_context_addr(iommu, bus, devfn, false);
@@ -691,10 +692,11 @@ static void device_pasid_table_teardown(struct device *dev, u8 bus, u8 devfn)
		return;
	}

	did = context_domain_id(context);
	context_clear_entry(context);
	__iommu_flush_cache(iommu, context, sizeof(*context));
	spin_unlock(&iommu->lock);
	intel_context_flush_present(info, context, false);
	intel_context_flush_present(info, context, did, false);
}

static int pci_pasid_table_teardown(struct pci_dev *pdev, u16 alias, void *data)
@@ -885,10 +887,9 @@ static void __context_flush_dev_iotlb(struct device_domain_info *info)
 */
void intel_context_flush_present(struct device_domain_info *info,
				 struct context_entry *context,
				 bool flush_domains)
				 u16 did, bool flush_domains)
{
	struct intel_iommu *iommu = info->iommu;
	u16 did = context_domain_id(context);
	struct pasid_entry *pte;
	int i;

Loading