| From 230a08b71465667df5cff3cb283a7babe256c8e0 Mon Sep 17 00:00:00 2001 |
| From: Michael Chan <michael.chan@broadcom.com> |
| Date: Mon, 8 Apr 2019 17:39:54 -0400 |
| Subject: bnxt_en: Improve RX consumer index validity check. |
| |
| [ Upstream commit a1b0e4e684e9c300b9e759b46cb7a0147e61ddff ] |
| |
| There is logic to check that the RX/TPA consumer index is the expected |
| index to work around a hardware problem. However, the potentially bad |
| consumer index is first used to index into an array to reference an entry. |
| This can potentially crash if the bad consumer index is beyond legal |
| range. Improve the logic to use the consumer index for dereferencing |
| after the validity check and log an error message. |
| |
| Fixes: fa7e28127a5a ("bnxt_en: Add workaround to detect bad opaque in rx completion (part 2)") |
| Signed-off-by: Michael Chan <michael.chan@broadcom.com> |
| Signed-off-by: David S. Miller <davem@davemloft.net> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| drivers/net/ethernet/broadcom/bnxt/bnxt.c | 10 +++++++--- |
| 1 file changed, 7 insertions(+), 3 deletions(-) |
| |
| diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c |
| index 803f7990d32b..351417e74ae2 100644 |
| --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c |
| +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c |
| @@ -1129,6 +1129,8 @@ static void bnxt_tpa_start(struct bnxt *bp, struct bnxt_rx_ring_info *rxr, |
| tpa_info = &rxr->rx_tpa[agg_id]; |
| |
| if (unlikely(cons != rxr->rx_next_cons)) { |
| + netdev_warn(bp->dev, "TPA cons %x != expected cons %x\n", |
| + cons, rxr->rx_next_cons); |
| bnxt_sched_reset(bp, rxr); |
| return; |
| } |
| @@ -1581,15 +1583,17 @@ static int bnxt_rx_pkt(struct bnxt *bp, struct bnxt_cp_ring_info *cpr, |
| } |
| |
| cons = rxcmp->rx_cmp_opaque; |
| - rx_buf = &rxr->rx_buf_ring[cons]; |
| - data = rx_buf->data; |
| - data_ptr = rx_buf->data_ptr; |
| if (unlikely(cons != rxr->rx_next_cons)) { |
| int rc1 = bnxt_discard_rx(bp, cpr, raw_cons, rxcmp); |
| |
| + netdev_warn(bp->dev, "RX cons %x != expected cons %x\n", |
| + cons, rxr->rx_next_cons); |
| bnxt_sched_reset(bp, rxr); |
| return rc1; |
| } |
| + rx_buf = &rxr->rx_buf_ring[cons]; |
| + data = rx_buf->data; |
| + data_ptr = rx_buf->data_ptr; |
| prefetch(data_ptr); |
| |
| misc = le32_to_cpu(rxcmp->rx_cmp_misc_v1); |
| -- |
| 2.19.1 |
| |