IB/uverbs: Use inline data transfer for UHW_IN
authorJason Gunthorpe <jgg@mellanox.com>
Tue, 13 Feb 2018 10:18:30 +0000 (12:18 +0200)
committerJason Gunthorpe <jgg@mellanox.com>
Thu, 15 Feb 2018 21:59:44 +0000 (14:59 -0700)
The rule for the API is pointers less than 8 bytes are inlined into
the .data field of the attribute. Fix the creation of the driver udata
struct to follow this rule and point to the .data itself when the size
is less than 8 bytes.

Otherwise if the UHW struct is less than 8 bytes the driver will get
EFAULT during copy_from_user.

Signed-off-by: Leon Romanovsky <leon@kernel.org>
Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
drivers/infiniband/core/uverbs_std_types.c

index c6502c7b7c4666b6f1b8421574f0cf0ecaf65839..7b0e4d778d794bb2fd734cc5fd0e26a6a9d2f503 100644 (file)
@@ -234,8 +234,11 @@ static void create_udata(struct uverbs_attr_bundle *ctx,
                uverbs_attr_get(ctx, UVERBS_UHW_OUT);
 
        if (!IS_ERR(uhw_in)) {
-               udata->inbuf = uhw_in->ptr_attr.ptr;
                udata->inlen = uhw_in->ptr_attr.len;
+               if (uverbs_attr_ptr_is_inline(uhw_in))
+                       udata->inbuf = &uhw_in->uattr->data;
+               else
+                       udata->inbuf = uhw_in->ptr_attr.ptr;
        } else {
                udata->inbuf = NULL;
                udata->inlen = 0;