@@ -100,6 +100,7 @@ struct ib_uverbs_device {
struct mutex lists_mutex; /* protect lists */
struct list_head uverbs_file_list;
struct list_head uverbs_events_file_list;
+ struct uverbs_root_spec *specs_root;
};
struct ib_uverbs_event_queue {
@@ -49,6 +49,7 @@
#include <linux/uaccess.h>
#include <rdma/ib.h>
+#include <rdma/uverbs_std_types.h>
#include "uverbs.h"
#include "core_priv.h"
@@ -1109,6 +1110,18 @@ static void ib_uverbs_add_one(struct ib_device *device)
if (device_create_file(uverbs_dev->dev, &dev_attr_abi_version))
goto err_class;
+ if (!device->specs_root) {
+ const struct uverbs_object_tree_def *default_root[] = {
+ uverbs_default_get_objects()};
+
+ uverbs_dev->specs_root = uverbs_alloc_spec_tree(1,
+ default_root);
+ if (IS_ERR(uverbs_dev->specs_root))
+ goto err_class;
+
+ device->specs_root = uverbs_dev->specs_root;
+ }
+
ib_set_client_data(device, &uverbs_client, uverbs_dev);
return;
@@ -1240,6 +1253,11 @@ static void ib_uverbs_remove_one(struct ib_device *device, void *client_data)
ib_uverbs_comp_dev(uverbs_dev);
if (wait_clients)
wait_for_completion(&uverbs_dev->comp);
+ if (uverbs_dev->specs_root) {
+ uverbs_free_spec_tree(uverbs_dev->specs_root);
+ device->specs_root = NULL;
+ }
+
kobject_put(&uverbs_dev->kobj);
}
@@ -419,8 +419,20 @@ static inline int _uverbs_copy_from(void *to, size_t to_size,
* An object without any methods is considered invalid and will abort the
* function with -ENOENT error.
*/
+#if IS_ENABLED(CONFIG_INFINIBAND_USER_ACCESS)
struct uverbs_root_spec *uverbs_alloc_spec_tree(unsigned int num_trees,
const struct uverbs_object_tree_def **trees);
void uverbs_free_spec_tree(struct uverbs_root_spec *root);
+#else
+static inline struct uverbs_root_spec *uverbs_alloc_spec_tree(unsigned int num_trees,
+ const struct uverbs_object_tree_def **trees)
+{
+ return NULL;
+}
+
+static inline void uverbs_free_spec_tree(struct uverbs_root_spec *root)
+{
+}
+#endif
#endif
@@ -34,8 +34,10 @@
#define _UVERBS_STD_TYPES__
#include <rdma/uverbs_types.h>
+#include <rdma/uverbs_ioctl.h>
#include <rdma/ib_user_ioctl_verbs.h>
+#if IS_ENABLED(CONFIG_INFINIBAND_USER_ACCESS)
extern const struct uverbs_object_def uverbs_object_comp_channel;
extern const struct uverbs_object_def uverbs_object_cq;
extern const struct uverbs_object_def uverbs_object_qp;
@@ -50,6 +52,18 @@
extern const struct uverbs_object_def uverbs_object_xrcd;
extern const struct uverbs_object_def uverbs_object_device;
+extern const struct uverbs_object_tree_def uverbs_default_objects;
+static inline const struct uverbs_object_tree_def *uverbs_default_get_objects(void)
+{
+ return &uverbs_default_objects;
+}
+#else
+static inline const struct uverbs_object_tree_def *uverbs_default_get_objects(void)
+{
+ return NULL;
+}
+#endif
+
static inline struct ib_uobject *__uobj_get(const struct uverbs_obj_type *type,
bool write,
struct ib_ucontext *ucontext,