From 938cdfefeeebbf763dc04857b8aa9e659989f671 Mon Sep 17 00:00:00 2001 From: Miao Yan Date: Mon, 7 Dec 2015 21:28:30 -0800 Subject: [PATCH 01/24] net/vmxnet3: fix a build error when enabling debug output Macro MAC_FMT and MAC_ARG are not defined, but used in vmxnet3_net_init(). This will cause build error when debug level is raised in vmxnet3_debug.h (enable all VMXNET3_DEBUG_xxx). Use VMXNET_MF and VXMNET_MA instead. Signed-off-by: Miao Yan Reviewed-by: Eric Blake Reviewed-by: Dmitry Fleytman Signed-off-by: Jason Wang --- hw/net/vmxnet3.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/net/vmxnet3.c b/hw/net/vmxnet3.c index 37373e5d3d..b41a35cab7 100644 --- a/hw/net/vmxnet3.c +++ b/hw/net/vmxnet3.c @@ -2043,7 +2043,7 @@ static void vmxnet3_net_init(VMXNET3State *s) s->link_status_and_speed = VMXNET3_LINK_SPEED | VMXNET3_LINK_STATUS_UP; - VMW_CFPRN("Permanent MAC: " MAC_FMT, MAC_ARG(s->perm_mac.a)); + VMW_CFPRN("Permanent MAC: " VMXNET_MF, VMXNET_MA(s->perm_mac.a)); s->nic = qemu_new_nic(&net_vmxnet3_info, &s->conf, object_get_typename(OBJECT(s)), From 2e4ca7dbc11ab7fbdfbdefa1fd6dc4ed3e90eabe Mon Sep 17 00:00:00 2001 From: Miao Yan Date: Mon, 7 Dec 2015 21:28:31 -0800 Subject: [PATCH 02/24] net/vmxnet3: use %zu for size_t in printf Use %zu specifier for size_t in printf, otherwise build would fail on platforms where size_t is not unsigned long Signed-off-by: Miao Yan Reviewed-by: Dmitry Fleytman Signed-off-by: Jason Wang --- hw/net/vmxnet3.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/hw/net/vmxnet3.c b/hw/net/vmxnet3.c index b41a35cab7..a5dd79a9bf 100644 --- a/hw/net/vmxnet3.c +++ b/hw/net/vmxnet3.c @@ -138,7 +138,7 @@ static inline void vmxnet3_ring_init(Vmxnet3Ring *ring, } #define VMXNET3_RING_DUMP(macro, ring_name, ridx, r) \ - macro("%s#%d: base %" PRIx64 " size %lu cell_size %lu gen %d next %lu", \ + macro("%s#%d: base %" PRIx64 " size %zu cell_size %zu gen %d next %zu", \ (ring_name), (ridx), \ (r)->pa, (r)->size, (r)->cell_size, (r)->gen, (r)->next) @@ -925,7 +925,7 @@ static void vmxnet3_rx_need_csum_calculate(struct VmxnetRxPkt *pkt, /* Validate packet len: csum_start + scum_offset + length of csum field */ if (pkt_len < (vhdr->csum_start + vhdr->csum_offset + 2)) { - VMW_PKPRN("packet len:%lu < csum_start(%d) + csum_offset(%d) + 2, " + VMW_PKPRN("packet len:%zu < csum_start(%d) + csum_offset(%d) + 2, " "cannot calculate checksum", pkt_len, vhdr->csum_start, vhdr->csum_offset); return; @@ -1974,7 +1974,7 @@ vmxnet3_receive(NetClientState *nc, const uint8_t *buf, size_t size) vmxnet_rx_pkt_attach_data(s->rx_pkt, buf, size, s->rx_vlan_stripping); bytes_indicated = vmxnet3_indicate_packet(s) ? size : -1; if (bytes_indicated < size) { - VMW_PKPRN("RX: %lu of %lu bytes indicated", bytes_indicated, size); + VMW_PKPRN("RX: %zu of %zu bytes indicated", bytes_indicated, size); } } else { VMW_PKPRN("Packet dropped by RX filter"); From 71c2f5b9b3f386b6acae54f5646a445e50717806 Mon Sep 17 00:00:00 2001 From: Miao Yan Date: Mon, 7 Dec 2015 21:28:32 -0800 Subject: [PATCH 03/24] net/vmxnet3: fix debug macro pattern for vmxnet3 Vmxnet3 uses the following debug macro style: #ifdef SOME_DEBUG # define debug(...) do{ printf(...); } while (0) # else # define debug(...) do{ } while (0) #endif If SOME_DEBUG is undefined, then format string inside the debug macro will never be checked by compiler. Code is likely to break in the future when SOME_DEBUG is enabled because of lack of testing. This patch changes this to the following: #define debug(...) \ do { if (SOME_DEBUG_ENABLED) printf(...); } while (0) Signed-off-by: Miao Yan Reviewed-by: Eric Blake Reviewed-by: Dmitry Fleytman Signed-off-by: Jason Wang --- hw/net/vmxnet_debug.h | 161 +++++++++++++++++++++++++----------------- 1 file changed, 97 insertions(+), 64 deletions(-) diff --git a/hw/net/vmxnet_debug.h b/hw/net/vmxnet_debug.h index 96dae0f916..96495dbb12 100644 --- a/hw/net/vmxnet_debug.h +++ b/hw/net/vmxnet_debug.h @@ -20,94 +20,127 @@ #define VMXNET_DEVICE_NAME "vmxnet3" -/* #define VMXNET_DEBUG_CB */ #define VMXNET_DEBUG_WARNINGS #define VMXNET_DEBUG_ERRORS -/* #define VMXNET_DEBUG_INTERRUPTS */ -/* #define VMXNET_DEBUG_CONFIG */ -/* #define VMXNET_DEBUG_RINGS */ -/* #define VMXNET_DEBUG_PACKETS */ -/* #define VMXNET_DEBUG_SHMEM_ACCESS */ -#ifdef VMXNET_DEBUG_SHMEM_ACCESS -#define VMW_SHPRN(fmt, ...) \ - do { \ - printf("[%s][SH][%s]: " fmt "\n", VMXNET_DEVICE_NAME, __func__, \ - ## __VA_ARGS__); \ - } while (0) -#else -#define VMW_SHPRN(fmt, ...) do {} while (0) -#endif +#undef VMXNET_DEBUG_CB +#undef VMXNET_DEBUG_INTERRUPTS +#undef VMXNET_DEBUG_CONFIG +#undef VMXNET_DEBUG_RINGS +#undef VMXNET_DEBUG_PACKETS +#undef VMXNET_DEBUG_SHMEM_ACCESS #ifdef VMXNET_DEBUG_CB -#define VMW_CBPRN(fmt, ...) \ - do { \ - printf("[%s][CB][%s]: " fmt "\n", VMXNET_DEVICE_NAME, __func__, \ - ## __VA_ARGS__); \ - } while (0) +# define VMXNET_DEBUG_CB_ENABLED 1 #else -#define VMW_CBPRN(fmt, ...) do {} while (0) -#endif - -#ifdef VMXNET_DEBUG_PACKETS -#define VMW_PKPRN(fmt, ...) \ - do { \ - printf("[%s][PK][%s]: " fmt "\n", VMXNET_DEVICE_NAME, __func__, \ - ## __VA_ARGS__); \ - } while (0) -#else -#define VMW_PKPRN(fmt, ...) do {} while (0) +# define VMXNET_DEBUG_CB_ENABLED 0 #endif #ifdef VMXNET_DEBUG_WARNINGS -#define VMW_WRPRN(fmt, ...) \ - do { \ - printf("[%s][WR][%s]: " fmt "\n", VMXNET_DEVICE_NAME, __func__, \ - ## __VA_ARGS__); \ - } while (0) +# define VMXNET_DEBUG_WARNINGS_ENABLED 1 #else -#define VMW_WRPRN(fmt, ...) do {} while (0) +# define VMXNET_DEBUG_WARNINGS_ENABLED 0 #endif #ifdef VMXNET_DEBUG_ERRORS -#define VMW_ERPRN(fmt, ...) \ - do { \ - printf("[%s][ER][%s]: " fmt "\n", VMXNET_DEVICE_NAME, __func__, \ - ## __VA_ARGS__); \ - } while (0) +# define VMXNET_DEBUG_ERRORS_ENABLED 1 #else -#define VMW_ERPRN(fmt, ...) do {} while (0) -#endif - -#ifdef VMXNET_DEBUG_INTERRUPTS -#define VMW_IRPRN(fmt, ...) \ - do { \ - printf("[%s][IR][%s]: " fmt "\n", VMXNET_DEVICE_NAME, __func__, \ - ## __VA_ARGS__); \ - } while (0) -#else -#define VMW_IRPRN(fmt, ...) do {} while (0) +# define VMXNET_DEBUG_ERRORS_ENABLED 0 #endif #ifdef VMXNET_DEBUG_CONFIG -#define VMW_CFPRN(fmt, ...) \ - do { \ - printf("[%s][CF][%s]: " fmt "\n", VMXNET_DEVICE_NAME, __func__, \ - ## __VA_ARGS__); \ - } while (0) +# define VMXNET_DEBUG_CONFIG_ENABLED 1 #else -#define VMW_CFPRN(fmt, ...) do {} while (0) +# define VMXNET_DEBUG_CONFIG_ENABLED 0 #endif #ifdef VMXNET_DEBUG_RINGS +# define VMXNET_DEBUG_RINGS_ENABLED 1 +#else +# define VMXNET_DEBUG_RINGS_ENABLED 0 +#endif + +#ifdef VMXNET_DEBUG_PACKETS +# define VMXNET_DEBUG_PACKETS_ENABLED 1 +#else +# define VMXNET_DEBUG_PACKETS_ENABLED 0 +#endif + +#ifdef VMXNET_DEBUG_INTERRUPTS +# define VMXNET_DEBUG_INTERRUPTS_ENABLED 1 +#else +# define VMXNET_DEBUG_INTERRUPTS_ENABLED 0 +#endif + +#ifdef VMXNET_DEBUG_SHMEM_ACCESS +# define VMXNET_DEBUG_SHMEM_ACCESS_ENABLED 1 +#else +# define VMXNET_DEBUG_SHMEM_ACCESS_ENABLED 0 +#endif + +#define VMW_SHPRN(fmt, ...) \ + do { \ + if (VMXNET_DEBUG_SHMEM_ACCESS_ENABLED) { \ + printf("[%s][SH][%s]: " fmt "\n", VMXNET_DEVICE_NAME, __func__, \ + ## __VA_ARGS__); \ + } \ + } while (0) + +#define VMW_CBPRN(fmt, ...) \ + do { \ + if (VMXNET_DEBUG_CB_ENABLED) { \ + printf("[%s][CB][%s]: " fmt "\n", VMXNET_DEVICE_NAME, __func__, \ + ## __VA_ARGS__); \ + } \ + } while (0) + +#define VMW_PKPRN(fmt, ...) \ + do { \ + if (VMXNET_DEBUG_PACKETS_ENABLED) { \ + printf("[%s][PK][%s]: " fmt "\n", VMXNET_DEVICE_NAME, __func__, \ + ## __VA_ARGS__); \ + } \ + } while (0) + +#define VMW_WRPRN(fmt, ...) \ + do { \ + if (VMXNET_DEBUG_WARNINGS_ENABLED) { \ + printf("[%s][WR][%s]: " fmt "\n", VMXNET_DEVICE_NAME, __func__, \ + ## __VA_ARGS__); \ + } \ + } while (0) + +#define VMW_ERPRN(fmt, ...) \ + do { \ + if (VMXNET_DEBUG_ERRORS_ENABLED) { \ + printf("[%s][ER][%s]: " fmt "\n", VMXNET_DEVICE_NAME, __func__, \ + ## __VA_ARGS__); \ + } \ + } while (0) + +#define VMW_IRPRN(fmt, ...) \ + do { \ + if (VMXNET_DEBUG_INTERRUPTS_ENABLED) { \ + printf("[%s][IR][%s]: " fmt "\n", VMXNET_DEVICE_NAME, __func__, \ + ## __VA_ARGS__); \ + } \ + } while (0) + +#define VMW_CFPRN(fmt, ...) \ + do { \ + if (VMXNET_DEBUG_CONFIG_ENABLED) { \ + printf("[%s][CF][%s]: " fmt "\n", VMXNET_DEVICE_NAME, __func__, \ + ## __VA_ARGS__); \ + } \ + } while (0) + #define VMW_RIPRN(fmt, ...) \ do { \ - printf("[%s][RI][%s]: " fmt "\n", VMXNET_DEVICE_NAME, __func__, \ - ## __VA_ARGS__); \ + if (VMXNET_DEBUG_RINGS_ENABLED) { \ + printf("[%s][RI][%s]: " fmt "\n", VMXNET_DEVICE_NAME, __func__, \ + ## __VA_ARGS__); \ + } \ } while (0) -#else -#define VMW_RIPRN(fmt, ...) do {} while (0) -#endif #define VMXNET_MF "%02X:%02X:%02X:%02X:%02X:%02X" #define VMXNET_MA(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5] From dd3c1684719161859553f45b73bb7d68967a3efe Mon Sep 17 00:00:00 2001 From: Miao Yan Date: Mon, 7 Dec 2015 21:28:33 -0800 Subject: [PATCH 04/24] net/vmxnet3: remove redundant VMW_SHPRN(...) definition Macro VMW_SHPRN(...) is already defined vmxnet3_debug.h, so remove the duplication Signed-off-by: Miao Yan Reviewed-by: Eric Blake Reviewed-by: Dmitry Fleytman Signed-off-by: Jason Wang --- hw/net/vmware_utils.h | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/hw/net/vmware_utils.h b/hw/net/vmware_utils.h index 1099df669d..c2c2f900fa 100644 --- a/hw/net/vmware_utils.h +++ b/hw/net/vmware_utils.h @@ -18,10 +18,7 @@ #define VMWARE_UTILS_H #include "qemu/range.h" - -#ifndef VMW_SHPRN -#define VMW_SHPRN(fmt, ...) do {} while (0) -#endif +#include "vmxnet_debug.h" /* * Shared memory access functions with byte swap support From aa4a3dce1c88ed51b616806b8214b7c8428b7470 Mon Sep 17 00:00:00 2001 From: P J P Date: Tue, 15 Dec 2015 12:27:54 +0530 Subject: [PATCH 05/24] net: vmxnet3: avoid memory leakage in activate_device Vmxnet3 device emulator does not check if the device is active before activating it, also it did not free the transmit & receive buffers while deactivating the device, thus resulting in memory leakage on the host. This patch fixes both these issues to avoid host memory leakage. Reported-by: Qinghao Tang Reviewed-by: Dmitry Fleytman Signed-off-by: Prasad J Pandit Cc: qemu-stable@nongnu.org Signed-off-by: Jason Wang --- hw/net/vmxnet3.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/hw/net/vmxnet3.c b/hw/net/vmxnet3.c index a5dd79a9bf..9c1adfc7bd 100644 --- a/hw/net/vmxnet3.c +++ b/hw/net/vmxnet3.c @@ -1194,8 +1194,13 @@ static void vmxnet3_reset_mac(VMXNET3State *s) static void vmxnet3_deactivate_device(VMXNET3State *s) { - VMW_CBPRN("Deactivating vmxnet3..."); - s->device_active = false; + if (s->device_active) { + VMW_CBPRN("Deactivating vmxnet3..."); + vmxnet_tx_pkt_reset(s->tx_pkt); + vmxnet_tx_pkt_uninit(s->tx_pkt); + vmxnet_rx_pkt_uninit(s->rx_pkt); + s->device_active = false; + } } static void vmxnet3_reset(VMXNET3State *s) @@ -1204,7 +1209,6 @@ static void vmxnet3_reset(VMXNET3State *s) vmxnet3_deactivate_device(s); vmxnet3_reset_interrupt_states(s); - vmxnet_tx_pkt_reset(s->tx_pkt); s->drv_shmem = 0; s->tx_sop = true; s->skip_current_tx_pkt = false; @@ -1431,6 +1435,12 @@ static void vmxnet3_activate_device(VMXNET3State *s) return; } + /* Verify if device is active */ + if (s->device_active) { + VMW_CFPRN("Vmxnet3 device is active"); + return; + } + vmxnet3_adjust_by_guest_type(s); vmxnet3_update_features(s); vmxnet3_update_pm_state(s); @@ -1627,7 +1637,7 @@ static void vmxnet3_handle_command(VMXNET3State *s, uint64_t cmd) break; case VMXNET3_CMD_QUIESCE_DEV: - VMW_CBPRN("Set: VMXNET3_CMD_QUIESCE_DEV - pause the device"); + VMW_CBPRN("Set: VMXNET3_CMD_QUIESCE_DEV - deactivate the device"); vmxnet3_deactivate_device(s); break; @@ -1741,7 +1751,7 @@ vmxnet3_io_bar1_write(void *opaque, * shared address only after we get the high part */ if (val == 0) { - s->device_active = false; + vmxnet3_deactivate_device(s); } s->temp_shared_guest_driver_memory = val; s->drv_shmem = 0; @@ -2021,9 +2031,7 @@ static bool vmxnet3_peer_has_vnet_hdr(VMXNET3State *s) static void vmxnet3_net_uninit(VMXNET3State *s) { g_free(s->mcast_list); - vmxnet_tx_pkt_reset(s->tx_pkt); - vmxnet_tx_pkt_uninit(s->tx_pkt); - vmxnet_rx_pkt_uninit(s->rx_pkt); + vmxnet3_deactivate_device(s); qemu_del_nic(s->nic); } From 663fb1e172068c1633a674584d2b9cce396e0cca Mon Sep 17 00:00:00 2001 From: Thomas Huth Date: Tue, 15 Dec 2015 09:48:15 +0100 Subject: [PATCH 06/24] MAINTAINERS: Add an entry for the net/slirp.c file The file net/slirp.c should be listed in the SLIRP section, too. Signed-off-by: Thomas Huth Signed-off-by: Jason Wang --- MAINTAINERS | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS b/MAINTAINERS index 5a62ecda17..ccfa34b3ee 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1199,6 +1199,7 @@ SLIRP M: Jan Kiszka S: Maintained F: slirp/ +F: net/slirp.c T: git git://git.kiszka.org/qemu.git queues/slirp Tracing From fde58177aa112da377bbe1af71e0ec3ee7750196 Mon Sep 17 00:00:00 2001 From: Miao Yan Date: Tue, 22 Dec 2015 22:06:07 -0800 Subject: [PATCH 07/24] net/vmxnet3: return 1 on device activation failure When reading device status, 0 means device is successfully activated and 1 means error. This behavior can be observed by the following steps: 1) run a Linux distro on esxi server (5.5+) 2) modify vmxnet3 Linux driver to give it an invalid address to 'adapter->shared_pa' which is the shared memory for guest/host communication This will trigger device activation failure and kernel log will have the following message: [ 7138.403256] vmxnet3 0000:03:00.0 eth1: Failed to activate dev: error 1 So return 1 on device activation failure instead of -1; Signed-off-by: Miao Yan Reviewed-by: Dmitry Fleytman Signed-off-by: Jason Wang --- hw/net/vmxnet3.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/net/vmxnet3.c b/hw/net/vmxnet3.c index 9c1adfc7bd..8a992d3244 100644 --- a/hw/net/vmxnet3.c +++ b/hw/net/vmxnet3.c @@ -1662,7 +1662,7 @@ static uint64_t vmxnet3_get_command_status(VMXNET3State *s) switch (s->last_command) { case VMXNET3_CMD_ACTIVATE_DEV: - ret = (s->device_active) ? 0 : -1; + ret = (s->device_active) ? 0 : 1; VMW_CFPRN("Device active: %" PRIx64, ret); break; From c469669ef7b4ee2ec1e0db0053ada6809c5b5f98 Mon Sep 17 00:00:00 2001 From: Miao Yan Date: Tue, 22 Dec 2015 22:06:08 -0800 Subject: [PATCH 08/24] net/vmxnet3: return correct value for VMXNET3_CMD_GET_DID_* command VMXNET3_CMD_GET_DID_LO should return PCI ID of the device and VMXNET3_CMD_GET_DID_HI should return vmxnet3 revision ID. This behavior can be observed by the following steps: 1) run a Linux distro on esxi server (5.x+) 2) modify vmxnet3 Linux driver to read DID_HI and DID_LO: VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD, VMXNET3_CMD_GET_DID_LO); lo = VMXNET3_READ_BAR1_REG(adapter, VMXNET3_REG_CMD); VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD, VMXNET3_CMD_GET_DID_HI); high = VMXNET3_READ_BAR1_REG(adapter, VMXNET3_REG_CMD); pr_info("vmxnet3 DID lo: 0x%x, high: 0x%x\n", lo, high); The kernel log will have something like the following message: [ 7005.111170] vmxnet3 DID lo: 0x7b0, high: 0x1 Signed-off-by: Miao Yan Reviewed-by: Dmitry Fleytman Signed-off-by: Jason Wang --- hw/net/vmxnet3.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/hw/net/vmxnet3.c b/hw/net/vmxnet3.c index 8a992d3244..0aff0d4658 100644 --- a/hw/net/vmxnet3.c +++ b/hw/net/vmxnet3.c @@ -1650,6 +1650,14 @@ static void vmxnet3_handle_command(VMXNET3State *s, uint64_t cmd) "adaptive ring info flags"); break; + case VMXNET3_CMD_GET_DID_LO: + VMW_CBPRN("Set: Get lower part of device ID"); + break; + + case VMXNET3_CMD_GET_DID_HI: + VMW_CBPRN("Set: Get upper part of device ID"); + break; + default: VMW_CBPRN("Received unknown command: %" PRIx64, cmd); break; @@ -1693,6 +1701,14 @@ static uint64_t vmxnet3_get_command_status(VMXNET3State *s) ret = VMXNET3_DISABLE_ADAPTIVE_RING; break; + case VMXNET3_CMD_GET_DID_LO: + ret = PCI_DEVICE_ID_VMWARE_VMXNET3; + break; + + case VMXNET3_CMD_GET_DID_HI: + ret = VMXNET3_DEVICE_REVISION; + break; + default: VMW_WRPRN("Received request for unknown command: %x", s->last_command); ret = -1; From 5ae3e91c3502df90fb0ca9c76ac6eb5c2363264f Mon Sep 17 00:00:00 2001 From: Miao Yan Date: Tue, 22 Dec 2015 22:06:09 -0800 Subject: [PATCH 09/24] net/vmxnet3: return correct value for VMXNET3_CMD_GET_DEV_EXTRA_INFO VMXNET3_CMD_GET_DEV_EXTRA_INFO should return 0 for emulation mode This behavior can be observed by the following steps: 1) run a Linux distro on esxi server (5.x+) 2) modify vmxnet3 Linux driver to read the register: VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD, VMXNET3_CMD_GET_DEV_EXTRA_INFO); ret = VMXNET3_READ_BAR1_REG(adapter, VMXNET3_REG_CMD); pr_info("vmxnet3 dev_info: 0x%x\n", ret); The kernel log will have some like the following message: [ 7005.111170] vmxnet3 dev_info: 0x0 Signed-off-by: Miao Yan Reviewed-by: Dmitry Fleytman Signed-off-by: Jason Wang --- hw/net/vmxnet3.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/hw/net/vmxnet3.c b/hw/net/vmxnet3.c index 0aff0d4658..da59d7df2c 100644 --- a/hw/net/vmxnet3.c +++ b/hw/net/vmxnet3.c @@ -1658,6 +1658,10 @@ static void vmxnet3_handle_command(VMXNET3State *s, uint64_t cmd) VMW_CBPRN("Set: Get upper part of device ID"); break; + case VMXNET3_CMD_GET_DEV_EXTRA_INFO: + VMW_CBPRN("Set: Get device extra info"); + break; + default: VMW_CBPRN("Received unknown command: %" PRIx64, cmd); break; @@ -1677,6 +1681,7 @@ static uint64_t vmxnet3_get_command_status(VMXNET3State *s) case VMXNET3_CMD_RESET_DEV: case VMXNET3_CMD_QUIESCE_DEV: case VMXNET3_CMD_GET_QUEUE_STATUS: + case VMXNET3_CMD_GET_DEV_EXTRA_INFO: ret = 0; break; From 8856be151241c3647b6eb0b91b10f2603bbe430c Mon Sep 17 00:00:00 2001 From: Miao Yan Date: Tue, 22 Dec 2015 22:06:10 -0800 Subject: [PATCH 10/24] net/vmxnet3: return 0 on unknown command Return 0 on unknown command, this is what esxi (5.x+) behaves. Signed-off-by: Miao Yan Reviewed-by: Dmitry Fleytman Signed-off-by: Jason Wang --- hw/net/vmxnet3.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/net/vmxnet3.c b/hw/net/vmxnet3.c index da59d7df2c..6ba7c7558c 100644 --- a/hw/net/vmxnet3.c +++ b/hw/net/vmxnet3.c @@ -1716,7 +1716,7 @@ static uint64_t vmxnet3_get_command_status(VMXNET3State *s) default: VMW_WRPRN("Received request for unknown command: %x", s->last_command); - ret = -1; + ret = 0; break; } From c12d82ef15e4a128a24c2fdaadcc45ba49133a27 Mon Sep 17 00:00:00 2001 From: Miao Yan Date: Tue, 22 Dec 2015 22:06:11 -0800 Subject: [PATCH 11/24] net/vmxnet3: rename VMXNET3_DEVICE_VERSION to VMXNET3_UPT_REVISION VMXNET3_DEVICE_VERSION is used as return value for accessing UPT Revision Report and Selection register. So rename it to VMXNET3_UPT_REVISION. Signed-off-by: Miao Yan Reviewed-by: Dmitry Fleytman Signed-off-by: Jason Wang --- hw/net/vmxnet3.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hw/net/vmxnet3.c b/hw/net/vmxnet3.c index 6ba7c7558c..63692c5d27 100644 --- a/hw/net/vmxnet3.c +++ b/hw/net/vmxnet3.c @@ -50,7 +50,7 @@ #define VMXNET3_LINK_STATUS_UP 0x1 /* Least significant bit should be set for revision and version */ -#define VMXNET3_DEVICE_VERSION 0x1 +#define VMXNET3_UPT_REVISION 0x1 #define VMXNET3_DEVICE_REVISION 0x1 /* Number of interrupt vectors for non-MSIx modes */ @@ -1847,7 +1847,7 @@ vmxnet3_io_bar1_read(void *opaque, hwaddr addr, unsigned size) /* UPT Version Report Selection */ case VMXNET3_REG_UVRS: VMW_CBPRN("Read BAR1 [VMXNET3_REG_UVRS], size %d", size); - ret = VMXNET3_DEVICE_VERSION; + ret = VMXNET3_UPT_REVISION; break; /* Command */ From b50c7d452f5aef52cc9e7461f215cab87c3f3b03 Mon Sep 17 00:00:00 2001 From: Li Zhijian Date: Wed, 23 Dec 2015 15:43:19 +0800 Subject: [PATCH 12/24] net/dump: fix nfds->filename leak Cc: Jason Wang Signed-off-by: Li Zhijian Cc: qemu-stable@nongnu.org Signed-off-by: Jason Wang --- net/dump.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/net/dump.c b/net/dump.c index ce16a4b0e3..347b5ca334 100644 --- a/net/dump.c +++ b/net/dump.c @@ -329,6 +329,13 @@ static void filter_dump_instance_init(Object *obj) file_dump_set_filename, NULL); } +static void filter_dump_instance_finalize(Object *obj) +{ + NetFilterDumpState *nfds = FILTER_DUMP(obj); + + g_free(nfds->filename); +} + static void filter_dump_class_init(ObjectClass *oc, void *data) { NetFilterClass *nfc = NETFILTER_CLASS(oc); @@ -343,6 +350,7 @@ static const TypeInfo filter_dump_info = { .parent = TYPE_NETFILTER, .class_init = filter_dump_class_init, .instance_init = filter_dump_instance_init, + .instance_finalize = filter_dump_instance_finalize, .instance_size = sizeof(NetFilterDumpState), }; From 671f66f87fbf6cc6a3879f3055f16347b1db91e9 Mon Sep 17 00:00:00 2001 From: Li Zhijian Date: Wed, 23 Dec 2015 15:43:18 +0800 Subject: [PATCH 13/24] net/filter: fix nf->netdev_id leak Cc: Jason Wang Cc: qemu-stable@nongnu.org Signed-off-by: Li Zhijian Signed-off-by: Jason Wang --- net/filter.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/filter.c b/net/filter.c index 1365bad026..f777ba2899 100644 --- a/net/filter.c +++ b/net/filter.c @@ -204,6 +204,7 @@ static void netfilter_finalize(Object *obj) if (nf->netdev && !QTAILQ_EMPTY(&nf->netdev->filters)) { QTAILQ_REMOVE(&nf->netdev->filters, nf, next); } + g_free(nf->netdev_id); } static void netfilter_class_init(ObjectClass *oc, void *data) From f9262dae13bc95664f9a285d40b6444f0b8842e6 Mon Sep 17 00:00:00 2001 From: Shmulik Ladkani Date: Thu, 24 Dec 2015 09:17:35 +0200 Subject: [PATCH 14/24] vmxnet3: Change offsets of msi/msix pci capabilities Place device reported PCI capabilities at the same offsets as placed by the VMware virtual hardware: MSI at [84], MSI-X at [9c]. Signed-off-by: Shmulik Ladkani Signed-off-by: Jason Wang --- hw/net/vmxnet3.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/hw/net/vmxnet3.c b/hw/net/vmxnet3.c index 63692c5d27..0097f4bbea 100644 --- a/hw/net/vmxnet3.c +++ b/hw/net/vmxnet3.c @@ -36,6 +36,16 @@ #define VMXNET3_MSIX_BAR_SIZE 0x2000 #define MIN_BUF_SIZE 60 +/* Compatability flags for migration */ +#define VMXNET3_COMPAT_FLAG_OLD_MSI_OFFSETS_BIT 0 +#define VMXNET3_COMPAT_FLAG_OLD_MSI_OFFSETS \ + (1 << VMXNET3_COMPAT_FLAG_OLD_MSI_OFFSETS_BIT) + +#define VMXNET3_MSI_OFFSET(s) \ + ((s)->compat_flags & VMXNET3_COMPAT_FLAG_OLD_MSI_OFFSETS ? 0x50 : 0x84) +#define VMXNET3_MSIX_OFFSET(s) \ + ((s)->compat_flags & VMXNET3_COMPAT_FLAG_OLD_MSI_OFFSETS ? 0 : 0x9c) + #define VMXNET3_BAR0_IDX (0) #define VMXNET3_BAR1_IDX (1) #define VMXNET3_MSIX_BAR_IDX (2) @@ -313,6 +323,9 @@ typedef struct { MACAddr *mcast_list; uint32_t mcast_list_len; uint32_t mcast_list_buff_size; /* needed for live migration. */ + + /* Compatability flags for migration */ + uint32_t compat_flags; } VMXNET3State; /* Interrupt management */ @@ -2131,7 +2144,7 @@ vmxnet3_init_msix(VMXNET3State *s) VMXNET3_MSIX_BAR_IDX, VMXNET3_OFF_MSIX_TABLE, &s->msix_bar, VMXNET3_MSIX_BAR_IDX, VMXNET3_OFF_MSIX_PBA, - 0); + VMXNET3_MSIX_OFFSET(s)); if (0 > res) { VMW_WRPRN("Failed to initialize MSI-X, error %d", res); @@ -2159,7 +2172,6 @@ vmxnet3_cleanup_msix(VMXNET3State *s) } } -#define VMXNET3_MSI_OFFSET (0x50) #define VMXNET3_USE_64BIT (true) #define VMXNET3_PER_VECTOR_MASK (false) @@ -2169,7 +2181,7 @@ vmxnet3_init_msi(VMXNET3State *s) PCIDevice *d = PCI_DEVICE(s); int res; - res = msi_init(d, VMXNET3_MSI_OFFSET, VMXNET3_MAX_NMSIX_INTRS, + res = msi_init(d, VMXNET3_MSI_OFFSET(s), VMXNET3_MAX_NMSIX_INTRS, VMXNET3_USE_64BIT, VMXNET3_PER_VECTOR_MASK); if (0 > res) { VMW_WRPRN("Failed to initialize MSI, error %d", res); From 9c087a05040a7495d7614110fb85a81d65ac24d3 Mon Sep 17 00:00:00 2001 From: Shmulik Ladkani Date: Thu, 24 Dec 2015 09:17:36 +0200 Subject: [PATCH 15/24] vmxnet3: Change the offset of the MSIX PBA table Place the PBA table at 0x1000, as placed by VMware virtual hardware. Signed-off-by: Shmulik Ladkani Signed-off-by: Jason Wang --- hw/net/vmxnet3.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/hw/net/vmxnet3.c b/hw/net/vmxnet3.c index 0097f4bbea..4e1534b21f 100644 --- a/hw/net/vmxnet3.c +++ b/hw/net/vmxnet3.c @@ -51,7 +51,8 @@ #define VMXNET3_MSIX_BAR_IDX (2) #define VMXNET3_OFF_MSIX_TABLE (0x000) -#define VMXNET3_OFF_MSIX_PBA (0x800) +#define VMXNET3_OFF_MSIX_PBA(s) \ + ((s)->compat_flags & VMXNET3_COMPAT_FLAG_OLD_MSI_OFFSETS ? 0x800 : 0x1000) /* Link speed in Mbps should be shifted by 16 */ #define VMXNET3_LINK_SPEED (1000 << 16) @@ -2143,7 +2144,7 @@ vmxnet3_init_msix(VMXNET3State *s) &s->msix_bar, VMXNET3_MSIX_BAR_IDX, VMXNET3_OFF_MSIX_TABLE, &s->msix_bar, - VMXNET3_MSIX_BAR_IDX, VMXNET3_OFF_MSIX_PBA, + VMXNET3_MSIX_BAR_IDX, VMXNET3_OFF_MSIX_PBA(s), VMXNET3_MSIX_OFFSET(s)); if (0 > res) { From b22e0aef462df40e3355ee1cdf707b9578d23706 Mon Sep 17 00:00:00 2001 From: Shmulik Ladkani Date: Thu, 24 Dec 2015 09:17:37 +0200 Subject: [PATCH 16/24] vmxnet3: Introduce 'x-old-msi-offsets' back-compat property Following the previous patches, where vmxnet3's pci's msi/msix capability offsets and msix's PBA table offsets have been changed, this patch introduces a boolean property 'x-old-msi-offsets' to vmxnet3, whose default is false. Setting 'x-old-msi-offsets' to 'on' preserves the old offsets behavior, which allows migration to older versions. Signed-off-by: Shmulik Ladkani Signed-off-by: Jason Wang --- hw/net/vmxnet3.c | 2 ++ include/hw/compat.h | 6 +++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/hw/net/vmxnet3.c b/hw/net/vmxnet3.c index 4e1534b21f..f398dea6c3 100644 --- a/hw/net/vmxnet3.c +++ b/hw/net/vmxnet3.c @@ -2593,6 +2593,8 @@ static const VMStateDescription vmstate_vmxnet3 = { static Property vmxnet3_properties[] = { DEFINE_NIC_PROPERTIES(VMXNET3State, conf), + DEFINE_PROP_BIT("x-old-msi-offsets", VMXNET3State, compat_flags, + VMXNET3_COMPAT_FLAG_OLD_MSI_OFFSETS_BIT, false), DEFINE_PROP_END_OF_LIST(), }; diff --git a/include/hw/compat.h b/include/hw/compat.h index 3d8d2a9244..fd20d0e00f 100644 --- a/include/hw/compat.h +++ b/include/hw/compat.h @@ -2,7 +2,11 @@ #define HW_COMPAT_H #define HW_COMPAT_2_5 \ - /* empty */ + {\ + .driver = "vmxnet3",\ + .property = "x-old-msi-offsets",\ + .value = "on",\ + }, #define HW_COMPAT_2_4 \ {\ From b79f17a9bc20efa2bc572528b047f1a297bdac3c Mon Sep 17 00:00:00 2001 From: Shmulik Ladkani Date: Thu, 24 Dec 2015 09:17:38 +0200 Subject: [PATCH 17/24] vmxnet3: coding: Introduce VMXNET3Class Introduce a class type for vmxnet3, and the usual DEVICE_CLASS/DEVICE_GET_CLASS macros. No semantic change. Signed-off-by: Shmulik Ladkani Signed-off-by: Jason Wang --- hw/net/vmxnet3.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/hw/net/vmxnet3.c b/hw/net/vmxnet3.c index f398dea6c3..30447112f6 100644 --- a/hw/net/vmxnet3.c +++ b/hw/net/vmxnet3.c @@ -119,9 +119,18 @@ #define VMXNET_FLAG_IS_SET(field, flag) (((field) & (flag)) == (flag)) +typedef struct VMXNET3Class { + PCIDeviceClass parent_class; +} VMXNET3Class; + #define TYPE_VMXNET3 "vmxnet3" #define VMXNET3(obj) OBJECT_CHECK(VMXNET3State, (obj), TYPE_VMXNET3) +#define VMXNET3_DEVICE_CLASS(klass) \ + OBJECT_CLASS_CHECK(VMXNET3Class, (klass), TYPE_VMXNET3) +#define VMXNET3_DEVICE_GET_CLASS(obj) \ + OBJECT_GET_CLASS(VMXNET3Class, (obj), TYPE_VMXNET3) + /* Cyclic ring abstraction */ typedef struct { hwaddr pa; @@ -2621,6 +2630,7 @@ static void vmxnet3_class_init(ObjectClass *class, void *data) static const TypeInfo vmxnet3_info = { .name = TYPE_VMXNET3, .parent = TYPE_PCI_DEVICE, + .class_size = sizeof(VMXNET3Class), .instance_size = sizeof(VMXNET3State), .class_init = vmxnet3_class_init, .instance_init = vmxnet3_instance_init, From f713d4d2f1b9babc88cbae8802b93f2cc2eabf0c Mon Sep 17 00:00:00 2001 From: Shmulik Ladkani Date: Thu, 24 Dec 2015 09:17:39 +0200 Subject: [PATCH 18/24] vmxnet3: The vmxnet3 device is a PCIE endpoint Report the 'express endpoint' capability if on a PCIE bus. Signed-off-by: Shmulik Ladkani Signed-off-by: Jason Wang --- hw/net/vmxnet3.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) diff --git a/hw/net/vmxnet3.c b/hw/net/vmxnet3.c index 30447112f6..4dc7519ef7 100644 --- a/hw/net/vmxnet3.c +++ b/hw/net/vmxnet3.c @@ -40,7 +40,11 @@ #define VMXNET3_COMPAT_FLAG_OLD_MSI_OFFSETS_BIT 0 #define VMXNET3_COMPAT_FLAG_OLD_MSI_OFFSETS \ (1 << VMXNET3_COMPAT_FLAG_OLD_MSI_OFFSETS_BIT) +#define VMXNET3_COMPAT_FLAG_DISABLE_PCIE_BIT 1 +#define VMXNET3_COMPAT_FLAG_DISABLE_PCIE \ + (1 << VMXNET3_COMPAT_FLAG_DISABLE_PCIE_BIT) +#define VMXNET3_EXP_EP_OFFSET (0x48) #define VMXNET3_MSI_OFFSET(s) \ ((s)->compat_flags & VMXNET3_COMPAT_FLAG_OLD_MSI_OFFSETS ? 0x50 : 0x84) #define VMXNET3_MSIX_OFFSET(s) \ @@ -121,6 +125,7 @@ typedef struct VMXNET3Class { PCIDeviceClass parent_class; + DeviceRealize parent_dc_realize; } VMXNET3Class; #define TYPE_VMXNET3 "vmxnet3" @@ -2285,6 +2290,10 @@ static void vmxnet3_pci_realize(PCIDevice *pci_dev, Error **errp) vmxnet3_net_init(s); + if (pci_is_express(pci_dev) && pci_bus_is_express(pci_dev->bus)) { + pcie_endpoint_cap_init(pci_dev, VMXNET3_EXP_EP_OFFSET); + } + register_savevm(dev, "vmxnet3-msix", -1, 1, vmxnet3_msix_save, vmxnet3_msix_load, s); } @@ -2554,6 +2563,29 @@ static const VMStateInfo int_state_info = { .put = vmxnet3_put_int_state }; +static bool vmxnet3_vmstate_need_pcie_device(void *opaque) +{ + VMXNET3State *s = VMXNET3(opaque); + + return !(s->compat_flags & VMXNET3_COMPAT_FLAG_DISABLE_PCIE); +} + +static bool vmxnet3_vmstate_test_pci_device(void *opaque, int version_id) +{ + return !vmxnet3_vmstate_need_pcie_device(opaque); +} + +static const VMStateDescription vmstate_vmxnet3_pcie_device = { + .name = "vmxnet3/pcie", + .version_id = 1, + .minimum_version_id = 1, + .needed = vmxnet3_vmstate_need_pcie_device, + .fields = (VMStateField[]) { + VMSTATE_PCIE_DEVICE(parent_obj, VMXNET3State), + VMSTATE_END_OF_LIST() + } +}; + static const VMStateDescription vmstate_vmxnet3 = { .name = "vmxnet3", .version_id = 1, @@ -2561,7 +2593,9 @@ static const VMStateDescription vmstate_vmxnet3 = { .pre_save = vmxnet3_pre_save, .post_load = vmxnet3_post_load, .fields = (VMStateField[]) { - VMSTATE_PCI_DEVICE(parent_obj, VMXNET3State), + VMSTATE_STRUCT_TEST(parent_obj, VMXNET3State, + vmxnet3_vmstate_test_pci_device, 0, + vmstate_pci_device, PCIDevice), VMSTATE_BOOL(rx_packets_compound, VMXNET3State), VMSTATE_BOOL(rx_vlan_stripping, VMXNET3State), VMSTATE_BOOL(lro_supported, VMXNET3State), @@ -2596,6 +2630,7 @@ static const VMStateDescription vmstate_vmxnet3 = { }, .subsections = (const VMStateDescription*[]) { &vmxstate_vmxnet3_mcast_list, + &vmstate_vmxnet3_pcie_device, NULL } }; @@ -2607,10 +2642,24 @@ static Property vmxnet3_properties[] = { DEFINE_PROP_END_OF_LIST(), }; +static void vmxnet3_realize(DeviceState *qdev, Error **errp) +{ + VMXNET3Class *vc = VMXNET3_DEVICE_GET_CLASS(qdev); + PCIDevice *pci_dev = PCI_DEVICE(qdev); + VMXNET3State *s = VMXNET3(qdev); + + if (!(s->compat_flags & VMXNET3_COMPAT_FLAG_DISABLE_PCIE)) { + pci_dev->cap_present |= QEMU_PCI_CAP_EXPRESS; + } + + vc->parent_dc_realize(qdev, errp); +} + static void vmxnet3_class_init(ObjectClass *class, void *data) { DeviceClass *dc = DEVICE_CLASS(class); PCIDeviceClass *c = PCI_DEVICE_CLASS(class); + VMXNET3Class *vc = VMXNET3_DEVICE_CLASS(class); c->realize = vmxnet3_pci_realize; c->exit = vmxnet3_pci_uninit; @@ -2620,6 +2669,8 @@ static void vmxnet3_class_init(ObjectClass *class, void *data) c->class_id = PCI_CLASS_NETWORK_ETHERNET; c->subsystem_vendor_id = PCI_VENDOR_ID_VMWARE; c->subsystem_id = PCI_DEVICE_ID_VMWARE_VMXNET3; + vc->parent_dc_realize = dc->realize; + dc->realize = vmxnet3_realize; dc->desc = "VMWare Paravirtualized Ethernet v3"; dc->reset = vmxnet3_qdev_reset; dc->vmsd = &vmstate_vmxnet3; From 3509866ab36972043d6757a03c48097c7b5ae22b Mon Sep 17 00:00:00 2001 From: Shmulik Ladkani Date: Thu, 24 Dec 2015 09:17:41 +0200 Subject: [PATCH 19/24] vmxnet3: Report the Device Serial Number capability Report the DSN extended PCI capability at 0x100. DSN value is a transformation of device MAC address, as calculated by VMware virtual hardware. DSN is reported only if device is pcie. Signed-off-by: Shmulik Ladkani Signed-off-by: Jason Wang --- hw/net/vmxnet3.c | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/hw/net/vmxnet3.c b/hw/net/vmxnet3.c index 4dc7519ef7..aee218c58a 100644 --- a/hw/net/vmxnet3.c +++ b/hw/net/vmxnet3.c @@ -49,6 +49,7 @@ ((s)->compat_flags & VMXNET3_COMPAT_FLAG_OLD_MSI_OFFSETS ? 0x50 : 0x84) #define VMXNET3_MSIX_OFFSET(s) \ ((s)->compat_flags & VMXNET3_COMPAT_FLAG_OLD_MSI_OFFSETS ? 0 : 0x9c) +#define VMXNET3_DSN_OFFSET (0x100) #define VMXNET3_BAR0_IDX (0) #define VMXNET3_BAR1_IDX (1) @@ -2253,6 +2254,22 @@ static const MemoryRegionOps b1_ops = { }, }; +static uint8_t *vmxnet3_device_serial_num(VMXNET3State *s) +{ + static uint64_t dsn_payload; + uint8_t *dsnp = (uint8_t *)&dsn_payload; + + dsnp[0] = 0xfe; + dsnp[1] = s->conf.macaddr.a[3]; + dsnp[2] = s->conf.macaddr.a[4]; + dsnp[3] = s->conf.macaddr.a[5]; + dsnp[4] = s->conf.macaddr.a[0]; + dsnp[5] = s->conf.macaddr.a[1]; + dsnp[6] = s->conf.macaddr.a[2]; + dsnp[7] = 0xff; + return dsnp; +} + static void vmxnet3_pci_realize(PCIDevice *pci_dev, Error **errp) { DeviceState *dev = DEVICE(pci_dev); @@ -2290,8 +2307,15 @@ static void vmxnet3_pci_realize(PCIDevice *pci_dev, Error **errp) vmxnet3_net_init(s); - if (pci_is_express(pci_dev) && pci_bus_is_express(pci_dev->bus)) { - pcie_endpoint_cap_init(pci_dev, VMXNET3_EXP_EP_OFFSET); + if (pci_is_express(pci_dev)) { + if (pci_bus_is_express(pci_dev->bus)) { + pcie_endpoint_cap_init(pci_dev, VMXNET3_EXP_EP_OFFSET); + } + + pcie_add_capability(pci_dev, PCI_EXT_CAP_ID_DSN, 0x1, + VMXNET3_DSN_OFFSET, PCI_EXT_CAP_DSN_SIZEOF); + memcpy(pci_dev->config + VMXNET3_DSN_OFFSET + 4, + vmxnet3_device_serial_num(s), sizeof(uint64_t)); } register_savevm(dev, "vmxnet3-msix", -1, 1, From 7d6d347d0602997a7fcb33b7edd20f8d8515b48b Mon Sep 17 00:00:00 2001 From: Shmulik Ladkani Date: Thu, 24 Dec 2015 09:17:40 +0200 Subject: [PATCH 20/24] vmxnet3: Introduce 'x-disable-pcie' back-compat property Following the previous patch which changed vmxnet3 to be a pci express device, this patch introduces a boolean property 'x-disable-pcie' whose default is false. Setting 'x-disable-pcie' to 'on' preserves the old 'pci device' (non express) behavior. This allows migration to older versions. Signed-off-by: Shmulik Ladkani Signed-off-by: Jason Wang --- hw/net/vmxnet3.c | 2 ++ include/hw/compat.h | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/hw/net/vmxnet3.c b/hw/net/vmxnet3.c index aee218c58a..67abad3598 100644 --- a/hw/net/vmxnet3.c +++ b/hw/net/vmxnet3.c @@ -2663,6 +2663,8 @@ static Property vmxnet3_properties[] = { DEFINE_NIC_PROPERTIES(VMXNET3State, conf), DEFINE_PROP_BIT("x-old-msi-offsets", VMXNET3State, compat_flags, VMXNET3_COMPAT_FLAG_OLD_MSI_OFFSETS_BIT, false), + DEFINE_PROP_BIT("x-disable-pcie", VMXNET3State, compat_flags, + VMXNET3_COMPAT_FLAG_DISABLE_PCIE_BIT, false), DEFINE_PROP_END_OF_LIST(), }; diff --git a/include/hw/compat.h b/include/hw/compat.h index fd20d0e00f..98df0dd7b5 100644 --- a/include/hw/compat.h +++ b/include/hw/compat.h @@ -6,6 +6,10 @@ .driver = "vmxnet3",\ .property = "x-old-msi-offsets",\ .value = "on",\ + },{\ + .driver = "vmxnet3",\ + .property = "x-disable-pcie",\ + .value = "on",\ }, #define HW_COMPAT_2_4 \ From 007cd223de527b5f41278f2d886c1a4beb3e67aa Mon Sep 17 00:00:00 2001 From: Prasad J Pandit Date: Mon, 28 Dec 2015 16:24:08 +0530 Subject: [PATCH 21/24] net: rocker: fix an incorrect array bounds check While processing transmit(tx) descriptors in 'tx_consume' routine the switch emulator suffers from an off-by-one error, if a descriptor was to have more than allowed(ROCKER_TX_FRAGS_MAX=16) fragments. Fix an incorrect bounds check to avoid it. Reported-by: Qinghao Tang Cc: qemu-stable@nongnu.org Signed-off-by: Prasad J Pandit Signed-off-by: Jason Wang --- hw/net/rocker/rocker.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/hw/net/rocker/rocker.c b/hw/net/rocker/rocker.c index c57f1a661a..2e77e5086a 100644 --- a/hw/net/rocker/rocker.c +++ b/hw/net/rocker/rocker.c @@ -232,6 +232,9 @@ static int tx_consume(Rocker *r, DescInfo *info) frag_addr = rocker_tlv_get_le64(tlvs[ROCKER_TLV_TX_FRAG_ATTR_ADDR]); frag_len = rocker_tlv_get_le16(tlvs[ROCKER_TLV_TX_FRAG_ATTR_LEN]); + if (iovcnt >= ROCKER_TX_FRAGS_MAX) { + goto err_too_many_frags; + } iov[iovcnt].iov_len = frag_len; iov[iovcnt].iov_base = g_malloc(frag_len); if (!iov[iovcnt].iov_base) { @@ -244,10 +247,7 @@ static int tx_consume(Rocker *r, DescInfo *info) err = -ROCKER_ENXIO; goto err_bad_io; } - - if (++iovcnt > ROCKER_TX_FRAGS_MAX) { - goto err_too_many_frags; - } + iovcnt++; } if (iovcnt) { From aa7f9966dfdff500bbbf1956d9e115b1fa8987a6 Mon Sep 17 00:00:00 2001 From: Prasad J Pandit Date: Thu, 31 Dec 2015 17:05:27 +0530 Subject: [PATCH 22/24] net: ne2000: fix bounds check in ioport operations While doing ioport r/w operations, ne2000 device emulation suffers from OOB r/w errors. Update respective array bounds check to avoid OOB access. Reported-by: Ling Liu Cc: qemu-stable@nongnu.org Signed-off-by: Prasad J Pandit Signed-off-by: Jason Wang --- hw/net/ne2000.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/hw/net/ne2000.c b/hw/net/ne2000.c index 010f9efccd..a3dffff2ad 100644 --- a/hw/net/ne2000.c +++ b/hw/net/ne2000.c @@ -467,8 +467,9 @@ static inline void ne2000_mem_writel(NE2000State *s, uint32_t addr, uint32_t val) { addr &= ~1; /* XXX: check exact behaviour if not even */ - if (addr < 32 || - (addr >= NE2000_PMEM_START && addr < NE2000_MEM_SIZE)) { + if (addr < 32 + || (addr >= NE2000_PMEM_START + && addr + sizeof(uint32_t) <= NE2000_MEM_SIZE)) { stl_le_p(s->mem + addr, val); } } @@ -497,8 +498,9 @@ static inline uint32_t ne2000_mem_readw(NE2000State *s, uint32_t addr) static inline uint32_t ne2000_mem_readl(NE2000State *s, uint32_t addr) { addr &= ~1; /* XXX: check exact behaviour if not even */ - if (addr < 32 || - (addr >= NE2000_PMEM_START && addr < NE2000_MEM_SIZE)) { + if (addr < 32 + || (addr >= NE2000_PMEM_START + && addr + sizeof(uint32_t) <= NE2000_MEM_SIZE)) { return ldl_le_p(s->mem + addr); } else { return 0xffffffff; From 3be9b3528debd985b7a84ace0626cacf5ffe5ec4 Mon Sep 17 00:00:00 2001 From: Alexis Dambricourt Date: Tue, 5 Jan 2016 00:26:07 +0100 Subject: [PATCH 23/24] l2tpv3: fix cookie decoding If a 32 bits l2tpv3 frame cookie MSB if set to 1, the cast to uint64_t cookie will spread 1 to the four most significant bytes. Then the condition (cookie != s->rx_cookie) becomes false. Signed-off-by: Alexis Dambricourt Signed-off-by: Jason Wang --- net/l2tpv3.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/l2tpv3.c b/net/l2tpv3.c index 8e68e540ec..21d6119ed4 100644 --- a/net/l2tpv3.c +++ b/net/l2tpv3.c @@ -325,7 +325,7 @@ static int l2tpv3_verify_header(NetL2TPV3State *s, uint8_t *buf) if (s->cookie_is_64) { cookie = ldq_be_p(buf + s->cookie_offset); } else { - cookie = ldl_be_p(buf + s->cookie_offset); + cookie = ldl_be_p(buf + s->cookie_offset) & 0xffffffffULL; } if (cookie != s->rx_cookie) { if (!s->header_mismatch) { From 9c7ffe266485c87e8e76d59af22e96866c202e42 Mon Sep 17 00:00:00 2001 From: "Dr. David Alan Gilbert" Date: Fri, 8 Jan 2016 14:41:28 +0000 Subject: [PATCH 24/24] ether/slirp: Avoid redefinition of the same constants MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit eth.h and slirp.h both define ETH_ALEN and ETH_P_IP rtl8139.c and eth.h both define ETH_HLEN Move the related constant (ETH_P_ARP) from slirp.h to eth.h, and remove the duplicates; make slirp.h include eth.h Signed-off-by: Dr. David Alan Gilbert Reviewed-by: Alex Bennée Signed-off-by: Jason Wang --- hw/net/rtl8139.c | 1 - include/net/eth.h | 4 +++- slirp/slirp.h | 7 +------ 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c index 68e43f3d48..d192d573b4 100644 --- a/hw/net/rtl8139.c +++ b/hw/net/rtl8139.c @@ -74,7 +74,6 @@ ( ( input ) & ( size - 1 ) ) #define ETHER_TYPE_LEN 2 -#define ETH_HLEN (ETH_ALEN * 2 + ETHER_TYPE_LEN) #define ETH_MTU 1500 #define VLAN_TCI_LEN 2 diff --git a/include/net/eth.h b/include/net/eth.h index b3273b823f..84384febf2 100644 --- a/include/net/eth.h +++ b/include/net/eth.h @@ -32,6 +32,7 @@ #include "qemu/iov.h" #define ETH_ALEN 6 +#define ETH_HLEN 14 struct eth_header { uint8_t h_dest[ETH_ALEN]; /* destination eth addr */ @@ -170,7 +171,8 @@ struct tcp_hdr { #define IP_HEADER_VERSION(ip) \ ((ip->ip_ver_len >> 4)&0xf) -#define ETH_P_IP (0x0800) +#define ETH_P_IP (0x0800) /* Internet Protocol packet */ +#define ETH_P_ARP (0x0806) /* Address Resolution packet */ #define ETH_P_IPV6 (0x86dd) #define ETH_P_VLAN (0x8100) #define ETH_P_DVLAN (0x88a8) diff --git a/slirp/slirp.h b/slirp/slirp.h index 6589d7eef0..ec0a4c2415 100644 --- a/slirp/slirp.h +++ b/slirp/slirp.h @@ -135,6 +135,7 @@ void free(void *ptr); #include "qemu/queue.h" #include "qemu/sockets.h" +#include "net/eth.h" #include "libslirp.h" #include "ip.h" @@ -158,12 +159,6 @@ void free(void *ptr); #include "bootp.h" #include "tftp.h" -#define ETH_ALEN 6 -#define ETH_HLEN 14 - -#define ETH_P_IP 0x0800 /* Internet Protocol packet */ -#define ETH_P_ARP 0x0806 /* Address Resolution packet */ - #define ARPOP_REQUEST 1 /* ARP request */ #define ARPOP_REPLY 2 /* ARP reply */