summaryrefslogtreecommitdiffstats
path: root/include/rdma/uverbs_ioctl.h
diff options
context:
space:
mode:
authorMatan Barak <matanb@mellanox.com>2017-08-03 15:07:04 +0200
committerDoug Ledford <dledford@redhat.com>2017-08-31 14:35:13 +0200
commitd70724f149b107f8e4062320270d3d8b6713a1bb (patch)
tree8424166e2e28c3f99666db14f7afd20e290b1fa1 /include/rdma/uverbs_ioctl.h
parentIB/core: Export ioctl enum types to user-space (diff)
downloadlinux-d70724f149b107f8e4062320270d3d8b6713a1bb.tar.xz
linux-d70724f149b107f8e4062320270d3d8b6713a1bb.zip
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>
Diffstat (limited to 'include/rdma/uverbs_ioctl.h')
-rw-r--r--include/rdma/uverbs_ioctl.h46
1 files changed, 46 insertions, 0 deletions
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 @@
#include <rdma/uverbs_types.h>
#include <linux/uaccess.h>
#include <rdma/rdma_user_ioctl.h>
+#include <rdma/ib_user_ioctl_verbs.h>
/*
* =======================================
@@ -338,6 +339,51 @@ static inline bool uverbs_attr_is_valid(const struct uverbs_attr_bundle *attrs_b
idx & ~UVERBS_ID_NS_MASK);
}
+static inline const struct uverbs_attr *uverbs_attr_get(const struct uverbs_attr_bundle *attrs_bundle,
+ u16 idx)
+{
+ u16 idx_bucket = idx >> UVERBS_ID_NS_SHIFT;
+
+ if (!uverbs_attr_is_valid(attrs_bundle, idx))
+ return ERR_PTR(-ENOENT);
+
+ return &attrs_bundle->hash[idx_bucket].attrs[idx & ~UVERBS_ID_NS_MASK];
+}
+
+static inline int uverbs_copy_to(const struct uverbs_attr_bundle *attrs_bundle,
+ size_t idx, const void *from)
+{
+ const struct uverbs_attr *attr = uverbs_attr_get(attrs_bundle, idx);
+ u16 flags;
+
+ if (IS_ERR(attr))
+ return PTR_ERR(attr);
+
+ flags = attr->ptr_attr.flags | UVERBS_ATTR_F_VALID_OUTPUT;
+ return (!copy_to_user(attr->ptr_attr.ptr, from, attr->ptr_attr.len) &&
+ !put_user(flags, &attr->uattr->flags)) ? 0 : -EFAULT;
+}
+
+static inline int _uverbs_copy_from(void *to, size_t to_size,
+ const struct uverbs_attr_bundle *attrs_bundle,
+ size_t idx)
+{
+ const struct uverbs_attr *attr = uverbs_attr_get(attrs_bundle, idx);
+
+ if (IS_ERR(attr))
+ return PTR_ERR(attr);
+
+ if (to_size <= sizeof(((struct ib_uverbs_attr *)0)->data))
+ memcpy(to, &attr->ptr_attr.data, attr->ptr_attr.len);
+ else if (copy_from_user(to, attr->ptr_attr.ptr, attr->ptr_attr.len))
+ return -EFAULT;
+
+ return 0;
+}
+
+#define uverbs_copy_from(to, attrs_bundle, idx) \
+ _uverbs_copy_from(to, sizeof(*(to)), attrs_bundle, idx)
+
/* =================================================
* Definitions -> Specs infrastructure
* =================================================