Loading MAINTAINERS +2 −0 Original line number Diff line number Diff line Loading @@ -17948,6 +17948,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> drivers/acpi/scan.c +6 −1 Original line number Diff line number Diff line Loading @@ -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 Loading drivers/iommu/intel/dmar.c +18 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); Loading drivers/iommu/intel/iommu.c +11 −7 Original line number Diff line number Diff line Loading @@ -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) { Loading Loading @@ -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) { Loading Loading @@ -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; Loading Loading @@ -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); Loading Loading @@ -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; } Loading Loading @@ -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, }; Loading Loading @@ -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)) Loading drivers/iommu/intel/iommu.h +3 −0 Original line number Diff line number Diff line Loading @@ -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 Loading
MAINTAINERS +2 −0 Original line number Diff line number Diff line Loading @@ -17948,6 +17948,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>
drivers/acpi/scan.c +6 −1 Original line number Diff line number Diff line Loading @@ -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 Loading
drivers/iommu/intel/dmar.c +18 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); Loading
drivers/iommu/intel/iommu.c +11 −7 Original line number Diff line number Diff line Loading @@ -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) { Loading Loading @@ -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) { Loading Loading @@ -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; Loading Loading @@ -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); Loading Loading @@ -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; } Loading Loading @@ -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, }; Loading Loading @@ -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)) Loading
drivers/iommu/intel/iommu.h +3 −0 Original line number Diff line number Diff line Loading @@ -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