git: 631e57d54c13 - main - mlx5ib: encode dynamic UAR mmap offsets in the reserved command range

From: Konstantin Belousov <kib_at_FreeBSD.org>
Date: Tue, 07 Jul 2026 11:30:06 UTC
The branch main has been updated by kib:

URL: https://cgit.FreeBSD.org/src/commit/?id=631e57d54c137e9393c47075db09a6c7fb84c6ed

commit 631e57d54c137e9393c47075db09a6c7fb84c6ed
Author:     Ariel Ehrenberg <aehrenberg@nvidia.com>
AuthorDate: 2026-06-08 10:55:47 +0000
Commit:     Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2026-07-07 11:25:06 +0000

    mlx5ib: encode dynamic UAR mmap offsets in the reserved command range
    
    The UAR ioctl handed user space a raw mmap offset, so the first dynamic
    UAR landed at page offset 0.  mlx5_ib_mmap() decodes offset 0 as the
    legacy regular-page command and routed the mapping through the old bfreg
    path, which rejects dynamic-UAR contexts, so mmap() failed with EINVAL
    and mlx5dv_devx_alloc_uar() returned NULL.
    
    Follow the upstream scheme: reserve the mmap command range [9, 255] for
    rdma_user_mmap entries and return command-encoded offsets, so the
    dynamic-UAR mappings decode to the intended mlx5_ib_mmap() path.
    
    Reviewed by:    kib
    Tested by:      Wafa Hamzah <wafah@nvidia.com>
    Sponsored by:   Nvidia networking
    MFC after:      1 month
---
 sys/dev/mlx5/mlx5_ib/mlx5_ib.h      | 11 +++++++++++
 sys/dev/mlx5/mlx5_ib/mlx5_ib_main.c | 24 +++++++++++++++++++++---
 2 files changed, 32 insertions(+), 3 deletions(-)

diff --git a/sys/dev/mlx5/mlx5_ib/mlx5_ib.h b/sys/dev/mlx5/mlx5_ib/mlx5_ib.h
index bbc7aa4a170a..c4775319ea47 100644
--- a/sys/dev/mlx5/mlx5_ib/mlx5_ib.h
+++ b/sys/dev/mlx5/mlx5_ib/mlx5_ib.h
@@ -66,6 +66,17 @@ enum {
 	MLX5_IB_MMAP_CMD_MASK	= 0xff,
 };
 
+/*
+ * Reserved mmap command range used to encode rdma_user_mmap entry page
+ * offsets (e.g. dynamically allocated UARs).  Keeping these above the legacy
+ * MLX5_IB_MMAP_* commands ensures mlx5_ib_mmap() routes them to the
+ * rdma_user_mmap offset handler instead of the legacy bfreg uar_mmap() path.
+ */
+enum {
+	MLX5_IB_MMAP_OFFSET_START	= 9,
+	MLX5_IB_MMAP_OFFSET_END		= 255,
+};
+
 enum {
 	MLX5_RES_SCAT_DATA32_CQE	= 0x1,
 	MLX5_RES_SCAT_DATA64_CQE	= 0x2,
diff --git a/sys/dev/mlx5/mlx5_ib/mlx5_ib_main.c b/sys/dev/mlx5/mlx5_ib/mlx5_ib_main.c
index daf5cb217001..66d8d511f2f0 100644
--- a/sys/dev/mlx5/mlx5_ib/mlx5_ib_main.c
+++ b/sys/dev/mlx5/mlx5_ib/mlx5_ib_main.c
@@ -1675,6 +1675,25 @@ static unsigned long mlx5_vma_to_pgoff(struct vm_area_struct *vma)
 	return (command << 16 | idx);
 }
 
+static u64 mlx5_entry_to_mmap_offset(struct mlx5_user_mmap_entry *entry)
+{
+	u64 cmd = (entry->rdma_entry.start_pgoff >> 16) & 0xFFFF;
+	u64 index = entry->rdma_entry.start_pgoff & 0xFFFF;
+
+	return (((index >> 8) << 16) | (cmd << MLX5_IB_MMAP_CMD_SHIFT) |
+		(index & 0xFF)) << PAGE_SHIFT;
+}
+
+static int mlx5_rdma_user_mmap_entry_insert(struct mlx5_ib_ucontext *c,
+					    struct mlx5_user_mmap_entry *entry,
+					    size_t length)
+{
+	return rdma_user_mmap_entry_insert_range(
+		&c->ibucontext, &entry->rdma_entry, length,
+		(MLX5_IB_MMAP_OFFSET_START << 16),
+		((MLX5_IB_MMAP_OFFSET_END << 16) + (1UL << 16) - 1));
+}
+
 static int mlx5_ib_mmap_offset(struct mlx5_ib_dev *dev,
 			       struct vm_area_struct *vma,
 			       struct ib_ucontext *ucontext)
@@ -3416,12 +3435,11 @@ static int UVERBS_HANDLER(MLX5_IB_METHOD_UAR_OBJ_ALLOC)(
 	entry->page_idx = uar_index;
 	entry->address = uar_index2pfn(dev, uar_index) << PAGE_SHIFT;
 
-	err = rdma_user_mmap_entry_insert(&c->ibucontext, &entry->rdma_entry,
-					  length);
+	err = mlx5_rdma_user_mmap_entry_insert(c, entry, length);
 	if (err)
 		goto err_entry;
 
-	mmap_offset = rdma_user_mmap_get_offset(&entry->rdma_entry);
+	mmap_offset = mlx5_entry_to_mmap_offset(entry);
 	err = uverbs_copy_to(attrs, MLX5_IB_ATTR_UAR_OBJ_ALLOC_MMAP_OFFSET,
 			     &mmap_offset, sizeof(mmap_offset));
 	if (err)