d1f1f31
From aa4a3dce1c88ed51b616806b8214b7c8428b7470 Mon Sep 17 00:00:00 2001
d1f1f31
From: P J P <ppandit@redhat.com>
d1f1f31
Date: Tue, 15 Dec 2015 12:27:54 +0530
d1f1f31
Subject: [PATCH] net: vmxnet3: avoid memory leakage in activate_device
d1f1f31
d1f1f31
Vmxnet3 device emulator does not check if the device is active
d1f1f31
before activating it, also it did not free the transmit & receive
d1f1f31
buffers while deactivating the device, thus resulting in memory
d1f1f31
leakage on the host. This patch fixes both these issues to avoid
d1f1f31
host memory leakage.
d1f1f31
d1f1f31
Reported-by: Qinghao Tang <luodalongde@gmail.com>
d1f1f31
Reviewed-by: Dmitry Fleytman <dmitry@daynix.com>
d1f1f31
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
d1f1f31
Cc: qemu-stable@nongnu.org
d1f1f31
Signed-off-by: Jason Wang <jasowang@redhat.com>
d1f1f31
---
d1f1f31
 tools/qemu-xen/hw/net/vmxnet3.c |   24 ++++++++++++++++--------
d1f1f31
 1 files changed, 16 insertions(+), 8 deletions(-)
d1f1f31
d1f1f31
diff --git a/tools/qemu-xen/hw/net/vmxnet3.c b/tools/qemu-xen/hw/net/vmxnet3.c
d1f1f31
index a5dd79a..9c1adfc 100644
d1f1f31
--- a/tools/qemu-xen/hw/net/vmxnet3.c
d1f1f31
+++ b/tools/qemu-xen/hw/net/vmxnet3.c
d1f1f31
@@ -1194,8 +1194,13 @@ static void vmxnet3_reset_mac(VMXNET3State *s)
d1f1f31
 
d1f1f31
 static void vmxnet3_deactivate_device(VMXNET3State *s)
d1f1f31
 {
d1f1f31
-    VMW_CBPRN("Deactivating vmxnet3...");
d1f1f31
-    s->device_active = false;
d1f1f31
+    if (s->device_active) {
d1f1f31
+        VMW_CBPRN("Deactivating vmxnet3...");
d1f1f31
+        vmxnet_tx_pkt_reset(s->tx_pkt);
d1f1f31
+        vmxnet_tx_pkt_uninit(s->tx_pkt);
d1f1f31
+        vmxnet_rx_pkt_uninit(s->rx_pkt);
d1f1f31
+        s->device_active = false;
d1f1f31
+    }
d1f1f31
 }
d1f1f31
 
d1f1f31
 static void vmxnet3_reset(VMXNET3State *s)
d1f1f31
@@ -1204,7 +1209,6 @@ static void vmxnet3_reset(VMXNET3State *s)
d1f1f31
 
d1f1f31
     vmxnet3_deactivate_device(s);
d1f1f31
     vmxnet3_reset_interrupt_states(s);
d1f1f31
-    vmxnet_tx_pkt_reset(s->tx_pkt);
d1f1f31
     s->drv_shmem = 0;
d1f1f31
     s->tx_sop = true;
d1f1f31
     s->skip_current_tx_pkt = false;
d1f1f31
@@ -1431,6 +1435,12 @@ static void vmxnet3_activate_device(VMXNET3State *s)
d1f1f31
         return;
d1f1f31
     }
d1f1f31
 
d1f1f31
+    /* Verify if device is active */
d1f1f31
+    if (s->device_active) {
d1f1f31
+        VMW_CFPRN("Vmxnet3 device is active");
d1f1f31
+        return;
d1f1f31
+    }
d1f1f31
+
d1f1f31
     vmxnet3_adjust_by_guest_type(s);
d1f1f31
     vmxnet3_update_features(s);
d1f1f31
     vmxnet3_update_pm_state(s);
d1f1f31
@@ -1627,7 +1637,7 @@ static void vmxnet3_handle_command(VMXNET3State *s, uint64_t cmd)
d1f1f31
         break;
d1f1f31
 
d1f1f31
     case VMXNET3_CMD_QUIESCE_DEV:
d1f1f31
-        VMW_CBPRN("Set: VMXNET3_CMD_QUIESCE_DEV - pause the device");
d1f1f31
+        VMW_CBPRN("Set: VMXNET3_CMD_QUIESCE_DEV - deactivate the device");
d1f1f31
         vmxnet3_deactivate_device(s);
d1f1f31
         break;
d1f1f31
 
d1f1f31
@@ -1741,7 +1751,7 @@ vmxnet3_io_bar1_write(void *opaque,
d1f1f31
          * shared address only after we get the high part
d1f1f31
          */
d1f1f31
         if (0 == val) {
d1f1f31
-            s->device_active = false;
d1f1f31
+            vmxnet3_deactivate_device(s);
d1f1f31
         }
d1f1f31
         s->temp_shared_guest_driver_memory = val;
d1f1f31
         s->drv_shmem = 0;
d1f1f31
@@ -2021,9 +2031,7 @@ static bool vmxnet3_peer_has_vnet_hdr(VMXNET3State *s)
d1f1f31
 static void vmxnet3_net_uninit(VMXNET3State *s)
d1f1f31
 {
d1f1f31
     g_free(s->mcast_list);
d1f1f31
-    vmxnet_tx_pkt_reset(s->tx_pkt);
d1f1f31
-    vmxnet_tx_pkt_uninit(s->tx_pkt);
d1f1f31
-    vmxnet_rx_pkt_uninit(s->rx_pkt);
d1f1f31
+    vmxnet3_deactivate_device(s);
d1f1f31
     qemu_del_nic(s->nic);
d1f1f31
 }
d1f1f31
 
d1f1f31
-- 
d1f1f31
1.7.0.4
d1f1f31