summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorJiri Pirko <jiri@nvidia.com>2026-05-29 15:42:59 +0200
committerJason Gunthorpe <jgg@nvidia.com>2026-05-29 20:19:57 -0300
commit3cfdff484d84f04716ae56063a8dac3773bd3f29 (patch)
tree5cea0a5fb2a22cc49c668831a4eafabc933d1bc8 /include
parent28fb701c642b8ff73e08fabef9265b508509d820 (diff)
RDMA/core: Introduce generic buffer descriptor infrastructure for umem
Introduce a per-attribute UVERBS_ATTR_UMEM model so each uverbs command's umem set is explicit in its UAPI definition. Add driver-facing wrapper helpers that pin a umem on demand from an attribute or a VA addr; the driver owns the returned umem and releases it from its destroy/error paths. Link: https://patch.msgid.link/r/20260529134312.2836341-4-jiri@resnulli.us Signed-off-by: Jiri Pirko <jiri@nvidia.com> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
Diffstat (limited to 'include')
-rw-r--r--include/rdma/ib_umem.h36
-rw-r--r--include/rdma/uverbs_ioctl.h30
-rw-r--r--include/uapi/rdma/ib_user_ioctl_verbs.h27
3 files changed, 93 insertions, 0 deletions
diff --git a/include/rdma/ib_umem.h b/include/rdma/ib_umem.h
index 25e90766892e..0f373679ea81 100644
--- a/include/rdma/ib_umem.h
+++ b/include/rdma/ib_umem.h
@@ -73,10 +73,26 @@ static inline size_t ib_umem_num_pages(struct ib_umem *umem)
{
return ib_umem_num_dma_blocks(umem, PAGE_SIZE);
}
+
+struct ib_udata;
+struct ib_uverbs_buffer_desc;
+struct uverbs_attr_bundle;
+
#ifdef CONFIG_INFINIBAND_USER_MEM
+struct ib_umem *ib_umem_get_desc(struct ib_device *device,
+ const struct ib_uverbs_buffer_desc *desc,
+ int access);
struct ib_umem *ib_umem_get_va(struct ib_device *device, unsigned long addr,
size_t size, int access);
+struct ib_umem *ib_umem_get_attr(struct ib_device *device,
+ const struct uverbs_attr_bundle *attrs,
+ u16 attr_id, size_t size, int access);
+struct ib_umem *ib_umem_get_attr_or_va(struct ib_device *device,
+ const struct uverbs_attr_bundle *attrs,
+ u16 attr_id, u64 addr, size_t size,
+ int access);
+
void ib_umem_release(struct ib_umem *umem);
int ib_umem_copy_from(void *dst, struct ib_umem *umem, size_t offset,
size_t length);
@@ -160,12 +176,32 @@ void ib_umem_dmabuf_revoke(struct ib_umem_dmabuf *umem_dmabuf);
#include <linux/err.h>
+static inline struct ib_umem *
+ib_umem_get_desc(struct ib_device *device,
+ const struct ib_uverbs_buffer_desc *desc, int access)
+{
+ return ERR_PTR(-EOPNOTSUPP);
+}
static inline struct ib_umem *ib_umem_get_va(struct ib_device *device,
unsigned long addr, size_t size,
int access)
{
return ERR_PTR(-EOPNOTSUPP);
}
+static inline struct ib_umem *
+ib_umem_get_attr(struct ib_device *device,
+ const struct uverbs_attr_bundle *attrs, u16 attr_id,
+ size_t size, int access)
+{
+ return ERR_PTR(-EOPNOTSUPP);
+}
+static inline struct ib_umem *
+ib_umem_get_attr_or_va(struct ib_device *device,
+ const struct uverbs_attr_bundle *attrs, u16 attr_id,
+ u64 addr, size_t size, int access)
+{
+ return ERR_PTR(-EOPNOTSUPP);
+}
static inline void ib_umem_release(struct ib_umem *umem) { }
static inline int ib_umem_copy_from(void *dst, struct ib_umem *umem, size_t offset,
size_t length) {
diff --git a/include/rdma/uverbs_ioctl.h b/include/rdma/uverbs_ioctl.h
index 9d7575d999e1..24fd36213023 100644
--- a/include/rdma/uverbs_ioctl.h
+++ b/include/rdma/uverbs_ioctl.h
@@ -590,6 +590,28 @@ struct uapi_definition {
UA_OPTIONAL, \
.is_udata = 1)
+/*
+ * Per-attribute UMEM descriptor. The payload is a single
+ * struct ib_uverbs_buffer_desc identifying a memory region backed by
+ * dma-buf or user virtual address. _access selects UA_OPTIONAL or
+ * UA_MANDATORY. Drivers obtain a umem from the attribute via the
+ * ib_umem_get_*() wrapper helpers.
+ */
+#define UVERBS_ATTR_UMEM(_attr_id, _access) \
+ UVERBS_ATTR_PTR_IN(_attr_id, \
+ UVERBS_ATTR_TYPE(struct ib_uverbs_buffer_desc), \
+ _access)
+
+/*
+ * Bit masks of the @flags / @optional_flags fields of struct
+ * ib_uverbs_buffer_desc that the kernel understands. @flags is strict:
+ * any bit outside the known mask makes the call fail with -EINVAL.
+ * @optional_flags is advisory: bits outside the known mask are silently
+ * dropped. Both masks are extended as new bits are introduced.
+ */
+#define IB_UVERBS_BUFFER_DESC_FLAGS_KNOWN_MASK 0U
+#define IB_UVERBS_BUFFER_DESC_OPTIONAL_FLAGS_KNOWN_MASK 0U
+
/* =================================================
* Parsing infrastructure
* =================================================
@@ -862,6 +884,8 @@ int uverbs_get_flags32(u32 *to, const struct uverbs_attr_bundle *attrs_bundle,
size_t idx, u64 allowed_bits);
int uverbs_copy_to(const struct uverbs_attr_bundle *attrs_bundle, size_t idx,
const void *from, size_t size);
+int uverbs_get_buffer_desc(const struct uverbs_attr_bundle *attrs_bundle,
+ u16 attr_id, struct ib_uverbs_buffer_desc *desc);
__malloc void *_uverbs_alloc(struct uverbs_attr_bundle *bundle, size_t size,
gfp_t flags);
@@ -920,6 +944,12 @@ static inline int uverbs_copy_to(const struct uverbs_attr_bundle *attrs_bundle,
{
return -EINVAL;
}
+static inline int
+uverbs_get_buffer_desc(const struct uverbs_attr_bundle *attrs_bundle,
+ u16 attr_id, struct ib_uverbs_buffer_desc *desc)
+{
+ return -EINVAL;
+}
static inline __malloc void *uverbs_alloc(struct uverbs_attr_bundle *bundle,
size_t size)
{
diff --git a/include/uapi/rdma/ib_user_ioctl_verbs.h b/include/uapi/rdma/ib_user_ioctl_verbs.h
index 90c5cd8e7753..51030c27d479 100644
--- a/include/uapi/rdma/ib_user_ioctl_verbs.h
+++ b/include/uapi/rdma/ib_user_ioctl_verbs.h
@@ -273,4 +273,31 @@ struct ib_uverbs_gid_entry {
__u32 netdev_ifindex; /* It is 0 if there is no netdev associated with it */
};
+enum ib_uverbs_buffer_type {
+ IB_UVERBS_BUFFER_TYPE_DMABUF,
+ IB_UVERBS_BUFFER_TYPE_VA,
+};
+
+/*
+ * Describes a single buffer backed by dma-buf or user virtual address.
+ * Used as the payload of a per-attribute UVERBS_ATTR_UMEM-typed attribute.
+ *
+ * @type: buffer type from enum ib_uverbs_buffer_type
+ * @fd: dma-buf file descriptor (valid for IB_UVERBS_BUFFER_TYPE_DMABUF)
+ * @flags: required flags; the kernel rejects the call with -EINVAL if any
+ * bit is not understood. No bits are defined yet.
+ * @optional_flags: advisory flags; bits the kernel does not understand are
+ * silently ignored. No bits are defined yet.
+ * @addr: offset within dma-buf, or user virtual address for VA
+ * @length: buffer length in bytes
+ */
+struct ib_uverbs_buffer_desc {
+ __u32 type;
+ __s32 fd;
+ __u32 flags;
+ __u32 optional_flags;
+ __aligned_u64 addr;
+ __aligned_u64 length;
+};
+
#endif