| From 622fc09f446efa3a4f3e69302507069973e8ac8a Mon Sep 17 00:00:00 2001 |
| From: Matt Carlson <mcarlson@broadcom.com> |
| Date: Tue, 24 Apr 2012 13:37:01 +0000 |
| Subject: tg3: Avoid panic from reserved statblk field access |
| |
| |
| From: Matt Carlson <mcarlson@broadcom.com> |
| |
| [ Upstream commit f891ea1634ce41f5f47ae40d8594809f4cd2ca66 ] |
| |
| When RSS is enabled, interrupt vector 0 does not receive any rx traffic. |
| The rx producer index fields for vector 0's status block should be |
| considered reserved in this case. This patch changes the code to |
| respect these reserved fields, which avoids a kernel panic when these |
| fields take on non-zero values. |
| |
| Signed-off-by: Matt Carlson <mcarlson@broadcom.com> |
| Signed-off-by: Michael Chan <mchan@broadcom.com> |
| Signed-off-by: David S. Miller <davem@davemloft.net> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| drivers/net/tg3.c | 18 ++++++++++++++++-- |
| 1 file changed, 16 insertions(+), 2 deletions(-) |
| |
| --- a/drivers/net/tg3.c |
| +++ b/drivers/net/tg3.c |
| @@ -740,8 +740,13 @@ static inline unsigned int tg3_has_work( |
| if (sblk->status & SD_STATUS_LINK_CHG) |
| work_exists = 1; |
| } |
| - /* check for RX/TX work to do */ |
| - if (sblk->idx[0].tx_consumer != tnapi->tx_cons || |
| + |
| + /* check for TX work to do */ |
| + if (sblk->idx[0].tx_consumer != tnapi->tx_cons) |
| + work_exists = 1; |
| + |
| + /* check for RX work to do */ |
| + if (tnapi->rx_rcb_prod_idx && |
| *(tnapi->rx_rcb_prod_idx) != tnapi->rx_rcb_ptr) |
| work_exists = 1; |
| |
| @@ -5216,6 +5221,9 @@ static int tg3_poll_work(struct tg3_napi |
| return work_done; |
| } |
| |
| + if (!tnapi->rx_rcb_prod_idx) |
| + return work_done; |
| + |
| /* run RX thread, within the bounds set by NAPI. |
| * All RX "locking" is done by ensuring outside |
| * code synchronizes with tg3->napi.poll() |
| @@ -6626,6 +6634,12 @@ static int tg3_alloc_consistent(struct t |
| */ |
| switch (i) { |
| default: |
| + if (tg3_flag(tp, ENABLE_RSS)) { |
| + tnapi->rx_rcb_prod_idx = NULL; |
| + break; |
| + } |
| + /* Fall through */ |
| + case 1: |
| tnapi->rx_rcb_prod_idx = &sblk->idx[0].rx_producer; |
| break; |
| case 2: |