Skip to content

Commit 8bc5482

Browse files
Xiyu Yang via iommujoergroedel
authored andcommitted
iommu/amd: Convert from atomic_t to refcount_t on pasid_state->count
refcount_t type and corresponding API can protect refcounters from accidental underflow and overflow and further use-after-free situations. Signed-off-by: Xiyu Yang <[email protected]> Signed-off-by: Xin Tan <[email protected]> Reviewed-by: Suravee Suthikulpanit <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Joerg Roedel <[email protected]>
1 parent ff11764 commit 8bc5482

File tree

1 file changed

+7
-6
lines changed

1 file changed

+7
-6
lines changed

drivers/iommu/amd/iommu_v2.c

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
#define pr_fmt(fmt) "AMD-Vi: " fmt
88

9+
#include <linux/refcount.h>
910
#include <linux/mmu_notifier.h>
1011
#include <linux/amd-iommu.h>
1112
#include <linux/mm_types.h>
@@ -33,7 +34,7 @@ struct pri_queue {
3334

3435
struct pasid_state {
3536
struct list_head list; /* For global state-list */
36-
atomic_t count; /* Reference count */
37+
refcount_t count; /* Reference count */
3738
unsigned mmu_notifier_count; /* Counting nested mmu_notifier
3839
calls */
3940
struct mm_struct *mm; /* mm_struct for the faults */
@@ -242,7 +243,7 @@ static struct pasid_state *get_pasid_state(struct device_state *dev_state,
242243

243244
ret = *ptr;
244245
if (ret)
245-
atomic_inc(&ret->count);
246+
refcount_inc(&ret->count);
246247

247248
out_unlock:
248249
spin_unlock_irqrestore(&dev_state->lock, flags);
@@ -257,14 +258,14 @@ static void free_pasid_state(struct pasid_state *pasid_state)
257258

258259
static void put_pasid_state(struct pasid_state *pasid_state)
259260
{
260-
if (atomic_dec_and_test(&pasid_state->count))
261+
if (refcount_dec_and_test(&pasid_state->count))
261262
wake_up(&pasid_state->wq);
262263
}
263264

264265
static void put_pasid_state_wait(struct pasid_state *pasid_state)
265266
{
266-
atomic_dec(&pasid_state->count);
267-
wait_event(pasid_state->wq, !atomic_read(&pasid_state->count));
267+
refcount_dec(&pasid_state->count);
268+
wait_event(pasid_state->wq, !refcount_read(&pasid_state->count));
268269
free_pasid_state(pasid_state);
269270
}
270271

@@ -624,7 +625,7 @@ int amd_iommu_bind_pasid(struct pci_dev *pdev, u32 pasid,
624625
goto out;
625626

626627

627-
atomic_set(&pasid_state->count, 1);
628+
refcount_set(&pasid_state->count, 1);
628629
init_waitqueue_head(&pasid_state->wq);
629630
spin_lock_init(&pasid_state->lock);
630631

0 commit comments

Comments
 (0)