]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
RDMA/core: Move the _ib_copy_validate_udata* functions to ib_core_uverbs
authorJason Gunthorpe <jgg@nvidia.com>
Wed, 13 May 2026 17:33:23 +0000 (14:33 -0300)
committerJason Gunthorpe <jgg@nvidia.com>
Tue, 19 May 2026 22:32:48 +0000 (19:32 -0300)
It was incorrect to place them in uverbs_ioctl because that makes every
driver depends on ib_uverbs.ko, which is undesired. ib_core_uverbs.c is
for functions used by alot of drivers that are linked into ib_core
instead.

Fixes: 1de9287ece44 ("RDMA: Add ib_copy_validate_udata_in()")
Link: https://patch.msgid.link/r/1-v1-045258567bd6+9fe-ib_uverbs_support_ko_jgg@nvidia.com
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
drivers/infiniband/core/ib_core_uverbs.c
drivers/infiniband/core/uverbs.h
drivers/infiniband/core/uverbs_ioctl.c

index 1f7a5c119cc9c15e58ccd4c6d42419eea769d612..685030e0c60fd0e6a8d1e99df34afbdfbd773a88 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/dma-resv.h>
 #include "uverbs.h"
 #include "core_priv.h"
+#include "rdma_core.h"
 
 MODULE_IMPORT_NS("DMA_BUF");
 
@@ -416,3 +417,91 @@ struct ib_device *rdma_udata_to_dev(struct ib_udata *udata)
 }
 EXPORT_SYMBOL(rdma_udata_to_dev);
 
+#if IS_ENABLED(CONFIG_INFINIBAND_USER_ACCESS)
+uverbs_api_ioctl_handler_fn uverbs_get_handler_fn(struct ib_udata *udata)
+{
+       struct uverbs_attr_bundle *bundle =
+               rdma_udata_to_uverbs_attr_bundle(udata);
+       struct bundle_priv *pbundle =
+               container_of(&bundle->hdr, struct bundle_priv, bundle);
+
+       lockdep_assert_held(&bundle->ufile->device->disassociate_srcu);
+
+       return srcu_dereference(pbundle->method_elm->handler,
+                               &bundle->ufile->device->disassociate_srcu);
+}
+
+int _ib_copy_validate_udata_in(struct ib_udata *udata, void *req,
+                              size_t kernel_size, size_t minimum_size)
+{
+       int err;
+
+       if (udata->inlen < minimum_size) {
+               ibdev_dbg(
+                       rdma_udata_to_dev(udata),
+                       "System call driver input udata too small (%zu < %zu) for ioctl %ps called by %pSR\n",
+                       udata->inlen, minimum_size,
+                       uverbs_get_handler_fn(udata),
+                       __builtin_return_address(0));
+               return -EINVAL;
+       }
+
+       err = copy_struct_from_user(req, kernel_size, udata->inbuf,
+                                   udata->inlen);
+       if (err) {
+               if (err == -E2BIG) {
+                       ibdev_dbg(
+                               rdma_udata_to_dev(udata),
+                               "System call driver input udata not zero from %zu -> %zu for ioctl %ps called by %pSR\n",
+                               minimum_size, udata->inlen,
+                               uverbs_get_handler_fn(udata),
+                               __builtin_return_address(0));
+                       return -EOPNOTSUPP;
+               }
+               ibdev_dbg(
+                       rdma_udata_to_dev(udata),
+                       "System call driver input udata EFAULT for ioctl %ps called by %pSR\n",
+                       uverbs_get_handler_fn(udata),
+                       __builtin_return_address(0));
+               return err;
+       }
+       return 0;
+}
+EXPORT_SYMBOL(_ib_copy_validate_udata_in);
+
+int _ib_copy_validate_udata_cm_fail(struct ib_udata *udata, u64 req_cm,
+                                   u64 valid_cm)
+{
+       ibdev_dbg(
+               rdma_udata_to_dev(udata),
+               "System call driver input udata has unsupported comp_mask %llx & ~%llx = %llx for ioctl %ps called by %pSR\n",
+               req_cm, valid_cm, req_cm & ~valid_cm,
+               uverbs_get_handler_fn(udata), __builtin_return_address(0));
+       return -EOPNOTSUPP;
+}
+EXPORT_SYMBOL(_ib_copy_validate_udata_cm_fail);
+
+int _ib_respond_udata(struct ib_udata *udata, const void *src, size_t len)
+{
+       size_t copy_len;
+
+       /* 0 length copy_len is a NOP for copy_to_user() and doesn't fail. */
+       copy_len = min(len, udata->outlen);
+       if (copy_to_user(udata->outbuf, src, copy_len))
+               goto err_fault;
+       if (copy_len < udata->outlen) {
+               if (clear_user(udata->outbuf + copy_len,
+                              udata->outlen - copy_len))
+                       goto err_fault;
+       }
+       return 0;
+err_fault:
+       ibdev_dbg(
+               rdma_udata_to_dev(udata),
+               "System call driver out udata has EFAULT (%zu into %zu) for ioctl %ps called by %pSR\n",
+               len, udata->outlen, uverbs_get_handler_fn(udata),
+               __builtin_return_address(0));
+       return -EFAULT;
+}
+EXPORT_SYMBOL(_ib_respond_udata);
+#endif
index 6d4295277e0e5f37403ce79e87cb04558056bd6a..a74a2dff1301ed366704891351167d98bde0dcd8 100644 (file)
@@ -229,6 +229,41 @@ int uverbs_dealloc_mw(struct ib_mw *mw);
 void ib_uverbs_detach_umcast(struct ib_qp *qp,
                             struct ib_uqp_object *uobj);
 
+struct bundle_alloc_head {
+       struct_group_tagged(bundle_alloc_head_hdr, hdr,
+               struct bundle_alloc_head *next;
+       );
+       u8 data[];
+};
+
+struct bundle_priv {
+       /* Must be first */
+       struct bundle_alloc_head_hdr alloc_head;
+       struct bundle_alloc_head *allocated_mem;
+       size_t internal_avail;
+       size_t internal_used;
+
+       struct radix_tree_root *radix;
+       const struct uverbs_api_ioctl_method *method_elm;
+       void __rcu **radix_slots;
+       unsigned long radix_slots_len;
+       u32 method_key;
+
+       struct ib_uverbs_attr __user *user_attrs;
+       struct ib_uverbs_attr *uattrs;
+
+       DECLARE_BITMAP(uobj_finalize, UVERBS_API_ATTR_BKEY_LEN);
+       DECLARE_BITMAP(spec_finalize, UVERBS_API_ATTR_BKEY_LEN);
+       DECLARE_BITMAP(uobj_hw_obj_valid, UVERBS_API_ATTR_BKEY_LEN);
+
+       /*
+        * Must be last. bundle ends in a flex array which overlaps
+        * internal_buffer.
+        */
+       struct uverbs_attr_bundle_hdr bundle;
+       u64 internal_buffer[32];
+};
+
 long ib_uverbs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);
 
 struct ib_uverbs_flow_spec {
index b61af625e679b2cf112d0f3731499f84300f110f..33feb88d652b6a1bc396b2d8e3d03c88e0bdc379 100644 (file)
 #include "rdma_core.h"
 #include "uverbs.h"
 
-struct bundle_alloc_head {
-       struct_group_tagged(bundle_alloc_head_hdr, hdr,
-               struct bundle_alloc_head *next;
-       );
-       u8 data[];
-};
-
-struct bundle_priv {
-       /* Must be first */
-       struct bundle_alloc_head_hdr alloc_head;
-       struct bundle_alloc_head *allocated_mem;
-       size_t internal_avail;
-       size_t internal_used;
-
-       struct radix_tree_root *radix;
-       const struct uverbs_api_ioctl_method *method_elm;
-       void __rcu **radix_slots;
-       unsigned long radix_slots_len;
-       u32 method_key;
-
-       struct ib_uverbs_attr __user *user_attrs;
-       struct ib_uverbs_attr *uattrs;
-
-       DECLARE_BITMAP(uobj_finalize, UVERBS_API_ATTR_BKEY_LEN);
-       DECLARE_BITMAP(spec_finalize, UVERBS_API_ATTR_BKEY_LEN);
-       DECLARE_BITMAP(uobj_hw_obj_valid, UVERBS_API_ATTR_BKEY_LEN);
-
-       /*
-        * Must be last. bundle ends in a flex array which overlaps
-        * internal_buffer.
-        */
-       struct uverbs_attr_bundle_hdr bundle;
-       u64 internal_buffer[32];
-};
-
-uverbs_api_ioctl_handler_fn uverbs_get_handler_fn(struct ib_udata *udata)
-{
-       struct uverbs_attr_bundle *bundle =
-               rdma_udata_to_uverbs_attr_bundle(udata);
-       struct bundle_priv *pbundle =
-               container_of(&bundle->hdr, struct bundle_priv, bundle);
-
-       lockdep_assert_held(&bundle->ufile->device->disassociate_srcu);
-
-       return srcu_dereference(pbundle->method_elm->handler,
-                               &bundle->ufile->device->disassociate_srcu);
-}
-
 /*
  * Each method has an absolute minimum amount of memory it needs to allocate,
  * precompute that amount and determine if the onstack memory can be used or
@@ -860,77 +812,3 @@ void uverbs_finalize_uobj_create(const struct uverbs_attr_bundle *bundle,
                  pbundle->uobj_hw_obj_valid);
 }
 EXPORT_SYMBOL(uverbs_finalize_uobj_create);
-
-int _ib_copy_validate_udata_in(struct ib_udata *udata, void *req,
-                              size_t kernel_size, size_t minimum_size)
-{
-       int err;
-
-       if (udata->inlen < minimum_size) {
-               ibdev_dbg(
-                       rdma_udata_to_dev(udata),
-                       "System call driver input udata too small (%zu < %zu) for ioctl %ps called by %pSR\n",
-                       udata->inlen, minimum_size,
-                       uverbs_get_handler_fn(udata),
-                       __builtin_return_address(0));
-               return -EINVAL;
-       }
-
-       err = copy_struct_from_user(req, kernel_size, udata->inbuf,
-                                   udata->inlen);
-       if (err) {
-               if (err == -E2BIG) {
-                       ibdev_dbg(
-                               rdma_udata_to_dev(udata),
-                               "System call driver input udata not zero from %zu -> %zu for ioctl %ps called by %pSR\n",
-                               minimum_size, udata->inlen,
-                               uverbs_get_handler_fn(udata),
-                               __builtin_return_address(0));
-                       return -EOPNOTSUPP;
-               }
-               ibdev_dbg(
-                       rdma_udata_to_dev(udata),
-                       "System call driver input udata EFAULT for ioctl %ps called by %pSR\n",
-                       uverbs_get_handler_fn(udata),
-                       __builtin_return_address(0));
-               return err;
-       }
-       return 0;
-}
-EXPORT_SYMBOL(_ib_copy_validate_udata_in);
-
-int _ib_copy_validate_udata_cm_fail(struct ib_udata *udata, u64 req_cm,
-                                   u64 valid_cm)
-{
-       ibdev_dbg(
-               rdma_udata_to_dev(udata),
-               "System call driver input udata has unsupported comp_mask %llx & ~%llx = %llx for ioctl %ps called by %pSR\n",
-               req_cm, valid_cm, req_cm & ~valid_cm,
-               uverbs_get_handler_fn(udata), __builtin_return_address(0));
-       return -EOPNOTSUPP;
-}
-EXPORT_SYMBOL(_ib_copy_validate_udata_cm_fail);
-
-int _ib_respond_udata(struct ib_udata *udata, const void *src, size_t len)
-{
-       size_t copy_len;
-
-       /* 0 length copy_len is a NOP for copy_to_user() and doesn't fail. */
-       copy_len = min(len, udata->outlen);
-       if (copy_to_user(udata->outbuf, src, copy_len))
-               goto err_fault;
-       if (copy_len < udata->outlen) {
-               if (clear_user(udata->outbuf + copy_len,
-                              udata->outlen - copy_len))
-                       goto err_fault;
-       }
-       return 0;
-err_fault:
-       ibdev_dbg(
-               rdma_udata_to_dev(udata),
-               "System call driver out udata has EFAULT (%zu into %zu) for ioctl %ps called by %pSR\n",
-               len, udata->outlen, uverbs_get_handler_fn(udata),
-               __builtin_return_address(0));
-       return -EFAULT;
-}
-EXPORT_SYMBOL(_ib_respond_udata);