RDMA/mlx5: Fix flow counter query via DEVX
authorMark Bloch <mbloch@nvidia.com>
Thu, 13 Apr 2023 09:23:09 +0000 (12:23 +0300)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 11 May 2023 14:03:35 +0000 (23:03 +0900)
[ Upstream commit 3e358ea8614ddfbc59ca7a3f5dff5dde2b350b2c ]

Commit cited in "fixes" tag added bulk support for flow counters but it
didn't account that's also possible to query a counter using a non-base id
if the counter was allocated as bulk.

When a user performs a query, validate the flow counter id given in the
mailbox is inside the valid range taking bulk value into account.

Fixes: 208d70f562e5 ("IB/mlx5: Support flow counters offset for bulk counters")
Signed-off-by: Mark Bloch <mbloch@nvidia.com>
Reviewed-by: Maor Gottlieb <maorg@nvidia.com>
Link: https://lore.kernel.org/r/79d7fbe291690128e44672418934256254d93115.1681377114.git.leon@kernel.org
Signed-off-by: Leon Romanovsky <leon@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/infiniband/hw/mlx5/devx.c
include/linux/mlx5/mlx5_ifc.h

index 2211a0b..f8e2bae 100644 (file)
@@ -666,7 +666,21 @@ static bool devx_is_valid_obj_id(struct uverbs_attr_bundle *attrs,
                                      obj_id;
 
        case MLX5_IB_OBJECT_DEVX_OBJ:
-               return ((struct devx_obj *)uobj->object)->obj_id == obj_id;
+       {
+               u16 opcode = MLX5_GET(general_obj_in_cmd_hdr, in, opcode);
+               struct devx_obj *devx_uobj = uobj->object;
+
+               if (opcode == MLX5_CMD_OP_QUERY_FLOW_COUNTER &&
+                   devx_uobj->flow_counter_bulk_size) {
+                       u64 end;
+
+                       end = devx_uobj->obj_id +
+                               devx_uobj->flow_counter_bulk_size;
+                       return devx_uobj->obj_id <= obj_id && end > obj_id;
+               }
+
+               return devx_uobj->obj_id == obj_id;
+       }
 
        default:
                return false;
@@ -1517,10 +1531,17 @@ static int UVERBS_HANDLER(MLX5_IB_METHOD_DEVX_OBJ_CREATE)(
                goto obj_free;
 
        if (opcode == MLX5_CMD_OP_ALLOC_FLOW_COUNTER) {
-               u8 bulk = MLX5_GET(alloc_flow_counter_in,
-                                  cmd_in,
-                                  flow_counter_bulk);
-               obj->flow_counter_bulk_size = 128UL * bulk;
+               u32 bulk = MLX5_GET(alloc_flow_counter_in,
+                                   cmd_in,
+                                   flow_counter_bulk_log_size);
+
+               if (bulk)
+                       bulk = 1 << bulk;
+               else
+                       bulk = 128UL * MLX5_GET(alloc_flow_counter_in,
+                                               cmd_in,
+                                               flow_counter_bulk);
+               obj->flow_counter_bulk_size = bulk;
        }
 
        uobj->object = obj;
index e45bdec..097cbf8 100644 (file)
@@ -9063,7 +9063,8 @@ struct mlx5_ifc_alloc_flow_counter_in_bits {
        u8         reserved_at_20[0x10];
        u8         op_mod[0x10];
 
-       u8         reserved_at_40[0x38];
+       u8         reserved_at_40[0x33];
+       u8         flow_counter_bulk_log_size[0x5];
        u8         flow_counter_bulk[0x8];
 };