Skip to content

Commit 3ab6572

Browse files
lian-bojoergroedel
authored andcommitted
iommu: use the __iommu_attach_device() directly for deferred attach
Currently, because domain attach allows to be deferred from iommu driver to device driver, and when iommu initializes, the devices on the bus will be scanned and the default groups will be allocated. Due to the above changes, some devices could be added to the same group as below: [ 3.859417] pci 0000:01:00.0: Adding to iommu group 16 [ 3.864572] pci 0000:01:00.1: Adding to iommu group 16 [ 3.869738] pci 0000:02:00.0: Adding to iommu group 17 [ 3.874892] pci 0000:02:00.1: Adding to iommu group 17 But when attaching these devices, it doesn't allow that a group has more than one device, otherwise it will return an error. This conflicts with the deferred attaching. Unfortunately, it has two devices in the same group for my side, for example: [ 9.627014] iommu_group_device_count(): device name[0]:0000:01:00.0 [ 9.633545] iommu_group_device_count(): device name[1]:0000:01:00.1 ... [ 10.255609] iommu_group_device_count(): device name[0]:0000:02:00.0 [ 10.262144] iommu_group_device_count(): device name[1]:0000:02:00.1 Finally, which caused the failure of tg3 driver when tg3 driver calls the dma_alloc_coherent() to allocate coherent memory in the tg3_test_dma(). [ 9.660310] tg3 0000:01:00.0: DMA engine test failed, aborting [ 9.754085] tg3: probe of 0000:01:00.0 failed with error -12 [ 9.997512] tg3 0000:01:00.1: DMA engine test failed, aborting [ 10.043053] tg3: probe of 0000:01:00.1 failed with error -12 [ 10.288905] tg3 0000:02:00.0: DMA engine test failed, aborting [ 10.334070] tg3: probe of 0000:02:00.0 failed with error -12 [ 10.578303] tg3 0000:02:00.1: DMA engine test failed, aborting [ 10.622629] tg3: probe of 0000:02:00.1 failed with error -12 In addition, the similar situations also occur in other drivers such as the bnxt_en driver. That can be reproduced easily in kdump kernel when SME is active. Let's move the handling currently in iommu_dma_deferred_attach() into the iommu core code so that it can call the __iommu_attach_device() directly instead of the iommu_attach_device(). The external interface iommu_attach_device() is not suitable for handling this situation. Signed-off-by: Lianbo Jiang <[email protected]> Reviewed-by: Robin Murphy <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Joerg Roedel <[email protected]>
1 parent a8e8af3 commit 3ab6572

File tree

3 files changed

+14
-15
lines changed

3 files changed

+14
-15
lines changed

drivers/iommu/dma-iommu.c

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -380,18 +380,6 @@ static int iommu_dma_init_domain(struct iommu_domain *domain, dma_addr_t base,
380380
return iova_reserve_iommu_regions(dev, domain);
381381
}
382382

383-
static int iommu_dma_deferred_attach(struct device *dev,
384-
struct iommu_domain *domain)
385-
{
386-
const struct iommu_ops *ops = domain->ops;
387-
388-
if (unlikely(ops->is_attach_deferred &&
389-
ops->is_attach_deferred(domain, dev)))
390-
return iommu_attach_device(domain, dev);
391-
392-
return 0;
393-
}
394-
395383
/**
396384
* dma_info_to_prot - Translate DMA API directions and attributes to IOMMU API
397385
* page flags.
@@ -535,7 +523,7 @@ static dma_addr_t __iommu_dma_map(struct device *dev, phys_addr_t phys,
535523
dma_addr_t iova;
536524

537525
if (static_branch_unlikely(&iommu_deferred_attach_enabled) &&
538-
iommu_dma_deferred_attach(dev, domain))
526+
iommu_deferred_attach(dev, domain))
539527
return DMA_MAPPING_ERROR;
540528

541529
size = iova_align(iovad, size + iova_off);
@@ -694,7 +682,7 @@ static void *iommu_dma_alloc_remap(struct device *dev, size_t size,
694682
*dma_handle = DMA_MAPPING_ERROR;
695683

696684
if (static_branch_unlikely(&iommu_deferred_attach_enabled) &&
697-
iommu_dma_deferred_attach(dev, domain))
685+
iommu_deferred_attach(dev, domain))
698686
return NULL;
699687

700688
min_size = alloc_sizes & -alloc_sizes;
@@ -978,7 +966,7 @@ static int iommu_dma_map_sg(struct device *dev, struct scatterlist *sg,
978966
int i;
979967

980968
if (static_branch_unlikely(&iommu_deferred_attach_enabled) &&
981-
iommu_dma_deferred_attach(dev, domain))
969+
iommu_deferred_attach(dev, domain))
982970
return 0;
983971

984972
if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC))

drivers/iommu/iommu.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1980,6 +1980,16 @@ int iommu_attach_device(struct iommu_domain *domain, struct device *dev)
19801980
}
19811981
EXPORT_SYMBOL_GPL(iommu_attach_device);
19821982

1983+
int iommu_deferred_attach(struct device *dev, struct iommu_domain *domain)
1984+
{
1985+
const struct iommu_ops *ops = domain->ops;
1986+
1987+
if (ops->is_attach_deferred && ops->is_attach_deferred(domain, dev))
1988+
return __iommu_attach_device(domain, dev);
1989+
1990+
return 0;
1991+
}
1992+
19831993
/*
19841994
* Check flags and other user provided data for valid combinations. We also
19851995
* make sure no reserved fields or unused flags are set. This is to ensure

include/linux/iommu.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,7 @@ int iommu_device_sysfs_add(struct iommu_device *iommu,
376376
void iommu_device_sysfs_remove(struct iommu_device *iommu);
377377
int iommu_device_link(struct iommu_device *iommu, struct device *link);
378378
void iommu_device_unlink(struct iommu_device *iommu, struct device *link);
379+
int iommu_deferred_attach(struct device *dev, struct iommu_domain *domain);
379380

380381
static inline void __iommu_device_set_ops(struct iommu_device *iommu,
381382
const struct iommu_ops *ops)

0 commit comments

Comments
 (0)