Skip to content

Commit 4a552f7

Browse files
jgunthorpejoergroedel
authored andcommitted
iommu/amd: Put list_add/del(dev_data) back under the domain->lock
The list domain->dev_list is protected by the domain->lock spinlock. Any iteration, addition or removal must be under the lock. Move the list_del() up into the critical section. pdom_is_sva_capable(), and destroy_gcr3_table() do not interact with the list element. Wrap the list_add() in a lock, it would make more sense if this was under the same critical section as adjusting the refcounts earlier, but that requires more complications. Fixes: d6b47de ("iommu/amd: Reduce domain lock scope in attach device path") Signed-off-by: Jason Gunthorpe <[email protected]> Reviewed-by: Vasant Hegde <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Joerg Roedel <[email protected]>
1 parent fac04ef commit 4a552f7

File tree

1 file changed

+4
-1
lines changed

1 file changed

+4
-1
lines changed

drivers/iommu/amd/iommu.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2073,6 +2073,7 @@ static int attach_device(struct device *dev,
20732073
struct iommu_dev_data *dev_data = dev_iommu_priv_get(dev);
20742074
struct amd_iommu *iommu = get_amd_iommu_from_dev_data(dev_data);
20752075
struct pci_dev *pdev;
2076+
unsigned long flags;
20762077
int ret = 0;
20772078

20782079
mutex_lock(&dev_data->mutex);
@@ -2113,7 +2114,9 @@ static int attach_device(struct device *dev,
21132114

21142115
/* Update data structures */
21152116
dev_data->domain = domain;
2117+
spin_lock_irqsave(&domain->lock, flags);
21162118
list_add(&dev_data->list, &domain->dev_list);
2119+
spin_unlock_irqrestore(&domain->lock, flags);
21172120

21182121
/* Update device table */
21192122
dev_update_dte(dev_data, true);
@@ -2160,6 +2163,7 @@ static void detach_device(struct device *dev)
21602163
/* Flush IOTLB and wait for the flushes to finish */
21612164
spin_lock_irqsave(&domain->lock, flags);
21622165
amd_iommu_domain_flush_all(domain);
2166+
list_del(&dev_data->list);
21632167
spin_unlock_irqrestore(&domain->lock, flags);
21642168

21652169
/* Clear GCR3 table */
@@ -2168,7 +2172,6 @@ static void detach_device(struct device *dev)
21682172

21692173
/* Update data structures */
21702174
dev_data->domain = NULL;
2171-
list_del(&dev_data->list);
21722175

21732176
/* decrease reference counters - needs to happen after the flushes */
21742177
pdom_detach_iommu(iommu, domain);

0 commit comments

Comments
 (0)