| From foo@baz Thu Dec 21 09:02:40 CET 2017 |
| From: Sankar Patchineelam <sankar.patchineelam@broadcom.com> |
| Date: Tue, 28 Mar 2017 19:47:29 -0400 |
| Subject: bnxt_en: Fix NULL pointer dereference in reopen failure path |
| |
| From: Sankar Patchineelam <sankar.patchineelam@broadcom.com> |
| |
| |
| [ Upstream commit 2247925f0942dc4e7c09b1cde45ca18461d94c5f ] |
| |
| Net device reset can fail when the h/w or f/w is in a bad state. |
| Subsequent netdevice open fails in bnxt_hwrm_stat_ctx_alloc(). |
| The cleanup invokes bnxt_hwrm_resource_free() which inturn |
| calls bnxt_disable_int(). In this routine, the code segment |
| |
| if (ring->fw_ring_id != INVALID_HW_RING_ID) |
| BNXT_CP_DB(cpr->cp_doorbell, cpr->cp_raw_cons); |
| |
| results in NULL pointer dereference as cpr->cp_doorbell is not yet |
| initialized, and fw_ring_id is zero. |
| |
| The fix is to initialize cpr fw_ring_id to INVALID_HW_RING_ID before |
| bnxt_init_chip() is invoked. |
| |
| Signed-off-by: Sankar Patchineelam <sankar.patchineelam@broadcom.com> |
| Signed-off-by: Michael Chan <michael.chan@broadcom.com> |
| Signed-off-by: David S. Miller <davem@davemloft.net> |
| Signed-off-by: Sasha Levin <alexander.levin@verizon.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| drivers/net/ethernet/broadcom/bnxt/bnxt.c | 13 +++++++++++++ |
| 1 file changed, 13 insertions(+) |
| |
| --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c |
| +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c |
| @@ -2381,6 +2381,18 @@ static int bnxt_init_one_rx_ring(struct |
| return 0; |
| } |
| |
| +static void bnxt_init_cp_rings(struct bnxt *bp) |
| +{ |
| + int i; |
| + |
| + for (i = 0; i < bp->cp_nr_rings; i++) { |
| + struct bnxt_cp_ring_info *cpr = &bp->bnapi[i]->cp_ring; |
| + struct bnxt_ring_struct *ring = &cpr->cp_ring_struct; |
| + |
| + ring->fw_ring_id = INVALID_HW_RING_ID; |
| + } |
| +} |
| + |
| static int bnxt_init_rx_rings(struct bnxt *bp) |
| { |
| int i, rc = 0; |
| @@ -4700,6 +4712,7 @@ static int bnxt_shutdown_nic(struct bnxt |
| |
| static int bnxt_init_nic(struct bnxt *bp, bool irq_re_init) |
| { |
| + bnxt_init_cp_rings(bp); |
| bnxt_init_rx_rings(bp); |
| bnxt_init_tx_rings(bp); |
| bnxt_init_ring_grps(bp, irq_re_init); |