Skip to content

Commit f24b46e

Browse files
committed
Merge tag 'iommu-fixes-v6.10-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu
Pull iommu fixes from Joerg Roedel: "Core: - Make iommu-dma code recognize 'force_aperture' again - Fix for potential NULL-ptr dereference from iommu_sva_bind_device() return value AMD IOMMU fixes: - Fix lockdep splat for invalid wait context - Add feature bit check before enabling PPR - Make workqueue name fit into buffer - Fix memory leak in sysfs code" * tag 'iommu-fixes-v6.10-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu: iommu/amd: Fix Invalid wait context issue iommu/amd: Check EFR[EPHSup] bit before enabling PPR iommu/amd: Fix workqueue name iommu: Return right value in iommu_sva_bind_device() iommu/dma: Fix domain init iommu/amd: Fix sysfs leak in iommu init
2 parents e693c50 + 526606b commit f24b46e

File tree

6 files changed

+45
-50
lines changed

6 files changed

+45
-50
lines changed

drivers/iommu/amd/amd_iommu.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,8 @@ static inline int check_feature_gpt_level(void)
129129
static inline bool amd_iommu_gt_ppr_supported(void)
130130
{
131131
return (check_feature(FEATURE_GT) &&
132-
check_feature(FEATURE_PPR));
132+
check_feature(FEATURE_PPR) &&
133+
check_feature(FEATURE_EPHSUP));
133134
}
134135

135136
static inline u64 iommu_virt_to_phys(void *vaddr)

drivers/iommu/amd/init.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1626,8 +1626,17 @@ static void __init free_pci_segments(void)
16261626
}
16271627
}
16281628

1629+
static void __init free_sysfs(struct amd_iommu *iommu)
1630+
{
1631+
if (iommu->iommu.dev) {
1632+
iommu_device_unregister(&iommu->iommu);
1633+
iommu_device_sysfs_remove(&iommu->iommu);
1634+
}
1635+
}
1636+
16291637
static void __init free_iommu_one(struct amd_iommu *iommu)
16301638
{
1639+
free_sysfs(iommu);
16311640
free_cwwb_sem(iommu);
16321641
free_command_buffer(iommu);
16331642
free_event_buffer(iommu);

drivers/iommu/amd/iommu.c

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2032,7 +2032,6 @@ static int do_attach(struct iommu_dev_data *dev_data,
20322032
struct protection_domain *domain)
20332033
{
20342034
struct amd_iommu *iommu = get_amd_iommu_from_dev_data(dev_data);
2035-
struct pci_dev *pdev;
20362035
int ret = 0;
20372036

20382037
/* Update data structures */
@@ -2047,30 +2046,13 @@ static int do_attach(struct iommu_dev_data *dev_data,
20472046
domain->dev_iommu[iommu->index] += 1;
20482047
domain->dev_cnt += 1;
20492048

2050-
pdev = dev_is_pci(dev_data->dev) ? to_pci_dev(dev_data->dev) : NULL;
2049+
/* Setup GCR3 table */
20512050
if (pdom_is_sva_capable(domain)) {
20522051
ret = init_gcr3_table(dev_data, domain);
20532052
if (ret)
20542053
return ret;
2055-
2056-
if (pdev) {
2057-
pdev_enable_caps(pdev);
2058-
2059-
/*
2060-
* Device can continue to function even if IOPF
2061-
* enablement failed. Hence in error path just
2062-
* disable device PRI support.
2063-
*/
2064-
if (amd_iommu_iopf_add_device(iommu, dev_data))
2065-
pdev_disable_cap_pri(pdev);
2066-
}
2067-
} else if (pdev) {
2068-
pdev_enable_cap_ats(pdev);
20692054
}
20702055

2071-
/* Update device table */
2072-
amd_iommu_dev_update_dte(dev_data, true);
2073-
20742056
return ret;
20752057
}
20762058

@@ -2163,17 +2145,18 @@ static void detach_device(struct device *dev)
21632145

21642146
do_detach(dev_data);
21652147

2148+
out:
2149+
spin_unlock(&dev_data->lock);
2150+
2151+
spin_unlock_irqrestore(&domain->lock, flags);
2152+
21662153
/* Remove IOPF handler */
21672154
if (ppr)
21682155
amd_iommu_iopf_remove_device(iommu, dev_data);
21692156

21702157
if (dev_is_pci(dev))
21712158
pdev_disable_caps(to_pci_dev(dev));
21722159

2173-
out:
2174-
spin_unlock(&dev_data->lock);
2175-
2176-
spin_unlock_irqrestore(&domain->lock, flags);
21772160
}
21782161

21792162
static struct iommu_device *amd_iommu_probe_device(struct device *dev)
@@ -2485,6 +2468,7 @@ static int amd_iommu_attach_device(struct iommu_domain *dom,
24852468
struct iommu_dev_data *dev_data = dev_iommu_priv_get(dev);
24862469
struct protection_domain *domain = to_pdomain(dom);
24872470
struct amd_iommu *iommu = get_amd_iommu_from_dev(dev);
2471+
struct pci_dev *pdev;
24882472
int ret;
24892473

24902474
/*
@@ -2517,7 +2501,23 @@ static int amd_iommu_attach_device(struct iommu_domain *dom,
25172501
}
25182502
#endif
25192503

2520-
iommu_completion_wait(iommu);
2504+
pdev = dev_is_pci(dev_data->dev) ? to_pci_dev(dev_data->dev) : NULL;
2505+
if (pdev && pdom_is_sva_capable(domain)) {
2506+
pdev_enable_caps(pdev);
2507+
2508+
/*
2509+
* Device can continue to function even if IOPF
2510+
* enablement failed. Hence in error path just
2511+
* disable device PRI support.
2512+
*/
2513+
if (amd_iommu_iopf_add_device(iommu, dev_data))
2514+
pdev_disable_cap_pri(pdev);
2515+
} else if (pdev) {
2516+
pdev_enable_cap_ats(pdev);
2517+
}
2518+
2519+
/* Update device table */
2520+
amd_iommu_dev_update_dte(dev_data, true);
25212521

25222522
return ret;
25232523
}

drivers/iommu/amd/ppr.c

Lines changed: 5 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -222,8 +222,7 @@ int amd_iommu_iopf_init(struct amd_iommu *iommu)
222222
if (iommu->iopf_queue)
223223
return ret;
224224

225-
snprintf(iommu->iopfq_name, sizeof(iommu->iopfq_name),
226-
"amdiommu-%#x-iopfq",
225+
snprintf(iommu->iopfq_name, sizeof(iommu->iopfq_name), "amdvi-%#x",
227226
PCI_SEG_DEVID_TO_SBDF(iommu->pci_seg->id, iommu->devid));
228227

229228
iommu->iopf_queue = iopf_queue_alloc(iommu->iopfq_name);
@@ -249,40 +248,26 @@ void amd_iommu_page_response(struct device *dev, struct iopf_fault *evt,
249248
int amd_iommu_iopf_add_device(struct amd_iommu *iommu,
250249
struct iommu_dev_data *dev_data)
251250
{
252-
unsigned long flags;
253251
int ret = 0;
254252

255253
if (!dev_data->pri_enabled)
256254
return ret;
257255

258-
raw_spin_lock_irqsave(&iommu->lock, flags);
259-
260-
if (!iommu->iopf_queue) {
261-
ret = -EINVAL;
262-
goto out_unlock;
263-
}
256+
if (!iommu->iopf_queue)
257+
return -EINVAL;
264258

265259
ret = iopf_queue_add_device(iommu->iopf_queue, dev_data->dev);
266260
if (ret)
267-
goto out_unlock;
261+
return ret;
268262

269263
dev_data->ppr = true;
270-
271-
out_unlock:
272-
raw_spin_unlock_irqrestore(&iommu->lock, flags);
273-
return ret;
264+
return 0;
274265
}
275266

276267
/* Its assumed that caller has verified that device was added to iopf queue */
277268
void amd_iommu_iopf_remove_device(struct amd_iommu *iommu,
278269
struct iommu_dev_data *dev_data)
279270
{
280-
unsigned long flags;
281-
282-
raw_spin_lock_irqsave(&iommu->lock, flags);
283-
284271
iopf_queue_remove_device(iommu->iopf_queue, dev_data->dev);
285272
dev_data->ppr = false;
286-
287-
raw_spin_unlock_irqrestore(&iommu->lock, flags);
288273
}

drivers/iommu/dma-iommu.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -686,15 +686,15 @@ static int iommu_dma_init_domain(struct iommu_domain *domain, struct device *dev
686686

687687
/* Check the domain allows at least some access to the device... */
688688
if (map) {
689-
dma_addr_t base = dma_range_map_min(map);
690-
if (base > domain->geometry.aperture_end ||
689+
if (dma_range_map_min(map) > domain->geometry.aperture_end ||
691690
dma_range_map_max(map) < domain->geometry.aperture_start) {
692691
pr_warn("specified DMA range outside IOMMU capability\n");
693692
return -EFAULT;
694693
}
695-
/* ...then finally give it a kicking to make sure it fits */
696-
base_pfn = max(base, domain->geometry.aperture_start) >> order;
697694
}
695+
/* ...then finally give it a kicking to make sure it fits */
696+
base_pfn = max_t(unsigned long, base_pfn,
697+
domain->geometry.aperture_start >> order);
698698

699699
/* start_pfn is always nonzero for an already-initialised domain */
700700
mutex_lock(&cookie->mutex);

include/linux/iommu.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1533,7 +1533,7 @@ struct iommu_domain *iommu_sva_domain_alloc(struct device *dev,
15331533
static inline struct iommu_sva *
15341534
iommu_sva_bind_device(struct device *dev, struct mm_struct *mm)
15351535
{
1536-
return NULL;
1536+
return ERR_PTR(-ENODEV);
15371537
}
15381538

15391539
static inline void iommu_sva_unbind_device(struct iommu_sva *handle)

0 commit comments

Comments
 (0)