Skip to content

Commit 2747328

Browse files
sreekanthbrcmkuba-moo
authored andcommitted
bnxt_en: Fix memory corruption when FW resources change during ifdown
bnxt_set_dflt_rings() assumes that it is always called before any TC has been created. So it doesn't take bp->num_tc into account and assumes that it is always 0 or 1. In the FW resource or capability change scenario, the FW will return flags in bnxt_hwrm_if_change() that will cause the driver to reinitialize and call bnxt_cancel_reservations(). This will lead to bnxt_init_dflt_ring_mode() calling bnxt_set_dflt_rings() and bp->num_tc may be greater than 1. This will cause bp->tx_ring[] to be sized too small and cause memory corruption in bnxt_alloc_cp_rings(). Fix it by properly scaling the TX rings by bp->num_tc in the code paths mentioned above. Add 2 helper functions to determine bp->tx_nr_rings and bp->tx_nr_rings_per_tc. Fixes: ec5d31e ("bnxt_en: Handle firmware reset status during IF_UP.") Reviewed-by: Kalesh AP <[email protected]> Reviewed-by: Andy Gospodarek <[email protected]> Signed-off-by: Sreekanth Reddy <[email protected]> Signed-off-by: Michael Chan <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent d9b0ca1 commit 2747328

File tree

1 file changed

+16
-5
lines changed
  • drivers/net/ethernet/broadcom/bnxt

1 file changed

+16
-5
lines changed

drivers/net/ethernet/broadcom/bnxt/bnxt.c

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12851,6 +12851,17 @@ static int bnxt_set_xps_mapping(struct bnxt *bp)
1285112851
return rc;
1285212852
}
1285312853

12854+
static int bnxt_tx_nr_rings(struct bnxt *bp)
12855+
{
12856+
return bp->num_tc ? bp->tx_nr_rings_per_tc * bp->num_tc :
12857+
bp->tx_nr_rings_per_tc;
12858+
}
12859+
12860+
static int bnxt_tx_nr_rings_per_tc(struct bnxt *bp)
12861+
{
12862+
return bp->num_tc ? bp->tx_nr_rings / bp->num_tc : bp->tx_nr_rings;
12863+
}
12864+
1285412865
static int __bnxt_open_nic(struct bnxt *bp, bool irq_re_init, bool link_re_init)
1285512866
{
1285612867
int rc = 0;
@@ -16325,7 +16336,7 @@ static void bnxt_trim_dflt_sh_rings(struct bnxt *bp)
1632516336
bp->cp_nr_rings = min_t(int, bp->tx_nr_rings_per_tc, bp->rx_nr_rings);
1632616337
bp->rx_nr_rings = bp->cp_nr_rings;
1632716338
bp->tx_nr_rings_per_tc = bp->cp_nr_rings;
16328-
bp->tx_nr_rings = bp->tx_nr_rings_per_tc;
16339+
bp->tx_nr_rings = bnxt_tx_nr_rings(bp);
1632916340
}
1633016341

1633116342
static int bnxt_set_dflt_rings(struct bnxt *bp, bool sh)
@@ -16357,7 +16368,7 @@ static int bnxt_set_dflt_rings(struct bnxt *bp, bool sh)
1635716368
bnxt_trim_dflt_sh_rings(bp);
1635816369
else
1635916370
bp->cp_nr_rings = bp->tx_nr_rings_per_tc + bp->rx_nr_rings;
16360-
bp->tx_nr_rings = bp->tx_nr_rings_per_tc;
16371+
bp->tx_nr_rings = bnxt_tx_nr_rings(bp);
1636116372

1636216373
avail_msix = bnxt_get_max_func_irqs(bp) - bp->cp_nr_rings;
1636316374
if (avail_msix >= BNXT_MIN_ROCE_CP_RINGS) {
@@ -16370,7 +16381,7 @@ static int bnxt_set_dflt_rings(struct bnxt *bp, bool sh)
1637016381
rc = __bnxt_reserve_rings(bp);
1637116382
if (rc && rc != -ENODEV)
1637216383
netdev_warn(bp->dev, "Unable to reserve tx rings\n");
16373-
bp->tx_nr_rings_per_tc = bp->tx_nr_rings;
16384+
bp->tx_nr_rings_per_tc = bnxt_tx_nr_rings_per_tc(bp);
1637416385
if (sh)
1637516386
bnxt_trim_dflt_sh_rings(bp);
1637616387

@@ -16379,7 +16390,7 @@ static int bnxt_set_dflt_rings(struct bnxt *bp, bool sh)
1637916390
rc = __bnxt_reserve_rings(bp);
1638016391
if (rc && rc != -ENODEV)
1638116392
netdev_warn(bp->dev, "2nd rings reservation failed.\n");
16382-
bp->tx_nr_rings_per_tc = bp->tx_nr_rings;
16393+
bp->tx_nr_rings_per_tc = bnxt_tx_nr_rings_per_tc(bp);
1638316394
}
1638416395
if (BNXT_CHIP_TYPE_NITRO_A0(bp)) {
1638516396
bp->rx_nr_rings++;
@@ -16413,7 +16424,7 @@ static int bnxt_init_dflt_ring_mode(struct bnxt *bp)
1641316424
if (rc)
1641416425
goto init_dflt_ring_err;
1641516426

16416-
bp->tx_nr_rings_per_tc = bp->tx_nr_rings;
16427+
bp->tx_nr_rings_per_tc = bnxt_tx_nr_rings_per_tc(bp);
1641716428

1641816429
bnxt_set_dflt_rfs(bp);
1641916430

0 commit comments

Comments
 (0)