mlx5_read_queue_counter() casts its uint64_t *stat argument to
uint32_t * before passing it to mlx5_devx_cmd_queue_counter_query().
The query function writes a single uint32_t, so:

  - On little-endian (x86): only the low 32 bits of *stat are
    written; the upper 32 bits retain whatever value they had
    before the call (stack garbage or a stale value).
  - On big-endian (PowerPC): the write hits the wrong half of the
    64-bit word entirely.

Use a local uint32_t for the query and widen to uint64_t on
assignment.

Fixes: f0c0731b6d40 ("net/mlx5: add counters for hairpin drop")
Cc: [email protected]

Signed-off-by: Stephen Hemminger <[email protected]>
---
 drivers/net/mlx5/mlx5.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c
index 71383f2ac7..4e0bc26754 100644
--- a/drivers/net/mlx5/mlx5.c
+++ b/drivers/net/mlx5/mlx5.c
@@ -3783,6 +3783,9 @@ int
 mlx5_read_queue_counter(struct mlx5_devx_obj *q_counter, const char *ctr_name,
                      uint64_t *stat)
 {
+       uint32_t val;
+       int ret;
+
        if (rte_eal_process_type() == RTE_PROC_SECONDARY) {
                DRV_LOG(WARNING,
                        "DevX %s counter is not supported in the secondary 
process", ctr_name);
@@ -3792,7 +3795,11 @@ mlx5_read_queue_counter(struct mlx5_devx_obj *q_counter, 
const char *ctr_name,
        if (q_counter == NULL)
                return -EINVAL;
 
-       return mlx5_devx_cmd_queue_counter_query(q_counter, 0, (uint32_t 
*)stat);
+       ret = mlx5_devx_cmd_queue_counter_query(q_counter, 0, &val);
+       if (ret == 0)
+               *stat = val;
+
+       return ret;
 }
 
 /**
-- 
2.51.0

Reply via email to