| From bbade94280909ebd5284ce117d9682ccb4e53825 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/ethernet/broadcom/tg3.c | 18 ++++++++++++++++-- |
| 1 file changed, 16 insertions(+), 2 deletions(-) |
| |
| --- a/drivers/net/ethernet/broadcom/tg3.c |
| +++ b/drivers/net/ethernet/broadcom/tg3.c |
| @@ -879,8 +879,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; |
| |
| @@ -5877,6 +5882,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() |
| @@ -7428,6 +7436,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: |