> mana_range.len is a uint32_t, so a mempool chunk of 4GB or more truncates
> modulo 2^32 -- exactly 4GB becomes 0, 15GB becomes 3GB.
> 
> The guard against priv->max_mr_size cannot catch this because it compares
> the already-truncated value, and the device advertises max_mr_size as
> UINT64_MAX. ibv_reg_mr() then fails with EINVAL on a zero length, or silently
> registers a region far shorter than the pool, so lookups for buffers past that
> boundary never find an MR and no Rx WQE can be posted.
> 
> Widen the length to uint64_t through the MR path, including the multi-process
> request that forwards it to the primary process.
> 
> Fixes: 0f5db3c68ba7 ("net/mana: implement memory registration")
> Cc: [email protected]
> Signed-off-by: Rita Ruvinsky <[email protected]>

Reviewed-by: Long Li <[email protected]>


> ---
>  drivers/net/mana/mana.h |  4 ++--
>  drivers/net/mana/mp.c   |  4 ++--
>  drivers/net/mana/mr.c   | 11 ++++++-----
>  3 files changed, 10 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/net/mana/mana.h b/drivers/net/mana/mana.h index
> 7d94840dc4..552865ff9d 100644
> --- a/drivers/net/mana/mana.h
> +++ b/drivers/net/mana/mana.h
> @@ -553,7 +553,7 @@ struct mana_mp_param {
> 
>         /* MANA_MP_REQ_CREATE_MR */
>         uintptr_t addr;
> -       uint32_t len;
> +       uint64_t len;
>  };
> 
>  #define MANA_MP_NAME   "net_mana_mp"
> @@ -562,7 +562,7 @@ int mana_mp_init_secondary(void);  void
> mana_mp_uninit_primary(void);  void mana_mp_uninit_secondary(void);  int
> mana_mp_req_verbs_cmd_fd(struct rte_eth_dev *dev); -int
> mana_mp_req_mr_create(struct mana_priv *priv, uintptr_t addr, uint32_t len);
> +int mana_mp_req_mr_create(struct mana_priv *priv, uintptr_t addr,
> +uint64_t len);
> 
>  void mana_mp_req_on_rxtx(struct rte_eth_dev *dev, enum
> mana_mp_req_type type);
> 
> diff --git a/drivers/net/mana/mp.c b/drivers/net/mana/mp.c index
> 5467d385ce..5cc29de3a1 100644
> --- a/drivers/net/mana/mp.c
> +++ b/drivers/net/mana/mp.c
> @@ -17,7 +17,7 @@ extern struct mana_shared_data *mana_shared_data;
>   * Process MR request from secondary process.
>   */
>  static int
> -mana_mp_mr_create(struct mana_priv *priv, uintptr_t addr, uint32_t len)
> +mana_mp_mr_create(struct mana_priv *priv, uintptr_t addr, uint64_t len)
>  {
>         struct ibv_mr *ibv_mr;
>         int ret;
> @@ -257,7 +257,7 @@ mana_mp_req_verbs_cmd_fd(struct rte_eth_dev *dev)
>   * Request the primary process to register a MR.
>   */
>  int
> -mana_mp_req_mr_create(struct mana_priv *priv, uintptr_t addr, uint32_t len)
> +mana_mp_req_mr_create(struct mana_priv *priv, uintptr_t addr, uint64_t
> +len)
>  {
>         struct rte_mp_msg mp_req = {0};
>         struct rte_mp_msg *mp_res;
> diff --git a/drivers/net/mana/mr.c b/drivers/net/mana/mr.c index
> c4045141bc..7405755df8 100644
> --- a/drivers/net/mana/mr.c
> +++ b/drivers/net/mana/mr.c
> @@ -13,7 +13,8 @@
>  struct mana_range {
>         uintptr_t       start;
>         uintptr_t       end;
> -       uint32_t        len;
> +       /* 64-bit: a mempool chunk can be 4GB or more, which overflows
> uint32_t. */
> +       uint64_t        len;
>  };
> 
>  void
> @@ -47,13 +48,13 @@ mana_new_pmd_mr(struct mana_mr_btree
> *local_tree, struct mana_priv *priv,
> 
>         for (i = 0; i < pool->nb_mem_chunks; i++) {
>                 if (ranges[i].len > priv->max_mr_size) {
> -                       DP_LOG(ERR, "memory chunk size %u exceeding max MR",
> +                       DP_LOG(ERR, "memory chunk size %" PRIu64 "
> + exceeding max MR",
>                                ranges[i].len);
>                         return -ENOMEM;
>                 }
> 
>                 DP_LOG(DEBUG,
> -                      "registering memory chunk start 0x%" PRIxPTR " len %u",
> +                      "registering memory chunk start 0x%" PRIxPTR "
> + len %" PRIu64,
>                        ranges[i].start, ranges[i].len);
> 
>                 if (rte_eal_process_type() == RTE_PROC_SECONDARY) { @@ -62,7
> +63,7 @@ mana_new_pmd_mr(struct mana_mr_btree *local_tree, struct
> mana_priv *priv,
>                                                     ranges[i].len);
>                         if (ret) {
>                                 DP_LOG(ERR,
> -                                      "MR failed start 0x%" PRIxPTR " len 
> %u",
> +                                      "MR failed start 0x%" PRIxPTR "
> + len %" PRIu64,
>                                        ranges[i].start, ranges[i].len);
>                                 return ret;
>                         }
> @@ -98,7 +99,7 @@ mana_new_pmd_mr(struct mana_mr_btree *local_tree,
> struct mana_priv *priv,
>                                 return ret;
>                         }
>                 } else {
> -                       DP_LOG(ERR, "MR failed at 0x%" PRIxPTR " len %u",
> +                       DP_LOG(ERR, "MR failed at 0x%" PRIxPTR " len %"
> + PRIu64,
>                                ranges[i].start, ranges[i].len);
>                         return -errno;
>                 }
> --
> 2.43.0

Reply via email to