diff options
author | David L Stevens <david.stevens@oracle.com> | 2015-01-26 15:54:35 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-01-27 03:25:21 -0500 |
commit | 07ac3e7099b5788ee4b78233c96532c6209a304b (patch) | |
tree | 0925365f787ab3ec164440078a9b946f4f421a0e | |
parent | 971f49dee2639badd70bea6cf92e4eaa357ffecf (diff) |
sunvnet: free pending tx buffers before clearing ring data
This patch moves the clearing of ring data in vnet_port_free_tx_bufs to after
the freeing of pending buffers in the ring. Otherwise, this can result in
dereferencing a NULL pointer.
Reported-by: Sowmini Varadhan <sowmini.varadhan@oracle.com>
Signed-off-by: David L Stevens <david.stevens@oracle.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/ethernet/sun/sunvnet.c | 21 |
1 files changed, 11 insertions, 10 deletions
diff --git a/drivers/net/ethernet/sun/sunvnet.c b/drivers/net/ethernet/sun/sunvnet.c index b5a1d3d7b0bf..fe044f31708e 100644 --- a/drivers/net/ethernet/sun/sunvnet.c +++ b/drivers/net/ethernet/sun/sunvnet.c | |||
@@ -1637,16 +1637,9 @@ static void vnet_port_free_tx_bufs(struct vnet_port *port) | |||
1637 | int i; | 1637 | int i; |
1638 | 1638 | ||
1639 | dr = &port->vio.drings[VIO_DRIVER_TX_RING]; | 1639 | dr = &port->vio.drings[VIO_DRIVER_TX_RING]; |
1640 | if (dr->base) { | 1640 | |
1641 | ldc_free_exp_dring(port->vio.lp, dr->base, | 1641 | if (dr->base == NULL) |
1642 | (dr->entry_size * dr->num_entries), | 1642 | return; |
1643 | dr->cookies, dr->ncookies); | ||
1644 | dr->base = NULL; | ||
1645 | dr->entry_size = 0; | ||
1646 | dr->num_entries = 0; | ||
1647 | dr->pending = 0; | ||
1648 | dr->ncookies = 0; | ||
1649 | } | ||
1650 | 1643 | ||
1651 | for (i = 0; i < VNET_TX_RING_SIZE; i++) { | 1644 | for (i = 0; i < VNET_TX_RING_SIZE; i++) { |
1652 | struct vio_net_desc *d; | 1645 | struct vio_net_desc *d; |
@@ -1666,6 +1659,14 @@ static void vnet_port_free_tx_bufs(struct vnet_port *port) | |||
1666 | port->tx_bufs[i].skb = NULL; | 1659 | port->tx_bufs[i].skb = NULL; |
1667 | d->hdr.state = VIO_DESC_FREE; | 1660 | d->hdr.state = VIO_DESC_FREE; |
1668 | } | 1661 | } |
1662 | ldc_free_exp_dring(port->vio.lp, dr->base, | ||
1663 | (dr->entry_size * dr->num_entries), | ||
1664 | dr->cookies, dr->ncookies); | ||
1665 | dr->base = NULL; | ||
1666 | dr->entry_size = 0; | ||
1667 | dr->num_entries = 0; | ||
1668 | dr->pending = 0; | ||
1669 | dr->ncookies = 0; | ||
1669 | } | 1670 | } |
1670 | 1671 | ||
1671 | static int vnet_port_alloc_tx_ring(struct vnet_port *port) | 1672 | static int vnet_port_alloc_tx_ring(struct vnet_port *port) |