Skip to content

Commit 84b1cec

Browse files
hegdevasantjoergroedel
authored andcommitted
iommu/amd: Fix possible irq lock inversion dependency issue
LOCKDEP detector reported below warning: ---------------------------------------- [ 23.796949] ======================================================== [ 23.796950] WARNING: possible irq lock inversion dependency detected [ 23.796952] 6.8.0fix+ #811 Not tainted [ 23.796954] -------------------------------------------------------- [ 23.796954] kworker/0:1/8 just changed the state of lock: [ 23.796956] ff365325e084a9b8 (&domain->lock){..-.}-{3:3}, at: amd_iommu_flush_iotlb_all+0x1f/0x50 [ 23.796969] but this lock took another, SOFTIRQ-unsafe lock in the past: [ 23.796970] (pd_bitmap_lock){+.+.}-{3:3} [ 23.796972] and interrupts could create inverse lock ordering between them. [ 23.796973] other info that might help us debug this: [ 23.796974] Chain exists of: &domain->lock --> &dev_data->lock --> pd_bitmap_lock [ 23.796980] Possible interrupt unsafe locking scenario: [ 23.796981] CPU0 CPU1 [ 23.796982] ---- ---- [ 23.796983] lock(pd_bitmap_lock); [ 23.796985] local_irq_disable(); [ 23.796985] lock(&domain->lock); [ 23.796988] lock(&dev_data->lock); [ 23.796990] <Interrupt> [ 23.796991] lock(&domain->lock); Fix this issue by disabling interrupt when acquiring pd_bitmap_lock. Note that this is temporary fix. We have a plan to replace custom bitmap allocator with IDA allocator. Fixes: 87a6f1f ("iommu/amd: Introduce per-device domain ID to fix potential TLB aliasing issue") Reviewed-by: Suravee Suthikulpanit <[email protected]> Signed-off-by: Vasant Hegde <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Joerg Roedel <[email protected]>
1 parent fec50db commit 84b1cec

File tree

1 file changed

+7
-4
lines changed

1 file changed

+7
-4
lines changed

drivers/iommu/amd/iommu.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1692,26 +1692,29 @@ int amd_iommu_complete_ppr(struct pci_dev *pdev, u32 pasid,
16921692

16931693
static u16 domain_id_alloc(void)
16941694
{
1695+
unsigned long flags;
16951696
int id;
16961697

1697-
spin_lock(&pd_bitmap_lock);
1698+
spin_lock_irqsave(&pd_bitmap_lock, flags);
16981699
id = find_first_zero_bit(amd_iommu_pd_alloc_bitmap, MAX_DOMAIN_ID);
16991700
BUG_ON(id == 0);
17001701
if (id > 0 && id < MAX_DOMAIN_ID)
17011702
__set_bit(id, amd_iommu_pd_alloc_bitmap);
17021703
else
17031704
id = 0;
1704-
spin_unlock(&pd_bitmap_lock);
1705+
spin_unlock_irqrestore(&pd_bitmap_lock, flags);
17051706

17061707
return id;
17071708
}
17081709

17091710
static void domain_id_free(int id)
17101711
{
1711-
spin_lock(&pd_bitmap_lock);
1712+
unsigned long flags;
1713+
1714+
spin_lock_irqsave(&pd_bitmap_lock, flags);
17121715
if (id > 0 && id < MAX_DOMAIN_ID)
17131716
__clear_bit(id, amd_iommu_pd_alloc_bitmap);
1714-
spin_unlock(&pd_bitmap_lock);
1717+
spin_unlock_irqrestore(&pd_bitmap_lock, flags);
17151718
}
17161719

17171720
static void free_gcr3_tbl_level1(u64 *tbl)

0 commit comments

Comments
 (0)