Skip to content
/ linux Public

Commit c3db55d

Browse files
Jianbo Liugregkh
authored andcommitted
net/mlx5e: Prevent concurrent access to IPSec ASO context
[ Upstream commit 99b3685 ] 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 869ff44 commit c3db55d

File tree

2 files changed

+9
-9
lines changed

2 files changed

+9
-9
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,7 @@ struct mlx5e_ipsec_sa_entry {
274274
struct mlx5e_ipsec_dwork *dwork;
275275
struct mlx5e_ipsec_limits limits;
276276
u32 rx_mapped_id;
277+
u8 ctx[MLX5_ST_SZ_BYTES(ipsec_aso)];
277278
};
278279

279280
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
@@ -371,20 +371,18 @@ static void mlx5e_ipsec_aso_update_soft(struct mlx5e_ipsec_sa_entry *sa_entry,
371371
static void mlx5e_ipsec_handle_limits(struct mlx5e_ipsec_sa_entry *sa_entry)
372372
{
373373
struct mlx5_accel_esp_xfrm_attrs *attrs = &sa_entry->attrs;
374-
struct mlx5e_ipsec *ipsec = sa_entry->ipsec;
375-
struct mlx5e_ipsec_aso *aso = ipsec->aso;
376374
bool soft_arm, hard_arm;
377375
u64 hard_cnt;
378376

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

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

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

461-
aso = sa_entry->ipsec->aso;
462458
attrs = &sa_entry->attrs;
463459

464460
spin_lock_bh(&sa_entry->x->lock);
@@ -467,8 +463,9 @@ static void mlx5e_ipsec_handle_event(struct work_struct *_work)
467463
goto unlock;
468464

469465
if (attrs->replay_esn.trigger &&
470-
!MLX5_GET(ipsec_aso, aso->ctx, esn_event_arm)) {
471-
u32 mode_param = MLX5_GET(ipsec_aso, aso->ctx, mode_parameter);
466+
!MLX5_GET(ipsec_aso, sa_entry->ctx, esn_event_arm)) {
467+
u32 mode_param = MLX5_GET(ipsec_aso, sa_entry->ctx,
468+
mode_parameter);
472469

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

0 commit comments

Comments
 (0)