Skip to content

Commit 2c6a5be

Browse files
Jianbo Liugregkh
authored andcommitted
net/mlx5e: Prevent concurrent access to IPSec ASO context
[ Upstream commit 99b36850d881e2d65912b2520a1c80d0fcc9429a ] The query or updating IPSec offload object is through Access ASO WQE. The driver uses a single mlx5e_ipsec_aso struct for each PF, which contains a shared DMA-mapped context for all ASO operations. A race condition exists because the ASO spinlock is released before the hardware has finished processing WQE. If a second operation is initiated immediately after, it overwrites the shared context in the DMA area. When the first operation's completion is processed later, it reads this corrupted context, leading to unexpected behavior and incorrect results. This commit fixes the race by introducing a private context within each IPSec offload object. The shared ASO context is now copied to this private context while the ASO spinlock is held. Subsequent processing uses this saved, per-object context, ensuring its integrity is maintained. Fixes: 1ed78fc ("net/mlx5e: Update IPsec soft and hard limits") Signed-off-by: Jianbo Liu <jianbol@nvidia.com> Reviewed-by: Leon Romanovsky <leonro@nvidia.com> Signed-off-by: Tariq Toukan <tariqt@nvidia.com> Link: https://patch.msgid.link/20260316094603.6999-3-tariqt@nvidia.com Signed-off-by: Jakub Kicinski <kuba@kernel.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent ea52e95 commit 2c6a5be

2 files changed

Lines changed: 9 additions & 9 deletions

File tree

drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,7 @@ struct mlx5e_ipsec_sa_entry {
287287
struct mlx5e_ipsec_dwork *dwork;
288288
struct mlx5e_ipsec_limits limits;
289289
u32 rx_mapped_id;
290+
u8 ctx[MLX5_ST_SZ_BYTES(ipsec_aso)];
290291
};
291292

292293
struct mlx5_accel_pol_xfrm_attrs {

drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_offload.c

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -370,20 +370,18 @@ static void mlx5e_ipsec_aso_update_soft(struct mlx5e_ipsec_sa_entry *sa_entry,
370370
static void mlx5e_ipsec_handle_limits(struct mlx5e_ipsec_sa_entry *sa_entry)
371371
{
372372
struct mlx5_accel_esp_xfrm_attrs *attrs = &sa_entry->attrs;
373-
struct mlx5e_ipsec *ipsec = sa_entry->ipsec;
374-
struct mlx5e_ipsec_aso *aso = ipsec->aso;
375373
bool soft_arm, hard_arm;
376374
u64 hard_cnt;
377375

378376
lockdep_assert_held(&sa_entry->x->lock);
379377

380-
soft_arm = !MLX5_GET(ipsec_aso, aso->ctx, soft_lft_arm);
381-
hard_arm = !MLX5_GET(ipsec_aso, aso->ctx, hard_lft_arm);
378+
soft_arm = !MLX5_GET(ipsec_aso, sa_entry->ctx, soft_lft_arm);
379+
hard_arm = !MLX5_GET(ipsec_aso, sa_entry->ctx, hard_lft_arm);
382380
if (!soft_arm && !hard_arm)
383381
/* It is not lifetime event */
384382
return;
385383

386-
hard_cnt = MLX5_GET(ipsec_aso, aso->ctx, remove_flow_pkt_cnt);
384+
hard_cnt = MLX5_GET(ipsec_aso, sa_entry->ctx, remove_flow_pkt_cnt);
387385
if (!hard_cnt || hard_arm) {
388386
/* It is possible to see packet counter equal to zero without
389387
* hard limit event armed. Such situation can be if packet
@@ -454,10 +452,8 @@ static void mlx5e_ipsec_handle_event(struct work_struct *_work)
454452
container_of(_work, struct mlx5e_ipsec_work, work);
455453
struct mlx5e_ipsec_sa_entry *sa_entry = work->data;
456454
struct mlx5_accel_esp_xfrm_attrs *attrs;
457-
struct mlx5e_ipsec_aso *aso;
458455
int ret;
459456

460-
aso = sa_entry->ipsec->aso;
461457
attrs = &sa_entry->attrs;
462458

463459
spin_lock_bh(&sa_entry->x->lock);
@@ -466,8 +462,9 @@ static void mlx5e_ipsec_handle_event(struct work_struct *_work)
466462
goto unlock;
467463

468464
if (attrs->replay_esn.trigger &&
469-
!MLX5_GET(ipsec_aso, aso->ctx, esn_event_arm)) {
470-
u32 mode_param = MLX5_GET(ipsec_aso, aso->ctx, mode_parameter);
465+
!MLX5_GET(ipsec_aso, sa_entry->ctx, esn_event_arm)) {
466+
u32 mode_param = MLX5_GET(ipsec_aso, sa_entry->ctx,
467+
mode_parameter);
471468

472469
mlx5e_ipsec_update_esn_state(sa_entry, mode_param);
473470
}
@@ -629,6 +626,8 @@ int mlx5e_ipsec_aso_query(struct mlx5e_ipsec_sa_entry *sa_entry,
629626
/* We are in atomic context */
630627
udelay(10);
631628
} while (ret && time_is_after_jiffies(expires));
629+
if (!ret)
630+
memcpy(sa_entry->ctx, aso->ctx, MLX5_ST_SZ_BYTES(ipsec_aso));
632631
spin_unlock_bh(&aso->lock);
633632
return ret;
634633
}

0 commit comments

Comments
 (0)