]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
RDMA/irdma: Do not directly rely on IB_PD_UNSAFE_GLOBAL_RKEY
authorJacob Moroni <jmoroni@google.com>
Tue, 25 Nov 2025 02:53:47 +0000 (20:53 -0600)
committerLeon Romanovsky <leon@kernel.org>
Wed, 26 Nov 2025 07:26:05 +0000 (02:26 -0500)
The HW disables bounds checking for MRs with a length of zero, so
the driver will only allow a zero length MR if the "all_memory"
flag is set, and this flag is only set if IB_PD_UNSAFE_GLOBAL_RKEY
is set for the PD.

This means that the "get_dma_mr" method will currently fail unless
the IB_PD_UNSAFE_GLOBAL_RKEY flag is set. This has not been an issue
because the "get_dma_mr" method is only ever invoked if the device
does not support the local DMA key or if IB_PD_UNSAFE_GLOBAL_RKEY
is set, and so far, all IRDMA HW supports the local DMA lkey.

However, some new HW does not support the local DMA lkey, so the
"get_dma_mr" method needs to work without IB_PD_UNSAFE_GLOBAL_RKEY
being set.

To support HW that does not allow the local DMA lkey, the logic has
been changed to pass an explicit flag to indicate when a dma_mr is
being created so that the zero length will be allowed.

Also, the "all_memory" flag has been forced to false for normal MR
allocation since these MRs are never supposed to provide global
unsafe rkey semantics anyway; only the MR created with "get_dma_mr"
should support this.

Fixes: bb6d73d9add6 ("RDMA/irdma: Prevent zero-length STAG registration")
Signed-off-by: Jacob Moroni <jmoroni@google.com>
Signed-off-by: Tatyana Nikolova <tatyana.e.nikolova@intel.com>
Link: https://patch.msgid.link/20251125025350.180-7-tatyana.e.nikolova@intel.com
Signed-off-by: Leon Romanovsky <leon@kernel.org>
drivers/infiniband/hw/irdma/cm.c
drivers/infiniband/hw/irdma/main.h
drivers/infiniband/hw/irdma/verbs.c
drivers/infiniband/hw/irdma/verbs.h

index c6a0a661d6e7eeeeab212fc6e435a964a9ed7731..f4f4f92ba63aca5cae77a13c8677f36a2869d3c4 100644 (file)
@@ -3710,7 +3710,7 @@ int irdma_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
        iwpd = iwqp->iwpd;
        tagged_offset = (uintptr_t)iwqp->ietf_mem.va;
        ibmr = irdma_reg_phys_mr(&iwpd->ibpd, iwqp->ietf_mem.pa, buf_len,
-                                IB_ACCESS_LOCAL_WRITE, &tagged_offset);
+                                IB_ACCESS_LOCAL_WRITE, &tagged_offset, false);
        if (IS_ERR(ibmr)) {
                ret = -ENOMEM;
                goto error;
index f22b1ee20fcc41f81ce539f94b9a4b6987fcfffd..baab61e424a267cc52b5e5e0eee25a3568050ea1 100644 (file)
@@ -556,7 +556,7 @@ void irdma_copy_ip_htonl(__be32 *dst, u32 *src);
 u16 irdma_get_vlan_ipv4(u32 *addr);
 void irdma_get_vlan_mac_ipv6(u32 *addr, u16 *vlan_id, u8 *mac);
 struct ib_mr *irdma_reg_phys_mr(struct ib_pd *ib_pd, u64 addr, u64 size,
-                               int acc, u64 *iova_start);
+                               int acc, u64 *iova_start, bool dma_mr);
 int irdma_upload_qp_context(struct irdma_qp *iwqp, bool freeze, bool raw);
 void irdma_cqp_ce_handler(struct irdma_pci_f *rf, struct irdma_sc_cq *cq);
 int irdma_ah_cqp_op(struct irdma_pci_f *rf, struct irdma_sc_ah *sc_ah, u8 cmd,
index 1fbc3592e13d27ca3bad869d86ccbd31f793aff2..bfbfde16bcb985fe2b73f1408f9a817af96ac04b 100644 (file)
@@ -3116,7 +3116,6 @@ static int irdma_hw_alloc_stag(struct irdma_device *iwdev,
        info->stag_idx = iwmr->stag >> IRDMA_CQPSQ_STAG_IDX_S;
        info->pd_id = iwpd->sc_pd.pd_id;
        info->total_len = iwmr->len;
-       info->all_memory = pd->flags & IB_PD_UNSAFE_GLOBAL_RKEY;
        info->remote_access = true;
        cqp_info->cqp_cmd = IRDMA_OP_ALLOC_STAG;
        cqp_info->post_sq = 1;
@@ -3127,7 +3126,7 @@ static int irdma_hw_alloc_stag(struct irdma_device *iwdev,
        if (status)
                return status;
 
-       iwmr->is_hwreg = 1;
+       iwmr->is_hwreg = true;
        return 0;
 }
 
@@ -3270,7 +3269,7 @@ static int irdma_hwreg_mr(struct irdma_device *iwdev, struct irdma_mr *iwmr,
        if (iwdev->rf->sc_dev.hw_attrs.uk_attrs.feature_flags & IRDMA_FEATURE_ATOMIC_OPS)
                stag_info->remote_atomics_en = (access & IB_ACCESS_REMOTE_ATOMIC) ? 1 : 0;
        stag_info->pd_id = iwpd->sc_pd.pd_id;
-       stag_info->all_memory = pd->flags & IB_PD_UNSAFE_GLOBAL_RKEY;
+       stag_info->all_memory = iwmr->dma_mr;
        if (stag_info->access_rights & IRDMA_ACCESS_FLAGS_ZERO_BASED)
                stag_info->addr_type = IRDMA_ADDR_TYPE_ZERO_BASED;
        else
@@ -3297,7 +3296,7 @@ static int irdma_hwreg_mr(struct irdma_device *iwdev, struct irdma_mr *iwmr,
        irdma_put_cqp_request(&iwdev->rf->cqp, cqp_request);
 
        if (!ret)
-               iwmr->is_hwreg = 1;
+               iwmr->is_hwreg = true;
 
        return ret;
 }
@@ -3669,7 +3668,7 @@ static int irdma_hwdereg_mr(struct ib_mr *ib_mr)
        if (status)
                return status;
 
-       iwmr->is_hwreg = 0;
+       iwmr->is_hwreg = false;
        return 0;
 }
 
@@ -3792,9 +3791,10 @@ static struct ib_mr *irdma_rereg_user_mr(struct ib_mr *ib_mr, int flags,
  * @size: size of memory to register
  * @access: Access rights
  * @iova_start: start of virtual address for physical buffers
+ * @dma_mr: Flag indicating whether this region is a PD DMA MR
  */
 struct ib_mr *irdma_reg_phys_mr(struct ib_pd *pd, u64 addr, u64 size, int access,
-                               u64 *iova_start)
+                               u64 *iova_start, bool dma_mr)
 {
        struct irdma_device *iwdev = to_iwdev(pd->device);
        struct irdma_pbl *iwpbl;
@@ -3811,6 +3811,7 @@ struct ib_mr *irdma_reg_phys_mr(struct ib_pd *pd, u64 addr, u64 size, int access
        iwpbl = &iwmr->iwpbl;
        iwpbl->iwmr = iwmr;
        iwmr->type = IRDMA_MEMREG_TYPE_MEM;
+       iwmr->dma_mr = dma_mr;
        iwpbl->user_base = *iova_start;
        stag = irdma_create_stag(iwdev);
        if (!stag) {
@@ -3849,7 +3850,7 @@ static struct ib_mr *irdma_get_dma_mr(struct ib_pd *pd, int acc)
 {
        u64 kva = 0;
 
-       return irdma_reg_phys_mr(pd, 0, 0, acc, &kva);
+       return irdma_reg_phys_mr(pd, 0, 0, acc, &kva, true);
 }
 
 /**
index ed21c1b56e8ec63ee3a46d26580eaa10e671da09..6c05179d4a317aca237046dd53b0bee1f4d9ea1b 100644 (file)
@@ -111,7 +111,8 @@ struct irdma_mr {
        };
        struct ib_umem *region;
        int access;
-       u8 is_hwreg;
+       bool is_hwreg:1;
+       bool dma_mr:1;
        u16 type;
        u32 page_cnt;
        u64 page_size;