Skip to content

Commit 4b20576

Browse files
committed
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
2 parents fa079ba + ab362ff commit 4b20576

File tree

5 files changed

+51
-37
lines changed

5 files changed

+51
-37
lines changed

drivers/iommu/Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ obj-$(CONFIG_MSM_IOMMU) += msm_iommu.o
1414
obj-$(CONFIG_AMD_IOMMU) += amd_iommu.o amd_iommu_init.o amd_iommu_quirks.o
1515
obj-$(CONFIG_AMD_IOMMU_DEBUGFS) += amd_iommu_debugfs.o
1616
obj-$(CONFIG_AMD_IOMMU_V2) += amd_iommu_v2.o
17-
obj-$(CONFIG_ARM_SMMU) += arm-smmu-mod.o
18-
arm-smmu-mod-objs += arm-smmu.o arm-smmu-impl.o arm-smmu-qcom.o
17+
obj-$(CONFIG_ARM_SMMU) += arm_smmu.o
18+
arm_smmu-objs += arm-smmu.o arm-smmu-impl.o arm-smmu-qcom.o
1919
obj-$(CONFIG_ARM_SMMU_V3) += arm-smmu-v3.o
2020
obj-$(CONFIG_DMAR_TABLE) += dmar.o
2121
obj-$(CONFIG_INTEL_IOMMU) += intel-iommu.o intel-pasid.o

drivers/iommu/amd_iommu_init.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2523,6 +2523,7 @@ static int __init early_amd_iommu_init(void)
25232523
struct acpi_table_header *ivrs_base;
25242524
acpi_status status;
25252525
int i, remap_cache_sz, ret = 0;
2526+
u32 pci_id;
25262527

25272528
if (!amd_iommu_detected)
25282529
return -ENODEV;
@@ -2610,6 +2611,16 @@ static int __init early_amd_iommu_init(void)
26102611
if (ret)
26112612
goto out;
26122613

2614+
/* Disable IOMMU if there's Stoney Ridge graphics */
2615+
for (i = 0; i < 32; i++) {
2616+
pci_id = read_pci_config(0, i, 0, 0);
2617+
if ((pci_id & 0xffff) == 0x1002 && (pci_id >> 16) == 0x98e4) {
2618+
pr_info("Disable IOMMU on Stoney Ridge\n");
2619+
amd_iommu_disabled = true;
2620+
break;
2621+
}
2622+
}
2623+
26132624
/* Disable any previously enabled IOMMUs */
26142625
if (!is_kdump_kernel() || amd_iommu_disabled)
26152626
disable_iommus();
@@ -2718,7 +2729,7 @@ static int __init state_next(void)
27182729
ret = early_amd_iommu_init();
27192730
init_state = ret ? IOMMU_INIT_ERROR : IOMMU_ACPI_FINISHED;
27202731
if (init_state == IOMMU_ACPI_FINISHED && amd_iommu_disabled) {
2721-
pr_info("AMD IOMMU disabled on kernel command-line\n");
2732+
pr_info("AMD IOMMU disabled\n");
27222733
init_state = IOMMU_CMDLINE_DISABLED;
27232734
ret = -EINVAL;
27242735
}

drivers/iommu/intel-iommu.c

Lines changed: 24 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -762,6 +762,11 @@ static int iommu_dummy(struct device *dev)
762762
return dev->archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO;
763763
}
764764

765+
static bool attach_deferred(struct device *dev)
766+
{
767+
return dev->archdata.iommu == DEFER_DEVICE_DOMAIN_INFO;
768+
}
769+
765770
/**
766771
* is_downstream_to_pci_bridge - test if a device belongs to the PCI
767772
* sub-hierarchy of a candidate PCI-PCI bridge
@@ -2510,8 +2515,7 @@ struct dmar_domain *find_domain(struct device *dev)
25102515
{
25112516
struct device_domain_info *info;
25122517

2513-
if (unlikely(dev->archdata.iommu == DEFER_DEVICE_DOMAIN_INFO ||
2514-
dev->archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO))
2518+
if (unlikely(attach_deferred(dev) || iommu_dummy(dev)))
25152519
return NULL;
25162520

25172521
if (dev_is_pci(dev))
@@ -2525,18 +2529,14 @@ struct dmar_domain *find_domain(struct device *dev)
25252529
return NULL;
25262530
}
25272531

2528-
static struct dmar_domain *deferred_attach_domain(struct device *dev)
2532+
static void do_deferred_attach(struct device *dev)
25292533
{
2530-
if (unlikely(dev->archdata.iommu == DEFER_DEVICE_DOMAIN_INFO)) {
2531-
struct iommu_domain *domain;
2532-
2533-
dev->archdata.iommu = NULL;
2534-
domain = iommu_get_domain_for_dev(dev);
2535-
if (domain)
2536-
intel_iommu_attach_device(domain, dev);
2537-
}
2534+
struct iommu_domain *domain;
25382535

2539-
return find_domain(dev);
2536+
dev->archdata.iommu = NULL;
2537+
domain = iommu_get_domain_for_dev(dev);
2538+
if (domain)
2539+
intel_iommu_attach_device(domain, dev);
25402540
}
25412541

25422542
static inline struct device_domain_info *
@@ -2916,7 +2916,7 @@ static int identity_mapping(struct device *dev)
29162916
struct device_domain_info *info;
29172917

29182918
info = dev->archdata.iommu;
2919-
if (info && info != DUMMY_DEVICE_DOMAIN_INFO && info != DEFER_DEVICE_DOMAIN_INFO)
2919+
if (info)
29202920
return (info->domain == si_domain);
29212921

29222922
return 0;
@@ -3587,6 +3587,9 @@ static bool iommu_need_mapping(struct device *dev)
35873587
if (iommu_dummy(dev))
35883588
return false;
35893589

3590+
if (unlikely(attach_deferred(dev)))
3591+
do_deferred_attach(dev);
3592+
35903593
ret = identity_mapping(dev);
35913594
if (ret) {
35923595
u64 dma_mask = *dev->dma_mask;
@@ -3635,7 +3638,7 @@ static dma_addr_t __intel_map_single(struct device *dev, phys_addr_t paddr,
36353638

36363639
BUG_ON(dir == DMA_NONE);
36373640

3638-
domain = deferred_attach_domain(dev);
3641+
domain = find_domain(dev);
36393642
if (!domain)
36403643
return DMA_MAPPING_ERROR;
36413644

@@ -3855,7 +3858,7 @@ static int intel_map_sg(struct device *dev, struct scatterlist *sglist, int nele
38553858
if (!iommu_need_mapping(dev))
38563859
return dma_direct_map_sg(dev, sglist, nelems, dir, attrs);
38573860

3858-
domain = deferred_attach_domain(dev);
3861+
domain = find_domain(dev);
38593862
if (!domain)
38603863
return 0;
38613864

@@ -3950,7 +3953,11 @@ bounce_map_single(struct device *dev, phys_addr_t paddr, size_t size,
39503953
int prot = 0;
39513954
int ret;
39523955

3953-
domain = deferred_attach_domain(dev);
3956+
if (unlikely(attach_deferred(dev)))
3957+
do_deferred_attach(dev);
3958+
3959+
domain = find_domain(dev);
3960+
39543961
if (WARN_ON(dir == DMA_NONE || !domain))
39553962
return DMA_MAPPING_ERROR;
39563963

@@ -6133,7 +6140,7 @@ intel_iommu_aux_get_pasid(struct iommu_domain *domain, struct device *dev)
61336140
static bool intel_iommu_is_attach_deferred(struct iommu_domain *domain,
61346141
struct device *dev)
61356142
{
6136-
return dev->archdata.iommu == DEFER_DEVICE_DOMAIN_INFO;
6143+
return attach_deferred(dev);
61376144
}
61386145

61396146
static int

drivers/iommu/qcom_iommu.c

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -344,21 +344,19 @@ static void qcom_iommu_domain_free(struct iommu_domain *domain)
344344
{
345345
struct qcom_iommu_domain *qcom_domain = to_qcom_iommu_domain(domain);
346346

347-
if (WARN_ON(qcom_domain->iommu)) /* forgot to detach? */
348-
return;
349-
350347
iommu_put_dma_cookie(domain);
351348

352-
/* NOTE: unmap can be called after client device is powered off,
353-
* for example, with GPUs or anything involving dma-buf. So we
354-
* cannot rely on the device_link. Make sure the IOMMU is on to
355-
* avoid unclocked accesses in the TLB inv path:
356-
*/
357-
pm_runtime_get_sync(qcom_domain->iommu->dev);
358-
359-
free_io_pgtable_ops(qcom_domain->pgtbl_ops);
360-
361-
pm_runtime_put_sync(qcom_domain->iommu->dev);
349+
if (qcom_domain->iommu) {
350+
/*
351+
* NOTE: unmap can be called after client device is powered
352+
* off, for example, with GPUs or anything involving dma-buf.
353+
* So we cannot rely on the device_link. Make sure the IOMMU
354+
* is on to avoid unclocked accesses in the TLB inv path:
355+
*/
356+
pm_runtime_get_sync(qcom_domain->iommu->dev);
357+
free_io_pgtable_ops(qcom_domain->pgtbl_ops);
358+
pm_runtime_put_sync(qcom_domain->iommu->dev);
359+
}
362360

363361
kfree(qcom_domain);
364362
}
@@ -404,7 +402,7 @@ static void qcom_iommu_detach_dev(struct iommu_domain *domain, struct device *de
404402
struct qcom_iommu_domain *qcom_domain = to_qcom_iommu_domain(domain);
405403
unsigned i;
406404

407-
if (!qcom_domain->iommu)
405+
if (WARN_ON(!qcom_domain->iommu))
408406
return;
409407

410408
pm_runtime_get_sync(qcom_iommu->dev);
@@ -417,8 +415,6 @@ static void qcom_iommu_detach_dev(struct iommu_domain *domain, struct device *de
417415
ctx->domain = NULL;
418416
}
419417
pm_runtime_put_sync(qcom_iommu->dev);
420-
421-
qcom_domain->iommu = NULL;
422418
}
423419

424420
static int qcom_iommu_map(struct iommu_domain *domain, unsigned long iova,

include/linux/intel-svm.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ static inline int intel_svm_unbind_mm(struct device *dev, int pasid)
122122
BUG();
123123
}
124124

125-
static int intel_svm_is_pasid_valid(struct device *dev, int pasid)
125+
static inline int intel_svm_is_pasid_valid(struct device *dev, int pasid)
126126
{
127127
return -EINVAL;
128128
}

0 commit comments

Comments
 (0)