Skip to content

Commit

Permalink
Merge pull request #6 from jfornal/jfornal_igb_avb
Browse files Browse the repository at this point in the history
Fixing potential memory corruption on ifconfig down event
  • Loading branch information
andrew-elder authored Sep 11, 2018
2 parents 38b7449 + ec4c4ed commit 45e5262
Showing 1 changed file with 55 additions and 6 deletions.
61 changes: 55 additions & 6 deletions kmod/igb_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -3334,9 +3334,12 @@ static int __igb_open(struct net_device *netdev, bool resuming)
int err;
int i;

mutex_lock(&adapter->lock);

/* disallow open during test */
if (test_bit(__IGB_TESTING, &adapter->state)) {
WARN_ON(resuming);
mutex_unlock(&adapter->lock);
return -EBUSY;
}

Expand Down Expand Up @@ -3412,6 +3415,8 @@ static int __igb_open(struct net_device *netdev, bool resuming)
hw->mac.get_link_status = 1;
schedule_work(&adapter->watchdog_task);

mutex_unlock(&adapter->lock);

return E1000_SUCCESS;

err_set_queues:
Expand All @@ -3430,6 +3435,8 @@ static int __igb_open(struct net_device *netdev, bool resuming)
pm_runtime_put(&pdev->dev);
#endif /* CONFIG_PM_RUNTIME */

mutex_unlock(&adapter->lock);

return err;
}

Expand All @@ -3456,6 +3463,8 @@ static int __igb_close(struct net_device *netdev, bool suspending)
struct pci_dev *pdev = adapter->pdev;
#endif /* CONFIG_PM_RUNTIME */

mutex_lock(&adapter->lock);

WARN_ON(test_bit(__IGB_RESETTING, &adapter->state));

#ifdef CONFIG_PM_RUNTIME
Expand All @@ -3479,6 +3488,8 @@ static int __igb_close(struct net_device *netdev, bool suspending)
pm_runtime_put_sync(&pdev->dev);
#endif /* CONFIG_PM_RUNTIME */

mutex_unlock(&adapter->lock);

return 0;
}

Expand Down Expand Up @@ -3538,6 +3549,10 @@ static int igb_setup_all_tx_resources(struct igb_adapter *adapter)
int i, err = 0;

for (i = 0; i < adapter->num_tx_queues; i++) {
/* do not reallocate queue in use */
if (adapter->uring_tx_init & (1 << i))
continue;

err = igb_setup_tx_resources(adapter->tx_ring[i]);
if (err) {
dev_err(pci_dev_to_dev(pdev),
Expand Down Expand Up @@ -3701,6 +3716,10 @@ static int igb_setup_all_rx_resources(struct igb_adapter *adapter)
int i, err = 0;

for (i = 0; i < adapter->num_rx_queues; i++) {
/* do not reallocate queue in use */
if (adapter->uring_rx_init & (1 << i))
continue;

err = igb_setup_rx_resources(adapter->rx_ring[i]);
if (err) {
dev_err(pci_dev_to_dev(pdev),
Expand Down Expand Up @@ -4142,8 +4161,10 @@ void igb_free_tx_resources(struct igb_ring *tx_ring)
{
igb_clean_tx_ring(tx_ring);

vfree(tx_ring->tx_buffer_info);
tx_ring->tx_buffer_info = NULL;
if (tx_ring->tx_buffer_info) {
vfree(tx_ring->tx_buffer_info);
tx_ring->tx_buffer_info = NULL;
}

/* if not set, then don't free */
if (!tx_ring->desc)
Expand All @@ -4165,8 +4186,12 @@ static void igb_free_all_tx_resources(struct igb_adapter *adapter)
{
int i;

for (i = 0; i < adapter->num_tx_queues; i++)
for (i = 0; i < adapter->num_tx_queues; i++) {
/* do not free queue in use */
if (adapter->uring_tx_init & (1 << i))
continue;
igb_free_tx_resources(adapter->tx_ring[i]);
}
}

void igb_unmap_and_free_tx_resource(struct igb_ring *ring,
Expand Down Expand Up @@ -4244,8 +4269,10 @@ void igb_free_rx_resources(struct igb_ring *rx_ring)
{
igb_clean_rx_ring(rx_ring);

vfree(rx_ring->rx_buffer_info);
rx_ring->rx_buffer_info = NULL;
if (rx_ring->rx_buffer_info) {
vfree(rx_ring->rx_buffer_info);
rx_ring->rx_buffer_info = NULL;
}

/* if not set, then don't free */
if (!rx_ring->desc)
Expand All @@ -4267,8 +4294,12 @@ static void igb_free_all_rx_resources(struct igb_adapter *adapter)
{
int i;

for (i = 0; i < adapter->num_rx_queues; i++)
for (i = 0; i < adapter->num_rx_queues; i++) {
/* do not free queue in use */
if (adapter->uring_rx_init & (1 << i))
continue;
igb_free_rx_resources(adapter->rx_ring[i]);
}
}

/**
Expand Down Expand Up @@ -10546,6 +10577,12 @@ static long igb_mapbuf(struct file *file, void __user *arg, int ring)
return -EBUSY;
}

if (adapter->tx_ring[req.queue]->desc == NULL) {
mutex_unlock(&adapter->lock);
printk("mapring:queue is not ready (txq %d)\n", req.queue);
return -ENOMEM;
}

adapter->uring_tx_init |= (1 << req.queue);
igb_priv->uring_tx_init |= (1 << req.queue);

Expand Down Expand Up @@ -10574,6 +10611,12 @@ static long igb_mapbuf(struct file *file, void __user *arg, int ring)
return -EBUSY;
}

if (adapter->rx_ring[req.queue]->desc == NULL) {
mutex_unlock(&adapter->lock);
printk("mapring:queue is not ready (rxq %d)\n", req.queue);
return -ENOMEM;
}

adapter->uring_rx_init |= (1 << req.queue);
igb_priv->uring_rx_init |= (1 << req.queue);

Expand Down Expand Up @@ -10794,6 +10837,12 @@ static int igb_close_file(struct inode *inode, struct file *file)
adapter->uring_tx_init &= ~igb_priv->uring_tx_init;
adapter->uring_rx_init &= ~igb_priv->uring_rx_init;

/* free remaining queue resoures if needed */
if (test_bit(__IGB_DOWN, &adapter->state)) {
igb_free_all_tx_resources(adapter);
igb_free_all_rx_resources(adapter);
}

userpage = igb_priv->userpages;

while (userpage != NULL) {
Expand Down

0 comments on commit 45e5262

Please sign in to comment.