diff --git a/drivers/net/virtio/Makefile b/drivers/net/virtio/Makefile
index 1c86d9d..5933205 100644
--- a/drivers/net/virtio/Makefile
+++ b/drivers/net/virtio/Makefile
@@ -66,6 +66,7 @@ endif
 ifeq ($(CONFIG_RTE_VIRTIO_QTEST),y)
 SRCS-$(CONFIG_RTE_LIBRTE_VIRTIO_PMD) += virtio_qtest/qtest_utils.c
 SRCS-$(CONFIG_RTE_LIBRTE_VIRTIO_PMD) += virtio_qtest/virtio_qtest_pci.c
+SRCS-$(CONFIG_RTE_LIBRTE_VIRTIO_PMD) += virtio_qtest/virtio_qtest_dev.c
 endif
 
 # this lib depends upon:
diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index f8972f2..c35d1c0 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -59,7 +59,6 @@
 #include "virtqueue.h"
 #include "virtio_rxtx.h"
 
-static int eth_virtio_dev_uninit(struct rte_eth_dev *eth_dev);
 static int  virtio_dev_configure(struct rte_eth_dev *dev);
 static int  virtio_dev_start(struct rte_eth_dev *dev);
 static void virtio_dev_stop(struct rte_eth_dev *dev);
@@ -1179,7 +1178,7 @@ eth_virtio_dev_init(struct rte_eth_dev *eth_dev)
 	return 0;
 }
 
-static int
+int
 eth_virtio_dev_uninit(struct rte_eth_dev *eth_dev)
 {
 	struct rte_pci_device *pci_dev;
diff --git a/drivers/net/virtio/virtio_ethdev.h b/drivers/net/virtio/virtio_ethdev.h
index 284afaa..cbb03f5 100644
--- a/drivers/net/virtio/virtio_ethdev.h
+++ b/drivers/net/virtio/virtio_ethdev.h
@@ -114,6 +114,7 @@ uint16_t virtio_xmit_pkts_simple(void *tx_queue, struct rte_mbuf **tx_pkts,
 		uint16_t nb_pkts);
 
 int eth_virtio_dev_init(struct rte_eth_dev *eth_dev);
+int eth_virtio_dev_uninit(struct rte_eth_dev *eth_dev);
 
 /*
  * The VIRTIO_NET_F_GUEST_TSO[46] features permit the host to send us
diff --git a/drivers/net/virtio/virtio_qtest/qtest.h b/drivers/net/virtio/virtio_qtest/qtest.h
new file mode 100644
index 0000000..534c5a0
--- /dev/null
+++ b/drivers/net/virtio/virtio_qtest/qtest.h
@@ -0,0 +1,95 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2016 IGEL Co., Ltd. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of IGEL Co., Ltd. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _VIRTIO_QTEST_H_
+#define _VIRTIO_QTEST_H_
+
+#define QTEST_DRV_NAME		        "eth_virtio_qtest"
+#define QTEST_DEVICE_NUM                2
+
+#include <rte_pci.h>
+#include <linux/pci_regs.h>
+
+/* Device information */
+#define VIRTIO_NET_DEVICE_ID            0x1000
+#define VIRTIO_NET_VENDOR_ID            0x1af4
+#define IVSHMEM_DEVICE_ID               0x1110
+#define IVSHMEM_VENDOR_ID               0x1af4
+#define PIIX3_DEVICE_ID                 0x7000
+#define PIIX3_VENDOR_ID                 0x8086
+
+/* ------------------------------------------------------------
+ * IO port mapping of qtest guest
+ * ------------------------------------------------------------
+ * 0x0000 - 0xbfff : not used
+ * 0xc000 - 0xc03f : virtio-net(BAR0)
+ * 0xc040 - 0xffff : not used
+ *
+ * ------------------------------------------------------------
+ * Memory mapping of qtest quest
+ * ------------------------------------------------------------
+ * 0x00000000_00000000 - 0x00000000_3fffffff : not used
+ * 0x00000000_40000000 - 0x00000000_40000fff : virtio-net(BAR1)
+ * 0x00000000_40001000 - 0x00000000_40ffffff : not used
+ * 0x00000000_41000000 - 0x00000000_417fffff : virtio-net(BAR4)
+ * 0x00000000_41800000 - 0x00000000_41ffffff : not used
+ * 0x00000000_42000000 - 0x00000000_420000ff : ivshmem(BAR0)
+ * 0x00000000_42000100 - 0x00000000_42ffffff : not used
+ * 0x00000000_80000000 - 0xffffffff_ffffffff : ivshmem(BAR2)
+ *
+ * We can only specify start address of a region. The region size
+ * will be defined by the device implementation in QEMU.
+ * The size will be pow of 2 according to the PCI specification.
+ * Also, the region start address should be aligned by region size.
+ *
+ * BAR2 of ivshmem will be used to mmap DPDK application memory.
+ * So this address will be dynamically changed, but not to overlap
+ * others, it should be mmaped between above addresses. Such allocation
+ * should be done by EAL.
+ */
+#define VIRTIO_NET_IO_START             0xc000
+#define VIRTIO_NET_MEMORY1_START	0x40000000
+#define VIRTIO_NET_MEMORY2_START	0x41000000
+#define IVSHMEM_MEMORY1_START           0x42000000
+#define IVSHMEM_MEMORY2_START           0x80000000
+
+static inline struct rte_pci_id
+qtest_get_pci_id_of_virtio_net(void)
+{
+	struct rte_pci_id id =  {VIRTIO_NET_DEVICE_ID,
+		VIRTIO_NET_VENDOR_ID, PCI_ANY_ID, PCI_ANY_ID};
+
+	return id;
+}
+
+#endif /* _VIRTIO_QTEST_H_ */
diff --git a/drivers/net/virtio/virtio_qtest/virtio_qtest_dev.c b/drivers/net/virtio/virtio_qtest/virtio_qtest_dev.c
new file mode 100644
index 0000000..dec38ff
--- /dev/null
+++ b/drivers/net/virtio/virtio_qtest/virtio_qtest_dev.c
@@ -0,0 +1,393 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2016 IGEL Co.,Ltd. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of IGEL Co.,Ltd. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdint.h>
+#include <stdio.h>
+#include <errno.h>
+#include <unistd.h>
+
+#include <rte_malloc.h>
+#include <rte_kvargs.h>
+
+#include "../virtio_logs.h"
+#include "../virtio_ethdev.h"
+
+#include "qtest.h"
+#include "qtest_utils.h"
+#include "virtio_qtest_dev.h"
+#include "virtio_qtest_pci.h"
+
+#define ETH_VIRTIO_NET_ARG_QTEST_PATH           "qtest"
+#define ETH_VIRTIO_NET_ARG_IVSHMEM_PATH         "ivshmem"
+#define ETH_VIRTIO_NET_ARG_VIRTIO_NET_ADDR      "virtio-net-addr"
+#define ETH_VIRTIO_NET_ARG_IVSHMEM_ADDR         "ivshmem-addr"
+
+static const char *valid_qtest_args[] = {
+	ETH_VIRTIO_NET_ARG_QTEST_PATH,
+	ETH_VIRTIO_NET_ARG_IVSHMEM_PATH,
+	ETH_VIRTIO_NET_ARG_VIRTIO_NET_ADDR,
+	ETH_VIRTIO_NET_ARG_IVSHMEM_ADDR,
+	NULL
+};
+
+static int
+get_socket_path_arg(const char *key __rte_unused,
+		const char *value, void *extra_args)
+{
+	char **p;
+
+	if ((value == NULL) || (extra_args == NULL))
+		return -EINVAL;
+
+	p = extra_args;
+	*p = strdup(value);
+
+	if (*p == NULL)
+		return -1;
+
+	return 0;
+}
+
+static int
+get_pci_addr_arg(const char *key __rte_unused,
+		const char *value, void *extra_args)
+{
+	struct rte_pci_addr *addr = extra_args;
+
+	if ((value == NULL) || (extra_args == NULL))
+		return -EINVAL;
+
+	if (eal_parse_pci_DomBDF(value, addr) != 0)
+		return -1;
+
+	if (addr->domain != 0)
+		return -1;
+
+	return 0;
+}
+
+static int
+virtio_net_eth_dev_free(struct rte_eth_dev *eth_dev)
+{
+	struct virtio_hw *hw;
+	int ret;
+
+	ret = rte_eth_dev_release_port(eth_dev);
+	if (ret < 0) {
+		PMD_INIT_LOG(ERR, "cannot release a port\n");
+		return -1;
+	}
+
+	hw = eth_dev->data->dev_private;
+	rte_free(hw);
+
+	return 0;
+}
+
+static struct rte_eth_dev *
+virtio_net_eth_dev_alloc(const char *name)
+{
+	struct rte_eth_dev *eth_dev;
+	struct rte_eth_dev_data *data;
+	struct virtio_hw *hw;
+	int ret;
+
+	eth_dev = rte_eth_dev_allocate(name, RTE_ETH_DEV_VIRTUAL);
+	if (eth_dev == NULL) {
+		PMD_INIT_LOG(ERR, "cannot alloc a port\n");
+		return NULL;
+	}
+
+	data = eth_dev->data;
+
+	hw = rte_zmalloc(NULL, sizeof(*hw), 0);
+	if (hw == NULL) {
+		PMD_INIT_LOG(ERR, "malloc virtio_hw failed\n");
+		ret = rte_eth_dev_release_port(eth_dev);
+		if (ret < 0)
+			rte_panic("cannot release a port");
+		return NULL;
+	}
+
+	data->dev_private = hw;
+	data->numa_node = SOCKET_ID_ANY;
+	data->kdrv = RTE_KDRV_NONE;
+	data->dev_flags = RTE_ETH_DEV_DETACHABLE;
+	eth_dev->pci_dev = NULL;
+	eth_dev->driver = NULL;
+
+	return eth_dev;
+}
+
+static int
+virtio_net_eth_pmd_parse_socket_path(struct rte_kvargs *kvlist,
+		const char *option, char **path)
+{
+	int ret;
+
+	if (rte_kvargs_count(kvlist, option) == 1) {
+		ret = rte_kvargs_process(kvlist, option,
+				&get_socket_path_arg, path);
+		if (ret != 0) {
+			PMD_INIT_LOG(ERR,
+					"Failed to connect to %s socket", option);
+			return -1;
+		}
+	} else {
+		PMD_INIT_LOG(ERR, "No argument specified for %s", option);
+		return -1;
+	}
+
+	return 0;
+}
+
+static int
+virtio_net_eth_pmd_parse_pci_addr(struct rte_kvargs *kvlist,
+		const char *option, struct rte_pci_addr *addr,
+		struct rte_pci_addr *default_addr)
+{
+	int ret;
+
+	if (rte_kvargs_count(kvlist, option) == 1) {
+		ret = rte_kvargs_process(kvlist, option,
+				&get_pci_addr_arg, addr);
+		if (ret != 0) {
+			PMD_INIT_LOG(ERR,
+					"Specified invalid address in '%s'", option);
+			return -1;
+		}
+	} else
+		/* copy default pci address */
+		*addr = *default_addr;
+
+	return 0;
+}
+
+static int
+virtio_prepare_target_devices(struct qtest_pci_device *devices,
+			struct rte_kvargs *kvlist)
+{
+	struct qtest_pci_device *virtio_net, *ivshmem;
+	struct rte_pci_addr default_addr;
+	const struct rte_memseg *ms;
+	int ret;
+
+	ms = rte_eal_get_physmem_layout();
+	/* if EAL memory size isn't pow of 2, ivshmem will refuse it */
+	if ((ms[0].len & (ms[0].len - 1)) != 0) {
+		PMD_DRV_LOG(ERR, "memory size must be power of 2\n");
+		return -1;
+	}
+
+	/* EAL memory should be mapped under 16TB */
+	if ((uint64_t)ms[0].addr >> (VIRTIO_PCI_QUEUE_ADDR_SHIFT + 32)) {
+		PMD_DRV_LOG(ERR, "EAL memory shouldn't be mapped above 16TB");
+		return -1;
+	}
+
+	/* EAL memory should be mapped above IVSHMEM_MEMORY2_START */
+	if ((uint64_t)ms[0].addr < IVSHMEM_MEMORY2_START) {
+		PMD_DRV_LOG(ERR, "EAL memory shouldn't be mapped under 0x%x",
+				IVSHMEM_MEMORY2_START);
+		return -1;
+	}
+
+	virtio_net = &devices[0];
+	ivshmem = &devices[1];
+
+	virtio_net->name = "virtio-net";
+	virtio_net->device_id = VIRTIO_NET_DEVICE_ID;
+	virtio_net->vendor_id = VIRTIO_NET_VENDOR_ID;
+	virtio_net->init = qtest_init_pci_device;
+	virtio_net->bar[0].addr = PCI_BASE_ADDRESS_0;
+	virtio_net->bar[0].type = QTEST_PCI_BAR_IO;
+	virtio_net->bar[0].region_start = VIRTIO_NET_IO_START;
+	virtio_net->bar[1].addr = PCI_BASE_ADDRESS_1;
+	virtio_net->bar[1].type = QTEST_PCI_BAR_MEMORY_32;
+	virtio_net->bar[1].region_start = VIRTIO_NET_MEMORY1_START;
+	virtio_net->bar[4].addr = PCI_BASE_ADDRESS_4;
+	virtio_net->bar[4].type = QTEST_PCI_BAR_MEMORY_64;
+	virtio_net->bar[4].region_start = VIRTIO_NET_MEMORY2_START;
+
+	ivshmem->name = "ivshmem";
+	ivshmem->device_id = IVSHMEM_DEVICE_ID;
+	ivshmem->vendor_id = IVSHMEM_VENDOR_ID;
+	ivshmem->init = qtest_init_pci_device;
+	ivshmem->bar[0].addr = PCI_BASE_ADDRESS_0;
+	ivshmem->bar[0].type = QTEST_PCI_BAR_MEMORY_32;
+	ivshmem->bar[0].region_start = IVSHMEM_MEMORY1_START;
+	ivshmem->bar[2].addr = PCI_BASE_ADDRESS_2;
+	ivshmem->bar[2].type = QTEST_PCI_BAR_MEMORY_64;
+	/* In host mode, only one memory segment is vaild */
+	ivshmem->bar[2].region_start = (uint64_t)ms[0].addr;
+
+	/*
+	 * Set pci addresses specified by command line.
+	 * QTest utils will only check specified pci address.
+	 * If it's wrong, a target device won't be found.
+	 */
+	default_addr.domain = 0;
+	default_addr.bus = 0;
+	default_addr.function = 0;
+
+	default_addr.devid = 3;
+	ret = virtio_net_eth_pmd_parse_pci_addr(kvlist,
+			ETH_VIRTIO_NET_ARG_VIRTIO_NET_ADDR,
+			&virtio_net->specified_addr, &default_addr);
+	if (ret < 0)
+		return -1;
+
+	default_addr.devid = 4;
+	ret = virtio_net_eth_pmd_parse_pci_addr(kvlist,
+			ETH_VIRTIO_NET_ARG_IVSHMEM_ADDR,
+			&ivshmem->specified_addr, &default_addr);
+	if (ret < 0)
+		return -1;
+
+	return 0;
+}
+/*
+ * Initialization when "CONFIG_RTE_VIRTIO_VDEV_QTEST" is enabled.
+ */
+static int
+rte_qtest_virtio_pmd_init(const char *name, const char *params)
+{
+	struct rte_kvargs *kvlist;
+	struct virtio_hw *hw = NULL;
+	struct rte_eth_dev *eth_dev = NULL;
+	char *qtest_path = NULL, *ivshmem_path = NULL;
+	struct qtest_pci_device devices[QTEST_DEVICE_NUM];
+	int ret;
+
+	if (params == NULL || params[0] == '\0')
+		return -EINVAL;
+
+	kvlist = rte_kvargs_parse(params, valid_qtest_args);
+	if (kvlist == NULL) {
+		PMD_INIT_LOG(ERR, "error when parsing param");
+		return -EFAULT;
+	}
+
+	ret = virtio_net_eth_pmd_parse_socket_path(kvlist,
+			ETH_VIRTIO_NET_ARG_IVSHMEM_PATH, &ivshmem_path);
+	if (ret < 0)
+		goto error;
+
+	ret = virtio_net_eth_pmd_parse_socket_path(kvlist,
+			ETH_VIRTIO_NET_ARG_QTEST_PATH, &qtest_path);
+	if (ret < 0)
+		goto error;
+
+	ret = virtio_prepare_target_devices(devices, kvlist);
+	if (ret < 0)
+		goto error;
+
+	eth_dev = virtio_net_eth_dev_alloc(name);
+	if (eth_dev == NULL)
+		goto error;
+
+	hw = eth_dev->data->dev_private;
+	hw->virtio_user_dev = qtest_vdev_init(qtest_path, ivshmem_path,
+			devices, QTEST_DEVICE_NUM);
+	if (hw->virtio_user_dev == NULL)
+		goto error;
+
+	ret = qtest_vtpci_init(hw, &eth_dev->data->dev_flags);
+	if (ret  < 0)
+		goto error;
+
+	/* originally, this will be called in rte_eal_pci_probe() */
+	ret = eth_virtio_dev_init(eth_dev);
+	if (ret < 0)
+		goto error;
+
+	eth_dev->driver = NULL;
+	eth_dev->data->dev_flags |= RTE_ETH_DEV_DETACHABLE;
+	eth_dev->data->kdrv = RTE_KDRV_NONE;
+	eth_dev->data->drv_name = QTEST_DRV_NAME;
+
+	free(qtest_path);
+	free(ivshmem_path);
+	rte_kvargs_free(kvlist);
+	return 0;
+
+error:
+	if (hw != NULL && hw->virtio_user_dev != NULL)
+		qtest_vdev_uninit(hw->virtio_user_dev);
+	if (eth_dev)
+		virtio_net_eth_dev_free(eth_dev);
+	if (qtest_path)
+		free(qtest_path);
+	if (ivshmem_path)
+		free(ivshmem_path);
+	rte_kvargs_free(kvlist);
+	return -EFAULT;
+}
+
+static int
+rte_qtest_virtio_pmd_uninit(const char *name)
+{
+	struct rte_eth_dev *eth_dev;
+	struct virtio_hw *hw;
+	int ret;
+
+	if (name == NULL)
+		return -EINVAL;
+
+	/* find the ethdev entry */
+	eth_dev = rte_eth_dev_allocated(name);
+	if (eth_dev == NULL)
+		return -ENODEV;
+
+	ret = eth_virtio_dev_uninit(eth_dev);
+	if (ret != 0)
+		return -EFAULT;
+
+	hw = eth_dev->data->dev_private;
+	qtest_vdev_uninit(hw->virtio_user_dev);
+
+	ret = virtio_net_eth_dev_free(eth_dev);
+	if (ret != 0)
+		return -EFAULT;
+
+	return 0;
+}
+
+static struct rte_driver rte_qtest_virtio_driver = {
+	.name   = QTEST_DRV_NAME,
+	.type   = PMD_VDEV,
+	.init   = rte_qtest_virtio_pmd_init,
+	.uninit = rte_qtest_virtio_pmd_uninit,
+};
+
+PMD_REGISTER_DRIVER(rte_qtest_virtio_driver);
diff --git a/drivers/net/virtio/virtio_qtest/virtio_qtest_dev.h b/drivers/net/virtio/virtio_qtest/virtio_qtest_dev.h
new file mode 100644
index 0000000..82f1eec
--- /dev/null
+++ b/drivers/net/virtio/virtio_qtest/virtio_qtest_dev.h
@@ -0,0 +1,42 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2016 IGEL Co., Ltd. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of IGEL Co., Ltd. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _VIRTIO_QTEST_VDEV_H
+#define _VIRTIO_QTEST_VDEV_H
+
+#include <limits.h>
+#include "../virtio_pci.h"
+
+const struct virtio_pci_ops qtest_ops;
+
+#endif
diff --git a/drivers/net/virtio/virtqueue.h b/drivers/net/virtio/virtqueue.h
index 8ffc366..8edb85f 100644
--- a/drivers/net/virtio/virtqueue.h
+++ b/drivers/net/virtio/virtqueue.h
@@ -66,13 +66,13 @@ struct rte_mbuf;
 
 #define VIRTQUEUE_MAX_NAME_SZ 32
 
-#ifdef RTE_VIRTIO_VDEV
+#if defined(RTE_VIRTIO_VDEV) || defined(RTE_VIRTIO_QTEST)
 #define MBUF_DATA_DMA_ADDR(mb, offset) \
 	((uint64_t)((uintptr_t)(*(void **)((uintptr_t)mb + offset)) \
 			+ (mb)->data_off))
-#else /* RTE_VIRTIO_VDEV */
+#else /* RTE_VIRTIO_VDEV or RTE_VIRTIO_QTEST */
 #define MBUF_DATA_DMA_ADDR(mb, offset) rte_mbuf_data_dma_addr(mb)
-#endif /* RTE_VIRTIO_VDEV */
+#endif /* RTE_VIRTIO_VDEV or RTE_VIRTIO_QTEST */
 
 #define VTNET_SQ_RQ_QUEUE_IDX 0
 #define VTNET_SQ_TQ_QUEUE_IDX 1
