diff options
author | Michael J. Ruhl <michael.j.ruhl@intel.com> | 2017-09-26 07:04:29 -0700 |
---|---|---|
committer | Doug Ledford <dledford@redhat.com> | 2017-09-29 11:08:06 -0400 |
commit | 8a41da09e6189598fea2750e64c620cf83f22aba (patch) | |
tree | cc1797fba2ddee7034cdcf405f75ea9af6649c73 /drivers/infiniband/hw/hfi1/file_ops.c | |
parent | 3920eef7a7e0cd90364944e6b3b9be3f9e73e4cc (diff) | |
download | linux-stable-8a41da09e6189598fea2750e64c620cf83f22aba.tar.gz linux-stable-8a41da09e6189598fea2750e64c620cf83f22aba.tar.bz2 linux-stable-8a41da09e6189598fea2750e64c620cf83f22aba.zip |
IB/hfi1: Refactor hfi_user_exp_rcv_invalid() IOCTLs
The IOCTL is a bit unwieldy. Refactor to a common pattern.
Refactor _TID_INVAL_READ IOCTLs.
Reviewed-by: Ira Weiny <ira.weiny@intel.com>
Signed-off-by: Michael J. Ruhl <michael.j.ruhl@intel.com>
Signed-off-by: Dennis Dalessandro <dennis.dalessandro@intel.com>
Signed-off-by: Doug Ledford <dledford@redhat.com>
Diffstat (limited to 'drivers/infiniband/hw/hfi1/file_ops.c')
-rw-r--r-- | drivers/infiniband/hw/hfi1/file_ops.c | 54 |
1 files changed, 40 insertions, 14 deletions
diff --git a/drivers/infiniband/hw/hfi1/file_ops.c b/drivers/infiniband/hw/hfi1/file_ops.c index aecd37132f6c..e898991655d4 100644 --- a/drivers/infiniband/hw/hfi1/file_ops.c +++ b/drivers/infiniband/hw/hfi1/file_ops.c @@ -90,6 +90,8 @@ static int user_exp_rcv_setup(struct hfi1_filedata *fd, unsigned long arg, u32 len); static int user_exp_rcv_clear(struct hfi1_filedata *fd, unsigned long arg, u32 len); +static int user_exp_rcv_invalid(struct hfi1_filedata *fd, unsigned long arg, + u32 len); static int setup_base_ctxt(struct hfi1_filedata *fd, struct hfi1_ctxtdata *uctxt); static int setup_subctxt(struct hfi1_ctxtdata *uctxt); @@ -223,9 +225,7 @@ static long hfi1_file_ioctl(struct file *fp, unsigned int cmd, { struct hfi1_filedata *fd = fp->private_data; struct hfi1_ctxtdata *uctxt = fd->uctxt; - struct hfi1_tid_info tinfo; int ret = 0; - unsigned long addr; int uval = 0; unsigned long ul_uval = 0; u16 uval16 = 0; @@ -263,18 +263,7 @@ static long hfi1_file_ioctl(struct file *fp, unsigned int cmd, break; case HFI1_IOCTL_TID_INVAL_READ: - if (copy_from_user(&tinfo, - (struct hfi11_tid_info __user *)arg, - sizeof(tinfo))) - return -EFAULT; - - ret = hfi1_user_exp_rcv_invalid(fd, &tinfo); - if (ret) - break; - addr = arg + offsetof(struct hfi1_tid_info, tidcnt); - if (copy_to_user((void __user *)addr, &tinfo.tidcnt, - sizeof(tinfo.tidcnt))) - ret = -EFAULT; + ret = user_exp_rcv_invalid(fd, arg, _IOC_SIZE(cmd)); break; case HFI1_IOCTL_RECV_CTRL: @@ -1466,6 +1455,43 @@ static int user_exp_rcv_clear(struct hfi1_filedata *fd, unsigned long arg, return ret; } +/** + * user_exp_rcv_invalid - Invalidate the given tid rcv list + * @fd: file data of the current driver instance + * @arg: ioctl argumnent for user space information + * @len: length of data structure associated with ioctl command + * + * Wrapper to validate ioctl information before doing _rcv_invalid. + * + */ +static int user_exp_rcv_invalid(struct hfi1_filedata *fd, unsigned long arg, + u32 len) +{ + int ret; + unsigned long addr; + struct hfi1_tid_info tinfo; + + if (sizeof(tinfo) != len) + return -EINVAL; + + if (!fd->invalid_tids) + return -EINVAL; + + if (copy_from_user(&tinfo, (void __user *)arg, (sizeof(tinfo)))) + return -EFAULT; + + ret = hfi1_user_exp_rcv_invalid(fd, &tinfo); + if (ret) + return ret; + + addr = arg + offsetof(struct hfi1_tid_info, tidcnt); + if (copy_to_user((void __user *)addr, &tinfo.tidcnt, + sizeof(tinfo.tidcnt))) + ret = -EFAULT; + + return ret; +} + static unsigned int poll_urgent(struct file *fp, struct poll_table_struct *pt) { |