e1000e: Modify Tx/Rx configurations to avoid null pointer dereferences in e1000_open
When e1000e_setup_rx_resources is failed in e1000_open, e1000e_free_tx_resources in "err_setup_rx" segment is executed. "writel(0, tx_ring->head)" statement in e1000_clean_tx_ring in e1000e_free_tx_resources will cause a null poonter dereference(crash), because "tx_ring->head" is only assigned in e1000_configure_tx in e1000_configure, but it is after e1000e_setup_rx_resources. This patch moves head/tail register writing to e1000_configure_tx/rx, which can fix this problem. It is inspired by igb_configure_tx_ring in the igb driver. Specially, thank Alexander Duyck for his valuable suggestion. Signed-off-by: Jia-Ju Bai <baijiaju1990@163.com> Tested-by: Aaron Brown <aaron.f.brown@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
This commit is contained in:
parent
3eb14ea8d9
commit
0845d45e90
|
@ -1737,12 +1737,6 @@ static void e1000_clean_rx_ring(struct e1000_ring *rx_ring)
|
|||
rx_ring->next_to_clean = 0;
|
||||
rx_ring->next_to_use = 0;
|
||||
adapter->flags2 &= ~FLAG2_IS_DISCARDING;
|
||||
|
||||
writel(0, rx_ring->head);
|
||||
if (adapter->flags2 & FLAG2_PCIM2PCI_ARBITER_WA)
|
||||
e1000e_update_rdt_wa(rx_ring, 0);
|
||||
else
|
||||
writel(0, rx_ring->tail);
|
||||
}
|
||||
|
||||
static void e1000e_downshift_workaround(struct work_struct *work)
|
||||
|
@ -2447,12 +2441,6 @@ static void e1000_clean_tx_ring(struct e1000_ring *tx_ring)
|
|||
|
||||
tx_ring->next_to_use = 0;
|
||||
tx_ring->next_to_clean = 0;
|
||||
|
||||
writel(0, tx_ring->head);
|
||||
if (adapter->flags2 & FLAG2_PCIM2PCI_ARBITER_WA)
|
||||
e1000e_update_tdt_wa(tx_ring, 0);
|
||||
else
|
||||
writel(0, tx_ring->tail);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2954,6 +2942,12 @@ static void e1000_configure_tx(struct e1000_adapter *adapter)
|
|||
tx_ring->head = adapter->hw.hw_addr + E1000_TDH(0);
|
||||
tx_ring->tail = adapter->hw.hw_addr + E1000_TDT(0);
|
||||
|
||||
writel(0, tx_ring->head);
|
||||
if (adapter->flags2 & FLAG2_PCIM2PCI_ARBITER_WA)
|
||||
e1000e_update_tdt_wa(tx_ring, 0);
|
||||
else
|
||||
writel(0, tx_ring->tail);
|
||||
|
||||
/* Set the Tx Interrupt Delay register */
|
||||
ew32(TIDV, adapter->tx_int_delay);
|
||||
/* Tx irq moderation */
|
||||
|
@ -3275,6 +3269,12 @@ static void e1000_configure_rx(struct e1000_adapter *adapter)
|
|||
rx_ring->head = adapter->hw.hw_addr + E1000_RDH(0);
|
||||
rx_ring->tail = adapter->hw.hw_addr + E1000_RDT(0);
|
||||
|
||||
writel(0, rx_ring->head);
|
||||
if (adapter->flags2 & FLAG2_PCIM2PCI_ARBITER_WA)
|
||||
e1000e_update_rdt_wa(rx_ring, 0);
|
||||
else
|
||||
writel(0, rx_ring->tail);
|
||||
|
||||
/* Enable Receive Checksum Offload for TCP and UDP */
|
||||
rxcsum = er32(RXCSUM);
|
||||
if (adapter->netdev->features & NETIF_F_RXCSUM)
|
||||
|
|
Loading…
Reference in New Issue