mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-06-01 23:23:46 -04:00
RDMA/irdma: Do not directly rely on IB_PD_UNSAFE_GLOBAL_RKEY
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: bb6d73d9ad ("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>
This commit is contained in:
committed by
Leon Romanovsky
parent
35bd787bab
commit
71d3bdae5e
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user