* One RX packet for ACK.
         */
        vq->vq_ring.desc[head].flags = VRING_DESC_F_NEXT;
-       vq->vq_ring.desc[head].addr = cvq->virtio_net_hdr_mz->phys_addr;
+       vq->vq_ring.desc[head].addr = cvq->virtio_net_hdr_mem;
        vq->vq_ring.desc[head].len = sizeof(struct virtio_net_ctrl_hdr);
        vq->vq_free_cnt--;
        i = vq->vq_ring.desc[head].next;
 
        for (k = 0; k < pkt_num; k++) {
                vq->vq_ring.desc[i].flags = VRING_DESC_F_NEXT;
-               vq->vq_ring.desc[i].addr = cvq->virtio_net_hdr_mz->phys_addr
+               vq->vq_ring.desc[i].addr = cvq->virtio_net_hdr_mem
                        + sizeof(struct virtio_net_ctrl_hdr)
                        + sizeof(ctrl->status) + sizeof(uint8_t)*sum;
                vq->vq_ring.desc[i].len = dlen[k];
        }
 
        vq->vq_ring.desc[i].flags = VRING_DESC_F_WRITE;
-       vq->vq_ring.desc[i].addr = cvq->virtio_net_hdr_mz->phys_addr
+       vq->vq_ring.desc[i].addr = cvq->virtio_net_hdr_mem
                        + sizeof(struct virtio_net_ctrl_hdr);
        vq->vq_ring.desc[i].len = sizeof(ctrl->status);
        vq->vq_free_cnt--;
        const struct rte_memzone *mz = NULL, *hdr_mz = NULL;
        unsigned int vq_size, size;
        struct virtio_hw *hw = dev->data->dev_private;
-       struct virtnet_rx *rxvq;
-       struct virtnet_tx *txvq;
-       struct virtnet_ctl *cvq;
+       struct virtnet_rx *rxvq = NULL;
+       struct virtnet_tx *txvq = NULL;
+       struct virtnet_ctl *cvq = NULL;
        struct virtqueue *vq;
        const char *queue_names[] = {"rvq", "txq", "cvq"};
        size_t sz_vq, sz_q = 0, sz_hdr_mz = 0;
                rxvq->mz = mz;
                *pvq = rxvq;
        } else if (queue_type == VTNET_TQ) {
-               struct virtio_tx_region *txr;
-               unsigned int i;
-
                txvq = (struct virtnet_tx *)RTE_PTR_ADD(vq, sz_vq);
                txvq->vq = vq;
                txvq->port_id = dev->data->port_id;
                txvq->virtio_net_hdr_mz = hdr_mz;
                txvq->virtio_net_hdr_mem = hdr_mz->phys_addr;
 
+               *pvq = txvq;
+       } else if (queue_type == VTNET_CQ) {
+               cvq = (struct virtnet_ctl *)RTE_PTR_ADD(vq, sz_vq);
+               cvq->vq = vq;
+               cvq->mz = mz;
+               cvq->virtio_net_hdr_mz = hdr_mz;
+               cvq->virtio_net_hdr_mem = hdr_mz->phys_addr;
+               memset(cvq->virtio_net_hdr_mz->addr, 0, PAGE_SIZE);
+               *pvq = cvq;
+       }
+
+       /* For virtio-user case (that is when dev->pci_dev is NULL), we use
+        * virtual address. And we need properly set _offset_, please see
+        * MBUF_DATA_DMA_ADDR in virtqueue.h for more information.
+        */
+       if (dev->pci_dev)
+               vq->offset = offsetof(struct rte_mbuf, buf_physaddr);
+       else {
+               vq->vq_ring_mem = (uintptr_t)mz->addr;
+               vq->offset = offsetof(struct rte_mbuf, buf_addr);
+               if (queue_type == VTNET_TQ)
+                       txvq->virtio_net_hdr_mem = (uintptr_t)hdr_mz->addr;
+               else if (queue_type == VTNET_CQ)
+                       cvq->virtio_net_hdr_mem = (uintptr_t)hdr_mz->addr;
+       }
+
+       if (queue_type == VTNET_TQ) {
+               struct virtio_tx_region *txr;
+               unsigned int i;
+
                txr = hdr_mz->addr;
                memset(txr, 0, vq_size * sizeof(*txr));
                for (i = 0; i < vq_size; i++) {
                        start_dp->len = hw->vtnet_hdr_size;
                        start_dp->flags = VRING_DESC_F_NEXT;
                }
-
-               *pvq = txvq;
-       } else if (queue_type == VTNET_CQ) {
-               cvq = (struct virtnet_ctl *)RTE_PTR_ADD(vq, sz_vq);
-               cvq->vq = vq;
-               cvq->mz = mz;
-               cvq->virtio_net_hdr_mz = hdr_mz;
-               cvq->virtio_net_hdr_mem = hdr_mz->phys_addr;
-               memset(cvq->virtio_net_hdr_mz->addr, 0, PAGE_SIZE);
-               *pvq = cvq;
        }
 
        if (hw->vtpci_ops->setup_queue(hw, vq) < 0) {
 
        vq->sw_ring[desc_idx] = cookie;
 
        start_dp = vq->vq_ring.desc;
-       start_dp[desc_idx].addr = (uint64_t)((uintptr_t)cookie->buf_physaddr +
-               RTE_PKTMBUF_HEADROOM - vq->hw->vtnet_hdr_size);
+       start_dp[desc_idx].addr = MBUF_DATA_DMA_ADDR(cookie, vq->offset) -
+                                 vq->hw->vtnet_hdr_size;
        start_dp[desc_idx].len = cookie->buf_len -
                RTE_PKTMBUF_HEADROOM + vq->hw->vtnet_hdr_size;
 
                *(uint64_t *)p = rxvq->mbuf_initializer;
 
                start_dp[i].addr =
-                       (uint64_t)((uintptr_t)sw_ring[i]->buf_physaddr +
-                       RTE_PKTMBUF_HEADROOM - vq->hw->vtnet_hdr_size);
+                       MBUF_DATA_DMA_ADDR(sw_ring[i], vq->offset) -
+                       vq->hw->vtnet_hdr_size;
                start_dp[i].len = sw_ring[i]->buf_len -
                        RTE_PKTMBUF_HEADROOM + vq->hw->vtnet_hdr_size;
        }
                        vq->vq_descx[desc_idx + i].cookie = tx_pkts[i];
                for (i = 0; i < nb_tail; i++) {
                        start_dp[desc_idx].addr =
-                               rte_mbuf_data_dma_addr(*tx_pkts);
+                               MBUF_DATA_DMA_ADDR(*tx_pkts, vq->offset);
                        start_dp[desc_idx].len = (*tx_pkts)->pkt_len;
                        tx_pkts++;
                        desc_idx++;
        for (i = 0; i < nb_commit; i++)
                vq->vq_descx[desc_idx + i].cookie = tx_pkts[i];
        for (i = 0; i < nb_commit; i++) {
-               start_dp[desc_idx].addr = rte_mbuf_data_dma_addr(*tx_pkts);
+               start_dp[desc_idx].addr =
+                       MBUF_DATA_DMA_ADDR(*tx_pkts, vq->offset);
                start_dp[desc_idx].len = (*tx_pkts)->pkt_len;
                tx_pkts++;
                desc_idx++;
 
 
 #define VIRTQUEUE_MAX_NAME_SZ 32
 
+#ifdef RTE_VIRTIO_USER
+#define MBUF_DATA_DMA_ADDR(mb, offset) \
+       ((uint64_t)((uintptr_t)(*(void **)((uintptr_t)mb + offset)) \
+                       + (mb)->data_off))
+#else /* RTE_VIRTIO_USER */
+#define MBUF_DATA_DMA_ADDR(mb, offset) rte_mbuf_data_dma_addr(mb)
+#endif /* RTE_VIRTIO_USER */
+
 #define VTNET_SQ_RQ_QUEUE_IDX 0
 #define VTNET_SQ_TQ_QUEUE_IDX 1
 #define VTNET_SQ_CQ_QUEUE_IDX 2
        unsigned int vq_ring_size;
 
        phys_addr_t vq_ring_mem; /**< physical address of vring */
+                               /**< use virtual address for virtio-user. */
 
        /**
         * Head of the free chain in the descriptor table. If
        uint16_t  vq_desc_head_idx;
        uint16_t  vq_desc_tail_idx;
        uint16_t  vq_queue_index;   /**< PCI queue index */
+       uint16_t offset; /**< relative offset to obtain addr in mbuf */
        uint16_t  *notify_addr;
        int configured;
        struct rte_mbuf **sw_ring;  /**< RX software ring. */