diff mbox series

[2/7] IB/uverbs: initialize context field in ib_udata

Message ID 20181007080820.2571-3-shamir.rabinovitch@oracle.com (mailing list archive)
State Superseded
Headers show
Series convey ib_ucontext via ib_udata | expand

Commit Message

Shamir Rabinovitch Oct. 7, 2018, 8:08 a.m. UTC
initialize the context field in ib_udata created from uverbs commands
and extended commands path.

Signed-off-by: Shamir Rabinovitch <shamir.rabinovitch@oracle.com>
---
 drivers/infiniband/core/uverbs.h      | 17 ++++++++------
 drivers/infiniband/core/uverbs_cmd.c  | 34 +++++++++++++--------------
 drivers/infiniband/core/uverbs_main.c |  6 +++--
 3 files changed, 31 insertions(+), 26 deletions(-)

Comments

Jason Gunthorpe Oct. 7, 2018, 7:30 p.m. UTC | #1
On Sun, Oct 07, 2018 at 11:08:15AM +0300, Shamir Rabinovitch wrote:
> initialize the context field in ib_udata created from uverbs commands
> and extended commands path.
> 
> Signed-off-by: Shamir Rabinovitch <shamir.rabinovitch@oracle.com>
>  drivers/infiniband/core/uverbs.h      | 17 ++++++++------
>  drivers/infiniband/core/uverbs_cmd.c  | 34 +++++++++++++--------------
>  drivers/infiniband/core/uverbs_main.c |  6 +++--
>  3 files changed, 31 insertions(+), 26 deletions(-)
> 
> diff --git a/drivers/infiniband/core/uverbs.h b/drivers/infiniband/core/uverbs.h
> index c97935a0c7c6..7c6c2c975125 100644
> +++ b/drivers/infiniband/core/uverbs.h
> @@ -55,23 +55,26 @@ static inline void
>  ib_uverbs_init_udata(struct ib_udata *udata,
>  		     const void __user *ibuf,
>  		     void __user *obuf,
> -		     size_t ilen, size_t olen)
> +		     size_t ilen, size_t olen,
> +		     struct ib_ucontext *context)
>  {
> -	udata->inbuf  = ibuf;
> -	udata->outbuf = obuf;
> -	udata->inlen  = ilen;
> -	udata->outlen = olen;
> +	udata->inbuf   = ibuf;
> +	udata->outbuf  = obuf;
> +	udata->inlen   = ilen;
> +	udata->outlen  = olen;
> +	udata->context = context;
>  }
>  
>  static inline void
>  ib_uverbs_init_udata_buf_or_null(struct ib_udata *udata,
>  				 const void __user *ibuf,
>  				 void __user *obuf,
> -				 size_t ilen, size_t olen)
> +				 size_t ilen, size_t olen,
> +				 struct ib_ucontext *context)
>  {
>  	ib_uverbs_init_udata(udata,
>  			     ilen ? ibuf : NULL, olen ? obuf : NULL,
> -			     ilen, olen);
> +			     ilen, olen, context);
>  }
>  
>  /*
> diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c
> index ef83813aefc2..c464ed65cbbb 100644
> +++ b/drivers/infiniband/core/uverbs_cmd.c
> @@ -100,7 +100,7 @@ ssize_t ib_uverbs_get_context(struct ib_uverbs_file *file,
>  	ib_uverbs_init_udata(&udata, buf + sizeof(cmd),
>  		   u64_to_user_ptr(cmd.response) + sizeof(resp),
>  		   in_len - sizeof(cmd) - sizeof(struct ib_uverbs_cmd_hdr),
> -		   out_len - sizeof(resp));
> +		   out_len - sizeof(resp), file->ucontext);

This accesses ignores this comment explaining the mandatory locking:

	/*
	 * ucontext must be accessed via ib_uverbs_get_ucontext() or with
	 * ucontext_lock held
	 */
	struct ib_ucontext		       *ucontext;

So, no to all of this patch.

In most cases ucontext must be set in the udata by the uobj_*
functions from the uobject they are handling, and never read from the
file.

The only exception might be the few uobject-less functions...

Jason
Shamir Rabinovitch Oct. 10, 2018, 7:47 a.m. UTC | #2
On Sun, Oct 07, 2018 at 01:30:45PM -0600, Jason Gunthorpe wrote:
> On Sun, Oct 07, 2018 at 11:08:15AM +0300, Shamir Rabinovitch wrote:
> > initialize the context field in ib_udata created from uverbs commands
> > and extended commands path.
> > 
> > Signed-off-by: Shamir Rabinovitch <shamir.rabinovitch@oracle.com>
> >  drivers/infiniband/core/uverbs.h      | 17 ++++++++------
> >  drivers/infiniband/core/uverbs_cmd.c  | 34 +++++++++++++--------------
> >  drivers/infiniband/core/uverbs_main.c |  6 +++--
> >  3 files changed, 31 insertions(+), 26 deletions(-)
> > 
> > diff --git a/drivers/infiniband/core/uverbs.h b/drivers/infiniband/core/uverbs.h
> > index c97935a0c7c6..7c6c2c975125 100644
> > +++ b/drivers/infiniband/core/uverbs.h
> > @@ -55,23 +55,26 @@ static inline void
> >  ib_uverbs_init_udata(struct ib_udata *udata,
> >  		     const void __user *ibuf,
> >  		     void __user *obuf,
> > -		     size_t ilen, size_t olen)
> > +		     size_t ilen, size_t olen,
> > +		     struct ib_ucontext *context)
> >  {
> > -	udata->inbuf  = ibuf;
> > -	udata->outbuf = obuf;
> > -	udata->inlen  = ilen;
> > -	udata->outlen = olen;
> > +	udata->inbuf   = ibuf;
> > +	udata->outbuf  = obuf;
> > +	udata->inlen   = ilen;
> > +	udata->outlen  = olen;
> > +	udata->context = context;
> >  }
> >  
> >  static inline void
> >  ib_uverbs_init_udata_buf_or_null(struct ib_udata *udata,
> >  				 const void __user *ibuf,
> >  				 void __user *obuf,
> > -				 size_t ilen, size_t olen)
> > +				 size_t ilen, size_t olen,
> > +				 struct ib_ucontext *context)
> >  {
> >  	ib_uverbs_init_udata(udata,
> >  			     ilen ? ibuf : NULL, olen ? obuf : NULL,
> > -			     ilen, olen);
> > +			     ilen, olen, context);
> >  }
> >  
> >  /*
> > diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c
> > index ef83813aefc2..c464ed65cbbb 100644
> > +++ b/drivers/infiniband/core/uverbs_cmd.c
> > @@ -100,7 +100,7 @@ ssize_t ib_uverbs_get_context(struct ib_uverbs_file *file,
> >  	ib_uverbs_init_udata(&udata, buf + sizeof(cmd),
> >  		   u64_to_user_ptr(cmd.response) + sizeof(resp),
> >  		   in_len - sizeof(cmd) - sizeof(struct ib_uverbs_cmd_hdr),
> > -		   out_len - sizeof(resp));
> > +		   out_len - sizeof(resp), file->ucontext);
> 
> This accesses ignores this comment explaining the mandatory locking:
> 
> 	/*
> 	 * ucontext must be accessed via ib_uverbs_get_ucontext() or with
> 	 * ucontext_lock held
> 	 */
> 	struct ib_ucontext		       *ucontext;
> 
> So, no to all of this patch.

I see that few lines above the call to ib_uverbs_init_udata the function
ib_uverbs_get_context grab the mentioned lock.

Have I missed anything?

> 
> In most cases ucontext must be set in the udata by the uobj_*
> functions from the uobject they are handling, and never read from the
> file.
> 
> The only exception might be the few uobject-less functions...

If the above is not an issue, do you still want me to modify this patch
to take the ucontext from the uobject fed in to uobj_get_obj_read?

> 
> Jason

Thanks
Jason Gunthorpe Oct. 10, 2018, 4:43 p.m. UTC | #3
On Wed, Oct 10, 2018 at 10:47:19AM +0300, Shamir Rabinovitch wrote:
> > > diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c
> > > index ef83813aefc2..c464ed65cbbb 100644
> > > +++ b/drivers/infiniband/core/uverbs_cmd.c
> > > @@ -100,7 +100,7 @@ ssize_t ib_uverbs_get_context(struct ib_uverbs_file *file,
> > >  	ib_uverbs_init_udata(&udata, buf + sizeof(cmd),
> > >  		   u64_to_user_ptr(cmd.response) + sizeof(resp),
> > >  		   in_len - sizeof(cmd) - sizeof(struct ib_uverbs_cmd_hdr),
> > > -		   out_len - sizeof(resp));
> > > +		   out_len - sizeof(resp), file->ucontext);
> > 
> > This accesses ignores this comment explaining the mandatory locking:
> > 
> > 	/*
> > 	 * ucontext must be accessed via ib_uverbs_get_ucontext() or with
> > 	 * ucontext_lock held
> > 	 */
> > 	struct ib_ucontext		       *ucontext;
> > 
> > So, no to all of this patch.
> 
> I see that few lines above the call to ib_uverbs_init_udata the function
> ib_uverbs_get_context grab the mentioned lock.

It is not a lock, it is reading the data

> Have I missed anything?

No handler can contain 'file->ucontext', must use the accessor or read
it from the uobject.

> > In most cases ucontext must be set in the udata by the uobj_*
> > functions from the uobject they are handling, and never read from the
> > file.
> > 
> > The only exception might be the few uobject-less functions...
> 
> If the above is not an issue, do you still want me to modify this patch
> to take the ucontext from the uobject fed in to uobj_get_obj_read?

It is an issue, and this is the best resolution..

Jason
diff mbox series

Patch

diff --git a/drivers/infiniband/core/uverbs.h b/drivers/infiniband/core/uverbs.h
index c97935a0c7c6..7c6c2c975125 100644
--- a/drivers/infiniband/core/uverbs.h
+++ b/drivers/infiniband/core/uverbs.h
@@ -55,23 +55,26 @@  static inline void
 ib_uverbs_init_udata(struct ib_udata *udata,
 		     const void __user *ibuf,
 		     void __user *obuf,
-		     size_t ilen, size_t olen)
+		     size_t ilen, size_t olen,
+		     struct ib_ucontext *context)
 {
-	udata->inbuf  = ibuf;
-	udata->outbuf = obuf;
-	udata->inlen  = ilen;
-	udata->outlen = olen;
+	udata->inbuf   = ibuf;
+	udata->outbuf  = obuf;
+	udata->inlen   = ilen;
+	udata->outlen  = olen;
+	udata->context = context;
 }
 
 static inline void
 ib_uverbs_init_udata_buf_or_null(struct ib_udata *udata,
 				 const void __user *ibuf,
 				 void __user *obuf,
-				 size_t ilen, size_t olen)
+				 size_t ilen, size_t olen,
+				 struct ib_ucontext *context)
 {
 	ib_uverbs_init_udata(udata,
 			     ilen ? ibuf : NULL, olen ? obuf : NULL,
-			     ilen, olen);
+			     ilen, olen, context);
 }
 
 /*
diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c
index ef83813aefc2..c464ed65cbbb 100644
--- a/drivers/infiniband/core/uverbs_cmd.c
+++ b/drivers/infiniband/core/uverbs_cmd.c
@@ -100,7 +100,7 @@  ssize_t ib_uverbs_get_context(struct ib_uverbs_file *file,
 	ib_uverbs_init_udata(&udata, buf + sizeof(cmd),
 		   u64_to_user_ptr(cmd.response) + sizeof(resp),
 		   in_len - sizeof(cmd) - sizeof(struct ib_uverbs_cmd_hdr),
-		   out_len - sizeof(resp));
+		   out_len - sizeof(resp), file->ucontext);
 
 	ret = ib_rdmacg_try_charge(&cg_obj, ib_dev, RDMACG_RESOURCE_HCA_HANDLE);
 	if (ret)
@@ -358,7 +358,7 @@  ssize_t ib_uverbs_alloc_pd(struct ib_uverbs_file *file,
 	ib_uverbs_init_udata(&udata, buf + sizeof(cmd),
 		   u64_to_user_ptr(cmd.response) + sizeof(resp),
                    in_len - sizeof(cmd) - sizeof(struct ib_uverbs_cmd_hdr),
-                   out_len - sizeof(resp));
+		   out_len - sizeof(resp), file->ucontext);
 
 	uobj = uobj_alloc(UVERBS_OBJECT_PD, file, &ib_dev);
 	if (IS_ERR(uobj))
@@ -519,7 +519,7 @@  ssize_t ib_uverbs_open_xrcd(struct ib_uverbs_file *file,
 	ib_uverbs_init_udata(&udata, buf + sizeof(cmd),
 		   u64_to_user_ptr(cmd.response) + sizeof(resp),
                    in_len - sizeof(cmd) - sizeof(struct ib_uverbs_cmd_hdr),
-                   out_len - sizeof(resp));
+		   out_len - sizeof(resp), file->ucontext);
 
 	mutex_lock(&file->device->xrcd_tree_mutex);
 
@@ -676,7 +676,7 @@  ssize_t ib_uverbs_reg_mr(struct ib_uverbs_file *file,
 	ib_uverbs_init_udata(&udata, buf + sizeof(cmd),
 		   u64_to_user_ptr(cmd.response) + sizeof(resp),
                    in_len - sizeof(cmd) - sizeof(struct ib_uverbs_cmd_hdr),
-                   out_len - sizeof(resp));
+		   out_len - sizeof(resp), file->ucontext);
 
 	if ((cmd.start & ~PAGE_MASK) != (cmd.hca_va & ~PAGE_MASK))
 		return -EINVAL;
@@ -769,7 +769,7 @@  ssize_t ib_uverbs_rereg_mr(struct ib_uverbs_file *file,
 	ib_uverbs_init_udata(&udata, buf + sizeof(cmd),
 		   u64_to_user_ptr(cmd.response) + sizeof(resp),
                    in_len - sizeof(cmd) - sizeof(struct ib_uverbs_cmd_hdr),
-                   out_len - sizeof(resp));
+		   out_len - sizeof(resp), file->ucontext);
 
 	if (cmd.flags & ~IB_MR_REREG_SUPPORTED || !cmd.flags)
 		return -EINVAL;
@@ -883,7 +883,7 @@  ssize_t ib_uverbs_alloc_mw(struct ib_uverbs_file *file,
 	ib_uverbs_init_udata(&udata, buf + sizeof(cmd),
 		   u64_to_user_ptr(cmd.response) + sizeof(resp),
 		   in_len - sizeof(cmd) - sizeof(struct ib_uverbs_cmd_hdr),
-		   out_len - sizeof(resp));
+		   out_len - sizeof(resp), file->ucontext);
 
 	mw = pd->device->alloc_mw(pd, cmd.mw_type, &udata);
 	if (IS_ERR(mw)) {
@@ -1095,12 +1095,12 @@  ssize_t ib_uverbs_create_cq(struct ib_uverbs_file *file,
 		return -EFAULT;
 
 	ib_uverbs_init_udata(&ucore, buf, u64_to_user_ptr(cmd.response),
-			     sizeof(cmd), sizeof(resp));
+			     sizeof(cmd), sizeof(resp), file->ucontext);
 
 	ib_uverbs_init_udata(&uhw, buf + sizeof(cmd),
 		   u64_to_user_ptr(cmd.response) + sizeof(resp),
 		   in_len - sizeof(cmd) - sizeof(struct ib_uverbs_cmd_hdr),
-		   out_len - sizeof(resp));
+		   out_len - sizeof(resp), file->ucontext);
 
 	memset(&cmd_ex, 0, sizeof(cmd_ex));
 	cmd_ex.user_handle = cmd.user_handle;
@@ -1179,7 +1179,7 @@  ssize_t ib_uverbs_resize_cq(struct ib_uverbs_file *file,
 	ib_uverbs_init_udata(&udata, buf + sizeof(cmd),
 		   u64_to_user_ptr(cmd.response) + sizeof(resp),
 		   in_len - sizeof(cmd) - sizeof(struct ib_uverbs_cmd_hdr),
-		   out_len - sizeof(resp));
+		   out_len - sizeof(resp), file->ucontext);
 
 	cq = uobj_get_obj_read(cq, UVERBS_OBJECT_CQ, cmd.cq_handle, file);
 	if (!cq)
@@ -1636,11 +1636,11 @@  ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file,
 		return -EFAULT;
 
 	ib_uverbs_init_udata(&ucore, buf, u64_to_user_ptr(cmd.response),
-		   sizeof(cmd), resp_size);
+		   sizeof(cmd), resp_size, file->ucontext);
 	ib_uverbs_init_udata(&uhw, buf + sizeof(cmd),
 		   u64_to_user_ptr(cmd.response) + resp_size,
 		   in_len - sizeof(cmd) - sizeof(struct ib_uverbs_cmd_hdr),
-		   out_len - resp_size);
+		   out_len - resp_size, file->ucontext);
 
 	memset(&cmd_ex, 0, sizeof(cmd_ex));
 	cmd_ex.user_handle = cmd.user_handle;
@@ -1737,7 +1737,7 @@  ssize_t ib_uverbs_open_qp(struct ib_uverbs_file *file,
 	ib_uverbs_init_udata(&udata, buf + sizeof(cmd),
 		   u64_to_user_ptr(cmd.response) + sizeof(resp),
 		   in_len - sizeof(cmd) - sizeof(struct ib_uverbs_cmd_hdr),
-		   out_len - sizeof(resp));
+		   out_len - sizeof(resp), file->ucontext);
 
 	obj = (struct ib_uqp_object *)uobj_alloc(UVERBS_OBJECT_QP, file,
 						 &ib_dev);
@@ -2089,7 +2089,7 @@  ssize_t ib_uverbs_modify_qp(struct ib_uverbs_file *file,
 
 	ib_uverbs_init_udata(&udata, buf + sizeof(cmd.base), NULL,
 		   in_len - sizeof(cmd.base) - sizeof(struct ib_uverbs_cmd_hdr),
-		   out_len);
+		   out_len, file->ucontext);
 
 	ret = modify_qp(file, &cmd, &udata);
 	if (ret)
@@ -2573,7 +2573,7 @@  ssize_t ib_uverbs_create_ah(struct ib_uverbs_file *file,
 	ib_uverbs_init_udata(&udata, buf + sizeof(cmd),
 		   u64_to_user_ptr(cmd.response) + sizeof(resp),
 		   in_len - sizeof(cmd) - sizeof(struct ib_uverbs_cmd_hdr),
-		   out_len - sizeof(resp));
+		   out_len - sizeof(resp), file->ucontext);
 
 	uobj = uobj_alloc(UVERBS_OBJECT_AH, file, &ib_dev);
 	if (IS_ERR(uobj))
@@ -3808,7 +3808,7 @@  ssize_t ib_uverbs_create_srq(struct ib_uverbs_file *file,
 	ib_uverbs_init_udata(&udata, buf + sizeof(cmd),
 		   u64_to_user_ptr(cmd.response) + sizeof(resp),
 		   in_len - sizeof(cmd) - sizeof(struct ib_uverbs_cmd_hdr),
-		   out_len - sizeof(resp));
+		   out_len - sizeof(resp), file->ucontext);
 
 	ret = __uverbs_create_xsrq(file, &xcmd, &udata);
 	if (ret)
@@ -3834,7 +3834,7 @@  ssize_t ib_uverbs_create_xsrq(struct ib_uverbs_file *file,
 	ib_uverbs_init_udata(&udata, buf + sizeof(cmd),
 		   u64_to_user_ptr(cmd.response) + sizeof(resp),
 		   in_len - sizeof(cmd) - sizeof(struct ib_uverbs_cmd_hdr),
-		   out_len - sizeof(resp));
+		   out_len - sizeof(resp), file->ucontext);
 
 	ret = __uverbs_create_xsrq(file, &cmd, &udata);
 	if (ret)
@@ -3857,7 +3857,7 @@  ssize_t ib_uverbs_modify_srq(struct ib_uverbs_file *file,
 		return -EFAULT;
 
 	ib_uverbs_init_udata(&udata, buf + sizeof cmd, NULL, in_len - sizeof cmd,
-		   out_len);
+		   out_len, file->ucontext);
 
 	srq = uobj_get_obj_read(srq, UVERBS_OBJECT_SRQ, cmd.srq_handle, file);
 	if (!srq)
diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c
index 12d8f8097574..50432f4eb36a 100644
--- a/drivers/infiniband/core/uverbs_main.c
+++ b/drivers/infiniband/core/uverbs_main.c
@@ -775,13 +775,15 @@  static ssize_t ib_uverbs_write(struct file *filp, const char __user *buf,
 
 		ib_uverbs_init_udata_buf_or_null(&ucore, buf,
 					u64_to_user_ptr(ex_hdr.response),
-					hdr.in_words * 8, hdr.out_words * 8);
+					hdr.in_words * 8, hdr.out_words * 8,
+					file->ucontext);
 
 		ib_uverbs_init_udata_buf_or_null(&uhw,
 					buf + ucore.inlen,
 					u64_to_user_ptr(ex_hdr.response) + ucore.outlen,
 					ex_hdr.provider_in_words * 8,
-					ex_hdr.provider_out_words * 8);
+					ex_hdr.provider_out_words * 8,
+					file->ucontext);
 
 		ret = uverbs_ex_cmd_table[command](file, &ucore, &uhw);
 		ret = (ret) ? : count;