Commit 1a2b4185 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'iommu-fixes-v6.7-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu

Pull iommu fixes from Joerg Roedel:

 - Fix race conditions in device probe path

 - Handle ERR_PTR() returns in __iommu_domain_alloc() path

 - Update MAINTAINERS entry for Qualcom IOMMUs

 - Printk argument fix in device tree specific code

 - Several Intel VT-d fixes from Lu Baolu:
     - Do not support enforcing cache coherency for non-empty domains
     - Avoid devTLB invalidation if iommu is off
     - Disable PCI ATS in legacy passthrough mode
     - Support non-PCI devices when clearing context
     - Fix incorrect cache invalidation for mm notification
     - Add MTL to quirk list to skip TE disabling
     - Set variable intel_dirty_ops to static

* tag 'iommu-fixes-v6.7-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu:
  iommu: Fix printk arg in of_iommu_get_resv_regions()
  iommu/vt-d: Set variable intel_dirty_ops to static
  iommu/vt-d: Fix incorrect cache invalidation for mm notification
  iommu/vt-d: Add MTL to quirk list to skip TE disabling
  iommu/vt-d: Make context clearing consistent with context mapping
  iommu/vt-d: Disable PCI ATS in legacy passthrough mode
  iommu/vt-d: Omit devTLB invalidation requests when TES=0
  iommu/vt-d: Support enforce_cache_coherency only for empty domains
  iommu: Avoid more races around device probe
  MAINTAINERS: list all Qualcomm IOMMU drivers in the QUALCOMM IOMMU entry
  iommu: Flow ERR_PTR out from __iommu_domain_alloc()
parents 06a3c59f c2183b3d
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -17946,6 +17946,8 @@ L: iommu@lists.linux.dev
L:	linux-arm-msm@vger.kernel.org
S:	Maintained
F:	drivers/iommu/arm/arm-smmu/qcom_iommu.c
F:	drivers/iommu/arm/arm-smmu/arm-smmu-qcom*
F:	drivers/iommu/msm_iommu*
QUALCOMM IPC ROUTER (QRTR) DRIVER
M:	Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+6 −1
Original line number Diff line number Diff line
@@ -1568,17 +1568,22 @@ static const struct iommu_ops *acpi_iommu_configure_id(struct device *dev,
	int err;
	const struct iommu_ops *ops;

	/* Serialise to make dev->iommu stable under our potential fwspec */
	mutex_lock(&iommu_probe_device_lock);
	/*
	 * If we already translated the fwspec there is nothing left to do,
	 * return the iommu_ops.
	 */
	ops = acpi_iommu_fwspec_ops(dev);
	if (ops)
	if (ops) {
		mutex_unlock(&iommu_probe_device_lock);
		return ops;
	}

	err = iort_iommu_configure_id(dev, id_in);
	if (err && err != -EPROBE_DEFER)
		err = viot_iommu_configure(dev);
	mutex_unlock(&iommu_probe_device_lock);

	/*
	 * If we have reason to believe the IOMMU driver missed the initial
+18 −0
Original line number Diff line number Diff line
@@ -1522,6 +1522,15 @@ void qi_flush_dev_iotlb(struct intel_iommu *iommu, u16 sid, u16 pfsid,
{
	struct qi_desc desc;

	/*
	 * VT-d spec, section 4.3:
	 *
	 * Software is recommended to not submit any Device-TLB invalidation
	 * requests while address remapping hardware is disabled.
	 */
	if (!(iommu->gcmd & DMA_GCMD_TE))
		return;

	if (mask) {
		addr |= (1ULL << (VTD_PAGE_SHIFT + mask - 1)) - 1;
		desc.qw1 = QI_DEV_IOTLB_ADDR(addr) | QI_DEV_IOTLB_SIZE;
@@ -1587,6 +1596,15 @@ void qi_flush_dev_iotlb_pasid(struct intel_iommu *iommu, u16 sid, u16 pfsid,
	unsigned long mask = 1UL << (VTD_PAGE_SHIFT + size_order - 1);
	struct qi_desc desc = {.qw1 = 0, .qw2 = 0, .qw3 = 0};

	/*
	 * VT-d spec, section 4.3:
	 *
	 * Software is recommended to not submit any Device-TLB invalidation
	 * requests while address remapping hardware is disabled.
	 */
	if (!(iommu->gcmd & DMA_GCMD_TE))
		return;

	desc.qw0 = QI_DEV_EIOTLB_PASID(pasid) | QI_DEV_EIOTLB_SID(sid) |
		QI_DEV_EIOTLB_QDEP(qdep) | QI_DEIOTLB_TYPE |
		QI_DEV_IOTLB_PFSID(pfsid);
+11 −7
Original line number Diff line number Diff line
@@ -299,7 +299,7 @@ static int iommu_skip_te_disable;
#define IDENTMAP_AZALIA		4

const struct iommu_ops intel_iommu_ops;
const struct iommu_dirty_ops intel_dirty_ops;
static const struct iommu_dirty_ops intel_dirty_ops;

static bool translation_pre_enabled(struct intel_iommu *iommu)
{
@@ -2207,6 +2207,8 @@ __domain_mapping(struct dmar_domain *domain, unsigned long iov_pfn,
			attr |= DMA_FL_PTE_DIRTY;
	}

	domain->has_mappings = true;

	pteval = ((phys_addr_t)phys_pfn << VTD_PAGE_SHIFT) | attr;

	while (nr_pages > 0) {
@@ -2490,6 +2492,7 @@ static int dmar_domain_attach_device(struct dmar_domain *domain,
		return ret;
	}

	if (sm_supported(info->iommu) || !domain_type_is_si(info->domain))
		iommu_enable_pci_caps(info);

	return 0;
@@ -3925,8 +3928,8 @@ static int domain_context_clear_one_cb(struct pci_dev *pdev, u16 alias, void *op
 */
static void domain_context_clear(struct device_domain_info *info)
{
	if (!info->iommu || !info->dev || !dev_is_pci(info->dev))
		return;
	if (!dev_is_pci(info->dev))
		domain_context_clear_one(info, info->bus, info->devfn);

	pci_for_each_dma_alias(to_pci_dev(info->dev),
			       &domain_context_clear_one_cb, info);
@@ -4360,7 +4363,8 @@ static bool intel_iommu_enforce_cache_coherency(struct iommu_domain *domain)
		return true;

	spin_lock_irqsave(&dmar_domain->lock, flags);
	if (!domain_support_force_snooping(dmar_domain)) {
	if (!domain_support_force_snooping(dmar_domain) ||
	    (!dmar_domain->use_first_level && dmar_domain->has_mappings)) {
		spin_unlock_irqrestore(&dmar_domain->lock, flags);
		return false;
	}
@@ -4925,7 +4929,7 @@ static int intel_iommu_read_and_clear_dirty(struct iommu_domain *domain,
	return 0;
}

const struct iommu_dirty_ops intel_dirty_ops = {
static const struct iommu_dirty_ops intel_dirty_ops = {
	.set_dirty_tracking = intel_iommu_set_dirty_tracking,
	.read_and_clear_dirty = intel_iommu_read_and_clear_dirty,
};
@@ -5073,7 +5077,7 @@ static void quirk_igfx_skip_te_disable(struct pci_dev *dev)
	ver = (dev->device >> 8) & 0xff;
	if (ver != 0x45 && ver != 0x46 && ver != 0x4c &&
	    ver != 0x4e && ver != 0x8a && ver != 0x98 &&
	    ver != 0x9a && ver != 0xa7)
	    ver != 0x9a && ver != 0xa7 && ver != 0x7d)
		return;

	if (risky_device(dev))
+3 −0
Original line number Diff line number Diff line
@@ -602,6 +602,9 @@ struct dmar_domain {
					 */
	u8 dirty_tracking:1;		/* Dirty tracking is enabled */
	u8 nested_parent:1;		/* Has other domains nested on it */
	u8 has_mappings:1;		/* Has mappings configured through
					 * iommu_map() interface.
					 */

	spinlock_t lock;		/* Protect device tracking lists */
	struct list_head devices;	/* all devices' list */
Loading