From 14badc323ed7153c24a0a9c3175e594aaf1366c9 Mon Sep 17 00:00:00 2001 From: Jason Gunthorpe Date: Tue, 3 Mar 2026 15:50:02 -0400 Subject: RDMA: Add ib_respond_udata() Wrap the common copy_to_user() pattern used in drivers and enhance it to zero pad as well. Include debug logging on failures. Link: https://patch.msgid.link/r/5-v3-bd56dd443069+49-bnxt_re_uapi_jgg@nvidia.com Tested-by: Sriharsha Basavapatna Acked-by: Sriharsha Basavapatna Signed-off-by: Jason Gunthorpe --- include/rdma/uverbs_ioctl.h | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) (limited to 'include/rdma') diff --git a/include/rdma/uverbs_ioctl.h b/include/rdma/uverbs_ioctl.h index a73016a977a1..38a11bfe1374 100644 --- a/include/rdma/uverbs_ioctl.h +++ b/include/rdma/uverbs_ioctl.h @@ -900,6 +900,7 @@ int uverbs_copy_to_struct_or_zero(const struct uverbs_attr_bundle *bundle, int _ib_copy_validate_udata_in(struct ib_udata *udata, void *req, size_t kernel_size, size_t minimum_size); +int _ib_respond_udata(struct ib_udata *udata, const void *src, size_t len); #else static inline int uverbs_get_flags64(u64 *to, const struct uverbs_attr_bundle *attrs_bundle, @@ -964,6 +965,11 @@ static inline int _ib_copy_validate_udata_in(struct ib_udata *udata, void *req, return -EINVAL; } +static inline int _ib_respond_udata(struct ib_udata *udata, const void *src, + size_t len) +{ + return -EINVAL; +} #endif #define uverbs_get_const_signed(_to, _attrs_bundle, _idx) \ @@ -1069,4 +1075,31 @@ int _ib_copy_validate_udata_cm_fail(struct ib_udata *udata, u64 req_cm, ret; \ }) +/** + * ib_respond_udata - Copy a driver data response to userspace + * @_udata: The system calls ib_udata struct + * @_rep: Kernel buffer containing the response driver data on the stack + * + * Copy driver data response structures back to userspace in a way that + * is forwards and backwards compatible. Longer kernel structs are truncated, + * userspace has made some kind of error if it needed the truncated information. + * Shorter structs are zero padded. + */ +#define ib_respond_udata(_udata, _rep) \ + _ib_respond_udata(_udata, &(_rep), sizeof(_rep)) + +/** + * ib_respond_empty_udata - Zero fill the response buffer to userspace + * @_udata: The system calls ib_udata struct + * + * Used when there is no driver response data to return. Provides forward + * compatability by zeroing any buffer the user may have provided. + */ +static inline int ib_respond_empty_udata(struct ib_udata *udata) +{ + if (udata && udata->outlen && clear_user(udata->outbuf, udata->outlen)) + return -EFAULT; + return 0; +} + #endif -- cgit v1.2.3