IOMMU Fixes for Linux v5.6-rc2
Including: - Compile warning fix for the Intel IOMMU driver - Fix kdump boot with Intel IOMMU enabled and in passthrough mode - Disable AMD IOMMU on a Laptop/Embedded platform because the delay in introduces in DMA transactions causes screen flickering there with 4k monitors - Make domain_free function in QCOM IOMMU driver robust and not leak memory/dereference NULL pointers - Fix ARM-SMMU module parameter prefix names -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEEr9jSbILcajRFYWYyK/BELZcBGuMFAl5NZtcACgkQK/BELZcB GuMqlg/+N46EWTr7up5ZaYOkyIX0mzcc0sIVSdJ8q1J7d8i6cQsXA9YTN7VtcPs3 EZdGBL67aDc872iG9iyjpj5dgGSoMbu0vKe60AIUM88tGcfmnRHQw49UTlhzamrd vneS1EPyFpl9GlxLnJoHr1Yd1hDsBftz7KrArgBM9spcPsfZxFuRchCZdJWxVlfD Wi6R1k2L0quH5hiv6Pz+2yc45J4y5LQeCWyj8LKOtO5n6elgTFhKTPtlfGagNX7a U8E9bAVFr2fnnTBiyIj42pDU4VbXSZYYXs07mUIcZ7d+cBYBvyYxZsz71Y0pOrbh I4yS14RXeu+oErpU3S2s/txgCNkgnJtKbKJAAhgHyWzUNQuiNtwF3QYmwiIViQ4z gRqmiNN4qR+DTcYU9/oOep5ptuJmVFUmgfmL4u+LR/vODaRoDopFn7p1WEzCM7bv IaNwV8gcPoHJwF5CBiEMhsJfwpVnZ2a7YPiwBDM63n2/oz6rfGueD+5qEiy1I0iF 4UCvhHNIsdJg5wBNbxigTnmaO/XKkcVIx8uyRdBVfoP4igUppeH/Sa/daIrJ6nRe ebfdpwBkYav7nlIDJM7mUTD3vGe5lXHuIFn9DL9YMQSQ09pRaN7/PiBCDBGkKgOe eEo41i1no11ZsapqD/znq/WtUHxTxjw4YVJk4qlhrzX6obT9hKk= =DUFi -----END PGP SIGNATURE----- Merge tag 'iommu-fixes-v5.6-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu Pull iommu fixes from Joerg Roedel: - Compile warning fix for the Intel IOMMU driver - Fix kdump boot with Intel IOMMU enabled and in passthrough mode - Disable AMD IOMMU on a Laptop/Embedded platform because the delay it introduces in DMA transactions causes screen flickering there with 4k monitors - Make domain_free function in QCOM IOMMU driver robust and not leak memory/dereference NULL pointers - Fix ARM-SMMU module parameter prefix names * tag 'iommu-fixes-v5.6-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu: iommu/arm-smmu: Restore naming of driver parameter prefix iommu/qcom: Fix bogus detach logic iommu/amd: Disable IOMMU on Stoney Ridge systems iommu/vt-d: Simplify check in identity_mapping() iommu/vt-d: Remove deferred_attach_domain() iommu/vt-d: Do deferred attachment in iommu_need_mapping() iommu/vt-d: Move deferred device attachment into helper function iommu/vt-d: Add attach_deferred() helper iommu/vt-d: Fix compile warning from intel-svm.h
This commit is contained in:
commit
4b205766d8
|
@ -14,8 +14,8 @@ obj-$(CONFIG_MSM_IOMMU) += msm_iommu.o
|
|||
obj-$(CONFIG_AMD_IOMMU) += amd_iommu.o amd_iommu_init.o amd_iommu_quirks.o
|
||||
obj-$(CONFIG_AMD_IOMMU_DEBUGFS) += amd_iommu_debugfs.o
|
||||
obj-$(CONFIG_AMD_IOMMU_V2) += amd_iommu_v2.o
|
||||
obj-$(CONFIG_ARM_SMMU) += arm-smmu-mod.o
|
||||
arm-smmu-mod-objs += arm-smmu.o arm-smmu-impl.o arm-smmu-qcom.o
|
||||
obj-$(CONFIG_ARM_SMMU) += arm_smmu.o
|
||||
arm_smmu-objs += arm-smmu.o arm-smmu-impl.o arm-smmu-qcom.o
|
||||
obj-$(CONFIG_ARM_SMMU_V3) += arm-smmu-v3.o
|
||||
obj-$(CONFIG_DMAR_TABLE) += dmar.o
|
||||
obj-$(CONFIG_INTEL_IOMMU) += intel-iommu.o intel-pasid.o
|
||||
|
|
|
@ -2523,6 +2523,7 @@ static int __init early_amd_iommu_init(void)
|
|||
struct acpi_table_header *ivrs_base;
|
||||
acpi_status status;
|
||||
int i, remap_cache_sz, ret = 0;
|
||||
u32 pci_id;
|
||||
|
||||
if (!amd_iommu_detected)
|
||||
return -ENODEV;
|
||||
|
@ -2610,6 +2611,16 @@ static int __init early_amd_iommu_init(void)
|
|||
if (ret)
|
||||
goto out;
|
||||
|
||||
/* Disable IOMMU if there's Stoney Ridge graphics */
|
||||
for (i = 0; i < 32; i++) {
|
||||
pci_id = read_pci_config(0, i, 0, 0);
|
||||
if ((pci_id & 0xffff) == 0x1002 && (pci_id >> 16) == 0x98e4) {
|
||||
pr_info("Disable IOMMU on Stoney Ridge\n");
|
||||
amd_iommu_disabled = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Disable any previously enabled IOMMUs */
|
||||
if (!is_kdump_kernel() || amd_iommu_disabled)
|
||||
disable_iommus();
|
||||
|
@ -2718,7 +2729,7 @@ static int __init state_next(void)
|
|||
ret = early_amd_iommu_init();
|
||||
init_state = ret ? IOMMU_INIT_ERROR : IOMMU_ACPI_FINISHED;
|
||||
if (init_state == IOMMU_ACPI_FINISHED && amd_iommu_disabled) {
|
||||
pr_info("AMD IOMMU disabled on kernel command-line\n");
|
||||
pr_info("AMD IOMMU disabled\n");
|
||||
init_state = IOMMU_CMDLINE_DISABLED;
|
||||
ret = -EINVAL;
|
||||
}
|
||||
|
|
|
@ -762,6 +762,11 @@ static int iommu_dummy(struct device *dev)
|
|||
return dev->archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO;
|
||||
}
|
||||
|
||||
static bool attach_deferred(struct device *dev)
|
||||
{
|
||||
return dev->archdata.iommu == DEFER_DEVICE_DOMAIN_INFO;
|
||||
}
|
||||
|
||||
/**
|
||||
* is_downstream_to_pci_bridge - test if a device belongs to the PCI
|
||||
* sub-hierarchy of a candidate PCI-PCI bridge
|
||||
|
@ -2510,8 +2515,7 @@ struct dmar_domain *find_domain(struct device *dev)
|
|||
{
|
||||
struct device_domain_info *info;
|
||||
|
||||
if (unlikely(dev->archdata.iommu == DEFER_DEVICE_DOMAIN_INFO ||
|
||||
dev->archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO))
|
||||
if (unlikely(attach_deferred(dev) || iommu_dummy(dev)))
|
||||
return NULL;
|
||||
|
||||
if (dev_is_pci(dev))
|
||||
|
@ -2525,18 +2529,14 @@ struct dmar_domain *find_domain(struct device *dev)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static struct dmar_domain *deferred_attach_domain(struct device *dev)
|
||||
static void do_deferred_attach(struct device *dev)
|
||||
{
|
||||
if (unlikely(dev->archdata.iommu == DEFER_DEVICE_DOMAIN_INFO)) {
|
||||
struct iommu_domain *domain;
|
||||
struct iommu_domain *domain;
|
||||
|
||||
dev->archdata.iommu = NULL;
|
||||
domain = iommu_get_domain_for_dev(dev);
|
||||
if (domain)
|
||||
intel_iommu_attach_device(domain, dev);
|
||||
}
|
||||
|
||||
return find_domain(dev);
|
||||
dev->archdata.iommu = NULL;
|
||||
domain = iommu_get_domain_for_dev(dev);
|
||||
if (domain)
|
||||
intel_iommu_attach_device(domain, dev);
|
||||
}
|
||||
|
||||
static inline struct device_domain_info *
|
||||
|
@ -2916,7 +2916,7 @@ static int identity_mapping(struct device *dev)
|
|||
struct device_domain_info *info;
|
||||
|
||||
info = dev->archdata.iommu;
|
||||
if (info && info != DUMMY_DEVICE_DOMAIN_INFO && info != DEFER_DEVICE_DOMAIN_INFO)
|
||||
if (info)
|
||||
return (info->domain == si_domain);
|
||||
|
||||
return 0;
|
||||
|
@ -3587,6 +3587,9 @@ static bool iommu_need_mapping(struct device *dev)
|
|||
if (iommu_dummy(dev))
|
||||
return false;
|
||||
|
||||
if (unlikely(attach_deferred(dev)))
|
||||
do_deferred_attach(dev);
|
||||
|
||||
ret = identity_mapping(dev);
|
||||
if (ret) {
|
||||
u64 dma_mask = *dev->dma_mask;
|
||||
|
@ -3635,7 +3638,7 @@ static dma_addr_t __intel_map_single(struct device *dev, phys_addr_t paddr,
|
|||
|
||||
BUG_ON(dir == DMA_NONE);
|
||||
|
||||
domain = deferred_attach_domain(dev);
|
||||
domain = find_domain(dev);
|
||||
if (!domain)
|
||||
return DMA_MAPPING_ERROR;
|
||||
|
||||
|
@ -3855,7 +3858,7 @@ static int intel_map_sg(struct device *dev, struct scatterlist *sglist, int nele
|
|||
if (!iommu_need_mapping(dev))
|
||||
return dma_direct_map_sg(dev, sglist, nelems, dir, attrs);
|
||||
|
||||
domain = deferred_attach_domain(dev);
|
||||
domain = find_domain(dev);
|
||||
if (!domain)
|
||||
return 0;
|
||||
|
||||
|
@ -3950,7 +3953,11 @@ bounce_map_single(struct device *dev, phys_addr_t paddr, size_t size,
|
|||
int prot = 0;
|
||||
int ret;
|
||||
|
||||
domain = deferred_attach_domain(dev);
|
||||
if (unlikely(attach_deferred(dev)))
|
||||
do_deferred_attach(dev);
|
||||
|
||||
domain = find_domain(dev);
|
||||
|
||||
if (WARN_ON(dir == DMA_NONE || !domain))
|
||||
return DMA_MAPPING_ERROR;
|
||||
|
||||
|
@ -6133,7 +6140,7 @@ intel_iommu_aux_get_pasid(struct iommu_domain *domain, struct device *dev)
|
|||
static bool intel_iommu_is_attach_deferred(struct iommu_domain *domain,
|
||||
struct device *dev)
|
||||
{
|
||||
return dev->archdata.iommu == DEFER_DEVICE_DOMAIN_INFO;
|
||||
return attach_deferred(dev);
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
|
@ -344,21 +344,19 @@ static void qcom_iommu_domain_free(struct iommu_domain *domain)
|
|||
{
|
||||
struct qcom_iommu_domain *qcom_domain = to_qcom_iommu_domain(domain);
|
||||
|
||||
if (WARN_ON(qcom_domain->iommu)) /* forgot to detach? */
|
||||
return;
|
||||
|
||||
iommu_put_dma_cookie(domain);
|
||||
|
||||
/* NOTE: unmap can be called after client device is powered off,
|
||||
* for example, with GPUs or anything involving dma-buf. So we
|
||||
* cannot rely on the device_link. Make sure the IOMMU is on to
|
||||
* avoid unclocked accesses in the TLB inv path:
|
||||
*/
|
||||
pm_runtime_get_sync(qcom_domain->iommu->dev);
|
||||
|
||||
free_io_pgtable_ops(qcom_domain->pgtbl_ops);
|
||||
|
||||
pm_runtime_put_sync(qcom_domain->iommu->dev);
|
||||
if (qcom_domain->iommu) {
|
||||
/*
|
||||
* NOTE: unmap can be called after client device is powered
|
||||
* off, for example, with GPUs or anything involving dma-buf.
|
||||
* So we cannot rely on the device_link. Make sure the IOMMU
|
||||
* is on to avoid unclocked accesses in the TLB inv path:
|
||||
*/
|
||||
pm_runtime_get_sync(qcom_domain->iommu->dev);
|
||||
free_io_pgtable_ops(qcom_domain->pgtbl_ops);
|
||||
pm_runtime_put_sync(qcom_domain->iommu->dev);
|
||||
}
|
||||
|
||||
kfree(qcom_domain);
|
||||
}
|
||||
|
@ -404,7 +402,7 @@ static void qcom_iommu_detach_dev(struct iommu_domain *domain, struct device *de
|
|||
struct qcom_iommu_domain *qcom_domain = to_qcom_iommu_domain(domain);
|
||||
unsigned i;
|
||||
|
||||
if (!qcom_domain->iommu)
|
||||
if (WARN_ON(!qcom_domain->iommu))
|
||||
return;
|
||||
|
||||
pm_runtime_get_sync(qcom_iommu->dev);
|
||||
|
@ -417,8 +415,6 @@ static void qcom_iommu_detach_dev(struct iommu_domain *domain, struct device *de
|
|||
ctx->domain = NULL;
|
||||
}
|
||||
pm_runtime_put_sync(qcom_iommu->dev);
|
||||
|
||||
qcom_domain->iommu = NULL;
|
||||
}
|
||||
|
||||
static int qcom_iommu_map(struct iommu_domain *domain, unsigned long iova,
|
||||
|
|
|
@ -122,7 +122,7 @@ static inline int intel_svm_unbind_mm(struct device *dev, int pasid)
|
|||
BUG();
|
||||
}
|
||||
|
||||
static int intel_svm_is_pasid_valid(struct device *dev, int pasid)
|
||||
static inline int intel_svm_is_pasid_valid(struct device *dev, int pasid)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue