aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatan Barak <matanb@mellanox.com>2017-08-03 09:07:04 -0400
committerDoug Ledford <dledford@redhat.com>2017-08-31 08:35:13 -0400
commitd70724f149b107f8e4062320270d3d8b6713a1bb (patch)
tree8424166e2e28c3f99666db14f7afd20e290b1fa1
parent64b19e1323e96c34af7ca90d1954e70890c7a98e (diff)
IB/core: Add legacy driver's user-data
In this phase, we don't want to change all the drivers to use flexible driver's specific attributes. Therefore, we add two default attributes: UHW_IN and UHW_OUT. These attributes are optional in some methods and they encode the driver specific command data. We add a function that extract this data and creates the legacy udata over it. Driver's data should start from UVERBS_UDATA_DRIVER_DATA_FLAG. This turns on the first bit of the namespace, indicating this attribute belongs to the driver's namespace. Signed-off-by: Matan Barak <matanb@mellanox.com> Reviewed-by: Yishai Hadas <yishaih@mellanox.com> Signed-off-by: Doug Ledford <dledford@redhat.com>
-rw-r--r--drivers/infiniband/core/uverbs_std_types.c40
-rw-r--r--include/rdma/uverbs_ioctl.h46
-rw-r--r--include/uapi/rdma/ib_user_ioctl_verbs.h10
3 files changed, 96 insertions, 0 deletions
diff --git a/drivers/infiniband/core/uverbs_std_types.c b/drivers/infiniband/core/uverbs_std_types.c
index 5f90978bda8d..db66c18857e4 100644
--- a/drivers/infiniband/core/uverbs_std_types.c
+++ b/drivers/infiniband/core/uverbs_std_types.c
@@ -209,6 +209,46 @@ static int uverbs_hot_unplug_completion_event_file(struct ib_uobject_file *uobj_
209 return 0; 209 return 0;
210}; 210};
211 211
212/*
213 * This spec is used in order to pass information to the hardware driver in a
214 * legacy way. Every verb that could get driver specific data should get this
215 * spec.
216 */
217static const struct uverbs_attr_def uverbs_uhw_compat_in =
218 UVERBS_ATTR_PTR_IN_SZ(UVERBS_UHW_IN, 0, UA_FLAGS(UVERBS_ATTR_SPEC_F_MIN_SZ));
219static const struct uverbs_attr_def uverbs_uhw_compat_out =
220 UVERBS_ATTR_PTR_OUT_SZ(UVERBS_UHW_OUT, 0, UA_FLAGS(UVERBS_ATTR_SPEC_F_MIN_SZ));
221
222static void create_udata(struct uverbs_attr_bundle *ctx,
223 struct ib_udata *udata)
224{
225 /*
226 * This is for ease of conversion. The purpose is to convert all drivers
227 * to use uverbs_attr_bundle instead of ib_udata.
228 * Assume attr == 0 is input and attr == 1 is output.
229 */
230 void __user *inbuf;
231 size_t inbuf_len = 0;
232 void __user *outbuf;
233 size_t outbuf_len = 0;
234 const struct uverbs_attr *uhw_in =
235 uverbs_attr_get(ctx, UVERBS_UHW_IN);
236 const struct uverbs_attr *uhw_out =
237 uverbs_attr_get(ctx, UVERBS_UHW_OUT);
238
239 if (!IS_ERR(uhw_in)) {
240 inbuf = uhw_in->ptr_attr.ptr;
241 inbuf_len = uhw_in->ptr_attr.len;
242 }
243
244 if (!IS_ERR(uhw_out)) {
245 outbuf = uhw_out->ptr_attr.ptr;
246 outbuf_len = uhw_out->ptr_attr.len;
247 }
248
249 INIT_UDATA_BUF_OR_NULL(udata, inbuf, outbuf, inbuf_len, outbuf_len);
250}
251
212DECLARE_UVERBS_OBJECT(uverbs_object_comp_channel, 252DECLARE_UVERBS_OBJECT(uverbs_object_comp_channel,
213 UVERBS_OBJECT_COMP_CHANNEL, 253 UVERBS_OBJECT_COMP_CHANNEL,
214 &UVERBS_TYPE_ALLOC_FD(0, 254 &UVERBS_TYPE_ALLOC_FD(0,
diff --git a/include/rdma/uverbs_ioctl.h b/include/rdma/uverbs_ioctl.h
index 9a8d217cdc1d..759afa0621ea 100644
--- a/include/rdma/uverbs_ioctl.h
+++ b/include/rdma/uverbs_ioctl.h
@@ -36,6 +36,7 @@
36#include <rdma/uverbs_types.h> 36#include <rdma/uverbs_types.h>
37#include <linux/uaccess.h> 37#include <linux/uaccess.h>
38#include <rdma/rdma_user_ioctl.h> 38#include <rdma/rdma_user_ioctl.h>
39#include <rdma/ib_user_ioctl_verbs.h>
39 40
40/* 41/*
41 * ======================================= 42 * =======================================
@@ -338,6 +339,51 @@ static inline bool uverbs_attr_is_valid(const struct uverbs_attr_bundle *attrs_b
338 idx & ~UVERBS_ID_NS_MASK); 339 idx & ~UVERBS_ID_NS_MASK);
339} 340}
340 341
342static inline const struct uverbs_attr *uverbs_attr_get(const struct uverbs_attr_bundle *attrs_bundle,
343 u16 idx)
344{
345 u16 idx_bucket = idx >> UVERBS_ID_NS_SHIFT;
346
347 if (!uverbs_attr_is_valid(attrs_bundle, idx))
348 return ERR_PTR(-ENOENT);
349
350 return &attrs_bundle->hash[idx_bucket].attrs[idx & ~UVERBS_ID_NS_MASK];
351}
352
353static inline int uverbs_copy_to(const struct uverbs_attr_bundle *attrs_bundle,
354 size_t idx, const void *from)
355{
356 const struct uverbs_attr *attr = uverbs_attr_get(attrs_bundle, idx);
357 u16 flags;
358
359 if (IS_ERR(attr))
360 return PTR_ERR(attr);
361
362 flags = attr->ptr_attr.flags | UVERBS_ATTR_F_VALID_OUTPUT;
363 return (!copy_to_user(attr->ptr_attr.ptr, from, attr->ptr_attr.len) &&
364 !put_user(flags, &attr->uattr->flags)) ? 0 : -EFAULT;
365}
366
367static inline int _uverbs_copy_from(void *to, size_t to_size,
368 const struct uverbs_attr_bundle *attrs_bundle,
369 size_t idx)
370{
371 const struct uverbs_attr *attr = uverbs_attr_get(attrs_bundle, idx);
372
373 if (IS_ERR(attr))
374 return PTR_ERR(attr);
375
376 if (to_size <= sizeof(((struct ib_uverbs_attr *)0)->data))
377 memcpy(to, &attr->ptr_attr.data, attr->ptr_attr.len);
378 else if (copy_from_user(to, attr->ptr_attr.ptr, attr->ptr_attr.len))
379 return -EFAULT;
380
381 return 0;
382}
383
384#define uverbs_copy_from(to, attrs_bundle, idx) \
385 _uverbs_copy_from(to, sizeof(*(to)), attrs_bundle, idx)
386
341/* ================================================= 387/* =================================================
342 * Definitions -> Specs infrastructure 388 * Definitions -> Specs infrastructure
343 * ================================================= 389 * =================================================
diff --git a/include/uapi/rdma/ib_user_ioctl_verbs.h b/include/uapi/rdma/ib_user_ioctl_verbs.h
index 78a2e5be4d6e..90f81eeca35b 100644
--- a/include/uapi/rdma/ib_user_ioctl_verbs.h
+++ b/include/uapi/rdma/ib_user_ioctl_verbs.h
@@ -33,6 +33,11 @@
33#ifndef IB_USER_IOCTL_VERBS_H 33#ifndef IB_USER_IOCTL_VERBS_H
34#define IB_USER_IOCTL_VERBS_H 34#define IB_USER_IOCTL_VERBS_H
35 35
36#include <rdma/rdma_user_ioctl.h>
37
38#define UVERBS_UDATA_DRIVER_DATA_NS 1
39#define UVERBS_UDATA_DRIVER_DATA_FLAG (1UL << UVERBS_ID_NS_SHIFT)
40
36enum uverbs_default_objects { 41enum uverbs_default_objects {
37 UVERBS_OBJECT_DEVICE, /* No instances of DEVICE are allowed */ 42 UVERBS_OBJECT_DEVICE, /* No instances of DEVICE are allowed */
38 UVERBS_OBJECT_PD, 43 UVERBS_OBJECT_PD,
@@ -50,5 +55,10 @@ enum uverbs_default_objects {
50 UVERBS_OBJECT_LAST, 55 UVERBS_OBJECT_LAST,
51}; 56};
52 57
58enum {
59 UVERBS_UHW_IN = UVERBS_UDATA_DRIVER_DATA_FLAG,
60 UVERBS_UHW_OUT,
61};
62
53#endif 63#endif
54 64