Skip to content

Commit 44b6e23

Browse files
committed
Merge tag 'iommu-fixes-v5.9-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu
Pull iommu fixes from Joerg Roedel: - Fix a device reference counting bug in the Exynos IOMMU driver. - Lockdep fix for the Intel VT-d driver. - Fix a bug in the AMD IOMMU driver which caused corruption of the IVRS ACPI table and caused IOMMU driver initialization failures in kdump kernels. * tag 'iommu-fixes-v5.9-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu: iommu/vt-d: Fix lockdep splat in iommu_flush_dev_iotlb() iommu/amd: Fix the overwritten field in IVMD header iommu/exynos: add missing put_device() call in exynos_iommu_of_xlate()
2 parents eed2ef4 + 1a3f2fd commit 44b6e23

3 files changed

Lines changed: 18 additions & 50 deletions

File tree

drivers/iommu/amd/init.c

Lines changed: 10 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1103,25 +1103,6 @@ static int __init add_early_maps(void)
11031103
return 0;
11041104
}
11051105

1106-
/*
1107-
* Reads the device exclusion range from ACPI and initializes the IOMMU with
1108-
* it
1109-
*/
1110-
static void __init set_device_exclusion_range(u16 devid, struct ivmd_header *m)
1111-
{
1112-
if (!(m->flags & IVMD_FLAG_EXCL_RANGE))
1113-
return;
1114-
1115-
/*
1116-
* Treat per-device exclusion ranges as r/w unity-mapped regions
1117-
* since some buggy BIOSes might lead to the overwritten exclusion
1118-
* range (exclusion_start and exclusion_length members). This
1119-
* happens when there are multiple exclusion ranges (IVMD entries)
1120-
* defined in ACPI table.
1121-
*/
1122-
m->flags = (IVMD_FLAG_IW | IVMD_FLAG_IR | IVMD_FLAG_UNITY_MAP);
1123-
}
1124-
11251106
/*
11261107
* Takes a pointer to an AMD IOMMU entry in the ACPI table and
11271108
* initializes the hardware and our data structures with it.
@@ -2073,30 +2054,6 @@ static void __init free_unity_maps(void)
20732054
}
20742055
}
20752056

2076-
/* called when we find an exclusion range definition in ACPI */
2077-
static int __init init_exclusion_range(struct ivmd_header *m)
2078-
{
2079-
int i;
2080-
2081-
switch (m->type) {
2082-
case ACPI_IVMD_TYPE:
2083-
set_device_exclusion_range(m->devid, m);
2084-
break;
2085-
case ACPI_IVMD_TYPE_ALL:
2086-
for (i = 0; i <= amd_iommu_last_bdf; ++i)
2087-
set_device_exclusion_range(i, m);
2088-
break;
2089-
case ACPI_IVMD_TYPE_RANGE:
2090-
for (i = m->devid; i <= m->aux; ++i)
2091-
set_device_exclusion_range(i, m);
2092-
break;
2093-
default:
2094-
break;
2095-
}
2096-
2097-
return 0;
2098-
}
2099-
21002057
/* called for unity map ACPI definition */
21012058
static int __init init_unity_map_range(struct ivmd_header *m)
21022059
{
@@ -2107,9 +2064,6 @@ static int __init init_unity_map_range(struct ivmd_header *m)
21072064
if (e == NULL)
21082065
return -ENOMEM;
21092066

2110-
if (m->flags & IVMD_FLAG_EXCL_RANGE)
2111-
init_exclusion_range(m);
2112-
21132067
switch (m->type) {
21142068
default:
21152069
kfree(e);
@@ -2133,6 +2087,16 @@ static int __init init_unity_map_range(struct ivmd_header *m)
21332087
e->address_end = e->address_start + PAGE_ALIGN(m->range_length);
21342088
e->prot = m->flags >> 1;
21352089

2090+
/*
2091+
* Treat per-device exclusion ranges as r/w unity-mapped regions
2092+
* since some buggy BIOSes might lead to the overwritten exclusion
2093+
* range (exclusion_start and exclusion_length members). This
2094+
* happens when there are multiple exclusion ranges (IVMD entries)
2095+
* defined in ACPI table.
2096+
*/
2097+
if (m->flags & IVMD_FLAG_EXCL_RANGE)
2098+
e->prot = (IVMD_FLAG_IW | IVMD_FLAG_IR) >> 1;
2099+
21362100
DUMP_printk("%s devid_start: %02x:%02x.%x devid_end: %02x:%02x.%x"
21372101
" range_start: %016llx range_end: %016llx flags: %x\n", s,
21382102
PCI_BUS_NUM(e->devid_start), PCI_SLOT(e->devid_start),

drivers/iommu/exynos-iommu.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1295,13 +1295,17 @@ static int exynos_iommu_of_xlate(struct device *dev,
12951295
return -ENODEV;
12961296

12971297
data = platform_get_drvdata(sysmmu);
1298-
if (!data)
1298+
if (!data) {
1299+
put_device(&sysmmu->dev);
12991300
return -ENODEV;
1301+
}
13001302

13011303
if (!owner) {
13021304
owner = kzalloc(sizeof(*owner), GFP_KERNEL);
1303-
if (!owner)
1305+
if (!owner) {
1306+
put_device(&sysmmu->dev);
13041307
return -ENOMEM;
1308+
}
13051309

13061310
INIT_LIST_HEAD(&owner->controllers);
13071311
mutex_init(&owner->rpm_lock);

drivers/iommu/intel/iommu.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2664,7 +2664,7 @@ static struct dmar_domain *dmar_insert_one_dev_info(struct intel_iommu *iommu,
26642664
}
26652665

26662666
/* Setup the PASID entry for requests without PASID: */
2667-
spin_lock(&iommu->lock);
2667+
spin_lock_irqsave(&iommu->lock, flags);
26682668
if (hw_pass_through && domain_type_is_si(domain))
26692669
ret = intel_pasid_setup_pass_through(iommu, domain,
26702670
dev, PASID_RID2PASID);
@@ -2674,7 +2674,7 @@ static struct dmar_domain *dmar_insert_one_dev_info(struct intel_iommu *iommu,
26742674
else
26752675
ret = intel_pasid_setup_second_level(iommu, domain,
26762676
dev, PASID_RID2PASID);
2677-
spin_unlock(&iommu->lock);
2677+
spin_unlock_irqrestore(&iommu->lock, flags);
26782678
if (ret) {
26792679
dev_err(dev, "Setup RID2PASID failed\n");
26802680
dmar_remove_one_dev_info(dev);

0 commit comments

Comments
 (0)