diff options
author | Xiyu Yang | 2021-07-19 14:00:53 +0800 |
---|---|---|
committer | Jason Gunthorpe | 2021-07-30 09:34:26 -0300 |
commit | a0293eb24936ff30e5a23f9438fd4ad1c4009dbf (patch) | |
tree | 0c8db95f2b80caf318a45141b7fbde54c78a1103 | |
parent | 62004871e1fa7f9a60797595c03477af5b5ec36f (diff) |
RDMA/hfi1: Convert from atomic_t to refcount_t on hfi1_devdata->user_refcount
refcount_t type and corresponding API can protect refcounters from
accidental underflow and overflow and further use-after-free situations.
Link: https://lore.kernel.org/r/1626674454-56075-1-git-send-email-xiyuyang19@fudan.edu.cn
Signed-off-by: Xiyu Yang <xiyuyang19@fudan.edu.cn>
Signed-off-by: Xin Tan <tanxin.ctf@gmail.com>
Tested-by: Josh Fisher <josh.fisher@cornelisnetworks.com>
Acked-by: Dennis Dalessandro <dennis.dalessandro@cornelisnetworks.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
-rw-r--r-- | drivers/infiniband/hw/hfi1/chip.c | 2 | ||||
-rw-r--r-- | drivers/infiniband/hw/hfi1/file_ops.c | 6 | ||||
-rw-r--r-- | drivers/infiniband/hw/hfi1/hfi.h | 3 | ||||
-rw-r--r-- | drivers/infiniband/hw/hfi1/init.c | 2 |
4 files changed, 7 insertions, 6 deletions
diff --git a/drivers/infiniband/hw/hfi1/chip.c b/drivers/infiniband/hw/hfi1/chip.c index c97544638367..50ffb8244625 100644 --- a/drivers/infiniband/hw/hfi1/chip.c +++ b/drivers/infiniband/hw/hfi1/chip.c @@ -15336,7 +15336,7 @@ int hfi1_init_dd(struct hfi1_devdata *dd) init_completion(&dd->user_comp); /* The user refcount starts with one to inidicate an active device */ - atomic_set(&dd->user_refcount, 1); + refcount_set(&dd->user_refcount, 1); goto bail; diff --git a/drivers/infiniband/hw/hfi1/file_ops.c b/drivers/infiniband/hw/hfi1/file_ops.c index 955c3637980e..6dbfb794c255 100644 --- a/drivers/infiniband/hw/hfi1/file_ops.c +++ b/drivers/infiniband/hw/hfi1/file_ops.c @@ -194,7 +194,7 @@ static int hfi1_file_open(struct inode *inode, struct file *fp) if (!((dd->flags & HFI1_PRESENT) && dd->kregbase1)) return -EINVAL; - if (!atomic_inc_not_zero(&dd->user_refcount)) + if (!refcount_inc_not_zero(&dd->user_refcount)) return -ENXIO; /* The real work is performed later in assign_ctxt() */ @@ -213,7 +213,7 @@ static int hfi1_file_open(struct inode *inode, struct file *fp) nomem: kfree(fd); fp->private_data = NULL; - if (atomic_dec_and_test(&dd->user_refcount)) + if (refcount_dec_and_test(&dd->user_refcount)) complete(&dd->user_comp); return -ENOMEM; } @@ -711,7 +711,7 @@ static int hfi1_file_close(struct inode *inode, struct file *fp) deallocate_ctxt(uctxt); done: - if (atomic_dec_and_test(&dd->user_refcount)) + if (refcount_dec_and_test(&dd->user_refcount)) complete(&dd->user_comp); cleanup_srcu_struct(&fdata->pq_srcu); diff --git a/drivers/infiniband/hw/hfi1/hfi.h b/drivers/infiniband/hw/hfi1/hfi.h index 31664f43c27f..6cf03d16a495 100644 --- a/drivers/infiniband/hw/hfi1/hfi.h +++ b/drivers/infiniband/hw/hfi1/hfi.h @@ -48,6 +48,7 @@ * */ +#include <linux/refcount.h> #include <linux/interrupt.h> #include <linux/pci.h> #include <linux/dma-mapping.h> @@ -1384,7 +1385,7 @@ struct hfi1_devdata { /* Number of verbs contexts which have disabled ASPM */ atomic_t aspm_disabled_cnt; /* Keeps track of user space clients */ - atomic_t user_refcount; + refcount_t user_refcount; /* Used to wait for outstanding user space clients before dev removal */ struct completion user_comp; diff --git a/drivers/infiniband/hw/hfi1/init.c b/drivers/infiniband/hw/hfi1/init.c index 34106e5be679..f37b157dbdb2 100644 --- a/drivers/infiniband/hw/hfi1/init.c +++ b/drivers/infiniband/hw/hfi1/init.c @@ -1747,7 +1747,7 @@ static void wait_for_clients(struct hfi1_devdata *dd) * Remove the device init value and complete the device if there is * no clients or wait for active clients to finish. */ - if (atomic_dec_and_test(&dd->user_refcount)) + if (refcount_dec_and_test(&dd->user_refcount)) complete(&dd->user_comp); wait_for_completion(&dd->user_comp); |