All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v1 00/10] vDPA support in qemu
@ 2020-06-22 15:37 Cindy Lu
  2020-06-22 15:37 ` [PATCH v1 01/10] net: introduce qemu_get_peer Cindy Lu
                   ` (11 more replies)
  0 siblings, 12 replies; 46+ messages in thread
From: Cindy Lu @ 2020-06-22 15:37 UTC (permalink / raw)
  To: mst, armbru, eblake, cohuck, jasowang
  Cc: mhabets, qemu-devel, rob.miller, saugatm, lulu, hanand, hch,
	eperezma, jgg, shahafs, kevin.tian, parav, vmireyno,
	cunming.liang, gdawar, jiri, xiao.w.wang, stefanha, zhihong.wang,
	aadam, rdunlap, maxime.coquelin, lingshan.zhu

vDPA device is a device that uses a datapath which complies with the
virtio specifications with vendor specific control path. vDPA devices
can be both physically located on the hardware or emulated by software.
This RFC introduce the vDPA support in qemu
TODO 
1) vIOMMU support
2) live migration support

Cindy Lu (8):
  net: introduce qemu_get_peer
  vhost_net: use the function qemu_get_peer
  vhost-backend: export the vhost backend helper
  vhsot_net: introduce set_config & get_config function
  vhost: introduce new VhostOps vhost_dev_start
  vhost: implement vhost_dev_start method
  vhost-vdpa: introduce vhost-vdpa backend
  vhost-vdpa: introduce vhost-vdpa net client

Jason Wang (2):
  virtio-bus: introduce queue_enabled method
  virtio-pci: implement queue_enabled method

 configure                         |  21 ++
 hw/net/vhost_net.c                |  46 +++-
 hw/net/virtio-net.c               |  19 +-
 hw/virtio/Makefile.objs           |   1 +
 hw/virtio/vhost-backend.c         |  40 ++-
 hw/virtio/vhost-vdpa.c            | 406 ++++++++++++++++++++++++++++++
 hw/virtio/vhost.c                 |  59 ++++-
 hw/virtio/virtio-pci.c            |  18 ++
 hw/virtio/virtio.c                |   6 +
 include/hw/virtio/vhost-backend.h |  36 ++-
 include/hw/virtio/vhost-vdpa.h    |  26 ++
 include/hw/virtio/vhost.h         |   8 +
 include/hw/virtio/virtio-bus.h    |   4 +
 include/net/net.h                 |   1 +
 include/net/vhost-vdpa.h          |  21 ++
 include/net/vhost_net.h           |   6 +-
 net/Makefile.objs                 |   2 +-
 net/clients.h                     |   2 +
 net/net.c                         |   9 +
 net/vhost-vdpa.c                  | 230 +++++++++++++++++
 qapi/net.json                     |  23 +-
 qemu-options.hx                   |  12 +
 22 files changed, 952 insertions(+), 44 deletions(-)
 create mode 100644 hw/virtio/vhost-vdpa.c
 create mode 100644 include/hw/virtio/vhost-vdpa.h
 create mode 100644 include/net/vhost-vdpa.h
 create mode 100644 net/vhost-vdpa.c

-- 
2.21.1



^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH v1 01/10] net: introduce qemu_get_peer
  2020-06-22 15:37 [PATCH v1 00/10] vDPA support in qemu Cindy Lu
@ 2020-06-22 15:37 ` Cindy Lu
  2020-06-23  7:10   ` Jason Wang
  2020-06-22 15:37 ` [PATCH v1 02/10] vhost_net: use the function qemu_get_peer Cindy Lu
                   ` (10 subsequent siblings)
  11 siblings, 1 reply; 46+ messages in thread
From: Cindy Lu @ 2020-06-22 15:37 UTC (permalink / raw)
  To: mst, armbru, eblake, cohuck, jasowang
  Cc: mhabets, qemu-devel, rob.miller, saugatm, lulu, hanand, hch,
	eperezma, jgg, shahafs, kevin.tian, parav, vmireyno,
	cunming.liang, gdawar, jiri, xiao.w.wang, stefanha, zhihong.wang,
	aadam, rdunlap, maxime.coquelin, lingshan.zhu

This is a small function that can get the peer
from given NetClientState and queue_index

Signed-off-by: Cindy Lu <lulu@redhat.com>
---
 include/net/net.h | 1 +
 net/net.c         | 6 ++++++
 2 files changed, 7 insertions(+)

diff --git a/include/net/net.h b/include/net/net.h
index 39085d9444..e7ef42d62b 100644
--- a/include/net/net.h
+++ b/include/net/net.h
@@ -176,6 +176,7 @@ void hmp_info_network(Monitor *mon, const QDict *qdict);
 void net_socket_rs_init(SocketReadState *rs,
                         SocketReadStateFinalize *finalize,
                         bool vnet_hdr);
+NetClientState *qemu_get_peer(NetClientState *nc, int queue_index);
 
 /* NIC info */
 
diff --git a/net/net.c b/net/net.c
index 38778e831d..599fb61028 100644
--- a/net/net.c
+++ b/net/net.c
@@ -324,6 +324,12 @@ void *qemu_get_nic_opaque(NetClientState *nc)
 
     return nic->opaque;
 }
+NetClientState *qemu_get_peer(NetClientState *nc, int queue_index)
+{
+    assert(nc != NULL);
+    NetClientState *ncs = nc + queue_index;
+    return ncs->peer;
+}
 
 static void qemu_cleanup_net_client(NetClientState *nc)
 {
-- 
2.21.1



^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH v1 02/10] vhost_net: use the function qemu_get_peer
  2020-06-22 15:37 [PATCH v1 00/10] vDPA support in qemu Cindy Lu
  2020-06-22 15:37 ` [PATCH v1 01/10] net: introduce qemu_get_peer Cindy Lu
@ 2020-06-22 15:37 ` Cindy Lu
  2020-06-24 13:20   ` Laurent Vivier
  2020-06-22 15:37 ` [PATCH v1 03/10] virtio-bus: introduce queue_enabled method Cindy Lu
                   ` (9 subsequent siblings)
  11 siblings, 1 reply; 46+ messages in thread
From: Cindy Lu @ 2020-06-22 15:37 UTC (permalink / raw)
  To: mst, armbru, eblake, cohuck, jasowang
  Cc: mhabets, qemu-devel, rob.miller, saugatm, lulu, hanand, hch,
	eperezma, jgg, shahafs, kevin.tian, parav, vmireyno,
	cunming.liang, gdawar, jiri, xiao.w.wang, stefanha, zhihong.wang,
	aadam, rdunlap, maxime.coquelin, lingshan.zhu

user the qemu_get_peer to replace the old process

Signed-off-by: Cindy Lu <lulu@redhat.com>
---
 hw/net/vhost_net.c | 16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c
index 6b82803fa7..4096d64aaf 100644
--- a/hw/net/vhost_net.c
+++ b/hw/net/vhost_net.c
@@ -306,7 +306,9 @@ int vhost_net_start(VirtIODevice *dev, NetClientState *ncs,
     BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(dev)));
     VirtioBusState *vbus = VIRTIO_BUS(qbus);
     VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(vbus);
+    struct vhost_net *net;
     int r, e, i;
+    NetClientState *peer;
 
     if (!k->set_guest_notifiers) {
         error_report("binding does not support guest notifiers");
@@ -314,9 +316,9 @@ int vhost_net_start(VirtIODevice *dev, NetClientState *ncs,
     }
 
     for (i = 0; i < total_queues; i++) {
-        struct vhost_net *net;
 
-        net = get_vhost_net(ncs[i].peer);
+        peer = qemu_get_peer(ncs, i);
+        net = get_vhost_net(peer);
         vhost_net_set_vq_index(net, i * 2);
 
         /* Suppress the masking guest notifiers on vhost user
@@ -335,15 +337,16 @@ int vhost_net_start(VirtIODevice *dev, NetClientState *ncs,
     }
 
     for (i = 0; i < total_queues; i++) {
-        r = vhost_net_start_one(get_vhost_net(ncs[i].peer), dev);
+        peer = qemu_get_peer(ncs, i);
+        r = vhost_net_start_one(get_vhost_net(peer), dev);
 
         if (r < 0) {
             goto err_start;
         }
 
-        if (ncs[i].peer->vring_enable) {
+        if (peer->vring_enable) {
             /* restore vring enable state */
-            r = vhost_set_vring_enable(ncs[i].peer, ncs[i].peer->vring_enable);
+            r = vhost_set_vring_enable(peer, peer->vring_enable);
 
             if (r < 0) {
                 goto err_start;
@@ -355,7 +358,8 @@ int vhost_net_start(VirtIODevice *dev, NetClientState *ncs,
 
 err_start:
     while (--i >= 0) {
-        vhost_net_stop_one(get_vhost_net(ncs[i].peer), dev);
+        peer = qemu_get_peer(ncs , i);
+        vhost_net_stop_one(get_vhost_net(peer), dev);
     }
     e = k->set_guest_notifiers(qbus->parent, total_queues * 2, false);
     if (e < 0) {
-- 
2.21.1



^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH v1 03/10] virtio-bus: introduce queue_enabled method
  2020-06-22 15:37 [PATCH v1 00/10] vDPA support in qemu Cindy Lu
  2020-06-22 15:37 ` [PATCH v1 01/10] net: introduce qemu_get_peer Cindy Lu
  2020-06-22 15:37 ` [PATCH v1 02/10] vhost_net: use the function qemu_get_peer Cindy Lu
@ 2020-06-22 15:37 ` Cindy Lu
  2020-06-22 15:37 ` [PATCH v1 04/10] virtio-pci: implement " Cindy Lu
                   ` (8 subsequent siblings)
  11 siblings, 0 replies; 46+ messages in thread
From: Cindy Lu @ 2020-06-22 15:37 UTC (permalink / raw)
  To: mst, armbru, eblake, cohuck, jasowang
  Cc: mhabets, qemu-devel, rob.miller, saugatm, lulu, hanand, hch,
	eperezma, jgg, shahafs, kevin.tian, parav, vmireyno,
	cunming.liang, gdawar, jiri, xiao.w.wang, stefanha, zhihong.wang,
	aadam, rdunlap, maxime.coquelin, lingshan.zhu

From: Jason Wang <jasowang@redhat.com>

This patch introduces queue_enabled() method which allows the
transport to implement its own way to report whether or not a queue is
enabled.

Signed-off-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: Cindy Lu <lulu@redhat.com>
---
 hw/virtio/virtio.c             | 6 ++++++
 include/hw/virtio/virtio-bus.h | 4 ++++
 2 files changed, 10 insertions(+)

diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index b6c8ef5bc0..445a4ed760 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -3285,6 +3285,12 @@ hwaddr virtio_queue_get_desc_addr(VirtIODevice *vdev, int n)
 
 bool virtio_queue_enabled(VirtIODevice *vdev, int n)
 {
+    BusState *qbus = qdev_get_parent_bus(DEVICE(vdev));
+    VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
+
+    if (k->queue_enabled) {
+        return k->queue_enabled(qbus->parent, n);
+    }
     return virtio_queue_get_desc_addr(vdev, n) != 0;
 }
 
diff --git a/include/hw/virtio/virtio-bus.h b/include/hw/virtio/virtio-bus.h
index 38c9399cd4..0f6f215925 100644
--- a/include/hw/virtio/virtio-bus.h
+++ b/include/hw/virtio/virtio-bus.h
@@ -83,6 +83,10 @@ typedef struct VirtioBusClass {
      */
     int (*ioeventfd_assign)(DeviceState *d, EventNotifier *notifier,
                             int n, bool assign);
+    /*
+     * Whether queue number n is enabled.
+     */
+    bool (*queue_enabled)(DeviceState *d, int n);
     /*
      * Does the transport have variable vring alignment?
      * (ie can it ever call virtio_queue_set_align()?)
-- 
2.21.1



^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH v1 04/10] virtio-pci: implement queue_enabled method
  2020-06-22 15:37 [PATCH v1 00/10] vDPA support in qemu Cindy Lu
                   ` (2 preceding siblings ...)
  2020-06-22 15:37 ` [PATCH v1 03/10] virtio-bus: introduce queue_enabled method Cindy Lu
@ 2020-06-22 15:37 ` Cindy Lu
  2020-06-23  7:13   ` Jason Wang
  2020-06-24 13:24   ` Laurent Vivier
  2020-06-22 15:37 ` [PATCH v1 05/10] vhost-backend: export the vhost backend helper Cindy Lu
                   ` (7 subsequent siblings)
  11 siblings, 2 replies; 46+ messages in thread
From: Cindy Lu @ 2020-06-22 15:37 UTC (permalink / raw)
  To: mst, armbru, eblake, cohuck, jasowang
  Cc: mhabets, qemu-devel, rob.miller, saugatm, lulu, hanand, hch,
	eperezma, jgg, shahafs, kevin.tian, parav, vmireyno,
	cunming.liang, gdawar, jiri, xiao.w.wang, stefanha, zhihong.wang,
	aadam, rdunlap, maxime.coquelin, lingshan.zhu

From: Jason Wang <jasowang@redhat.com>

With version 1, we can detect whether a queue is enabled via
queue_enabled.

Signed-off-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: Cindy Lu <lulu@redhat.com>
---
 hw/virtio/virtio-pci.c | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index 4cb784389c..3918aa9f6c 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -1107,6 +1107,23 @@ static AddressSpace *virtio_pci_get_dma_as(DeviceState *d)
     return pci_get_address_space(dev);
 }
 
+static bool  virtio_queue_check_enabled(VirtIODevice *vdev, int n)
+{
+    return  virtio_queue_get_desc_addr(vdev, n) != 0;
+}
+
+static bool virtio_pci_queue_enabled(DeviceState *d, int n)
+{
+    VirtIOPCIProxy *proxy = VIRTIO_PCI(d);
+    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
+
+    if (virtio_vdev_has_feature(vdev, VIRTIO_F_VERSION_1)) {
+        return proxy->vqs[vdev->queue_sel].enabled;
+    }
+
+    return  virtio_queue_check_enabled(vdev, n);
+}
+
 static int virtio_pci_add_mem_cap(VirtIOPCIProxy *proxy,
                                    struct virtio_pci_cap *cap)
 {
@@ -2059,6 +2076,7 @@ static void virtio_pci_bus_class_init(ObjectClass *klass, void *data)
     k->ioeventfd_enabled = virtio_pci_ioeventfd_enabled;
     k->ioeventfd_assign = virtio_pci_ioeventfd_assign;
     k->get_dma_as = virtio_pci_get_dma_as;
+    k->queue_enabled = virtio_pci_queue_enabled;
 }
 
 static const TypeInfo virtio_pci_bus_info = {
-- 
2.21.1



^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH v1 05/10] vhost-backend: export the vhost backend helper
  2020-06-22 15:37 [PATCH v1 00/10] vDPA support in qemu Cindy Lu
                   ` (3 preceding siblings ...)
  2020-06-22 15:37 ` [PATCH v1 04/10] virtio-pci: implement " Cindy Lu
@ 2020-06-22 15:37 ` Cindy Lu
  2020-06-25 15:07   ` Laurent Vivier
  2020-06-22 15:37 ` [PATCH v1 06/10] vhsot_net: introduce set_config & get_config function Cindy Lu
                   ` (6 subsequent siblings)
  11 siblings, 1 reply; 46+ messages in thread
From: Cindy Lu @ 2020-06-22 15:37 UTC (permalink / raw)
  To: mst, armbru, eblake, cohuck, jasowang
  Cc: mhabets, qemu-devel, rob.miller, saugatm, lulu, hanand, hch,
	eperezma, jgg, shahafs, kevin.tian, parav, vmireyno,
	cunming.liang, gdawar, jiri, xiao.w.wang, stefanha, zhihong.wang,
	aadam, rdunlap, maxime.coquelin, lingshan.zhu

export the helper then we can reuse them in other backend

Signed-off-by: Cindy Lu <lulu@redhat.com>
---
 hw/virtio/vhost-backend.c         | 18 +++++++++---------
 include/hw/virtio/vhost-backend.h | 28 ++++++++++++++++++++++++++++
 2 files changed, 37 insertions(+), 9 deletions(-)

diff --git a/hw/virtio/vhost-backend.c b/hw/virtio/vhost-backend.c
index 48905383f8..660e9e8588 100644
--- a/hw/virtio/vhost-backend.c
+++ b/hw/virtio/vhost-backend.c
@@ -89,7 +89,7 @@ static int vhost_kernel_scsi_get_abi_version(struct vhost_dev *dev, int *version
     return vhost_kernel_call(dev, VHOST_SCSI_GET_ABI_VERSION, version);
 }
 
-static int vhost_kernel_set_log_base(struct vhost_dev *dev, uint64_t base,
+int vhost_kernel_set_log_base(struct vhost_dev *dev, uint64_t base,
                                      struct vhost_log *log)
 {
     return vhost_kernel_call(dev, VHOST_SET_LOG_BASE, &base);
@@ -101,7 +101,7 @@ static int vhost_kernel_set_mem_table(struct vhost_dev *dev,
     return vhost_kernel_call(dev, VHOST_SET_MEM_TABLE, mem);
 }
 
-static int vhost_kernel_set_vring_addr(struct vhost_dev *dev,
+int vhost_kernel_set_vring_addr(struct vhost_dev *dev,
                                        struct vhost_vring_addr *addr)
 {
     return vhost_kernel_call(dev, VHOST_SET_VRING_ADDR, addr);
@@ -113,31 +113,31 @@ static int vhost_kernel_set_vring_endian(struct vhost_dev *dev,
     return vhost_kernel_call(dev, VHOST_SET_VRING_ENDIAN, ring);
 }
 
-static int vhost_kernel_set_vring_num(struct vhost_dev *dev,
+int vhost_kernel_set_vring_num(struct vhost_dev *dev,
                                       struct vhost_vring_state *ring)
 {
     return vhost_kernel_call(dev, VHOST_SET_VRING_NUM, ring);
 }
 
-static int vhost_kernel_set_vring_base(struct vhost_dev *dev,
+int vhost_kernel_set_vring_base(struct vhost_dev *dev,
                                        struct vhost_vring_state *ring)
 {
     return vhost_kernel_call(dev, VHOST_SET_VRING_BASE, ring);
 }
 
-static int vhost_kernel_get_vring_base(struct vhost_dev *dev,
+int vhost_kernel_get_vring_base(struct vhost_dev *dev,
                                        struct vhost_vring_state *ring)
 {
     return vhost_kernel_call(dev, VHOST_GET_VRING_BASE, ring);
 }
 
-static int vhost_kernel_set_vring_kick(struct vhost_dev *dev,
+int vhost_kernel_set_vring_kick(struct vhost_dev *dev,
                                        struct vhost_vring_file *file)
 {
     return vhost_kernel_call(dev, VHOST_SET_VRING_KICK, file);
 }
 
-static int vhost_kernel_set_vring_call(struct vhost_dev *dev,
+int vhost_kernel_set_vring_call(struct vhost_dev *dev,
                                        struct vhost_vring_file *file)
 {
     return vhost_kernel_call(dev, VHOST_SET_VRING_CALL, file);
@@ -155,13 +155,13 @@ static int vhost_kernel_set_features(struct vhost_dev *dev,
     return vhost_kernel_call(dev, VHOST_SET_FEATURES, &features);
 }
 
-static int vhost_kernel_get_features(struct vhost_dev *dev,
+int vhost_kernel_get_features(struct vhost_dev *dev,
                                      uint64_t *features)
 {
     return vhost_kernel_call(dev, VHOST_GET_FEATURES, features);
 }
 
-static int vhost_kernel_set_owner(struct vhost_dev *dev)
+int vhost_kernel_set_owner(struct vhost_dev *dev)
 {
     return vhost_kernel_call(dev, VHOST_SET_OWNER, NULL);
 }
diff --git a/include/hw/virtio/vhost-backend.h b/include/hw/virtio/vhost-backend.h
index 6f6670783f..300b59c172 100644
--- a/include/hw/virtio/vhost-backend.h
+++ b/include/hw/virtio/vhost-backend.h
@@ -172,4 +172,32 @@ int vhost_backend_handle_iotlb_msg(struct vhost_dev *dev,
 
 int vhost_user_gpu_set_socket(struct vhost_dev *dev, int fd);
 
+
+int vhost_kernel_set_log_base(struct vhost_dev *dev, uint64_t base,
+                                     struct vhost_log *log);
+
+int vhost_kernel_set_vring_addr(struct vhost_dev *dev,
+                                       struct vhost_vring_addr *addr);
+
+int vhost_kernel_set_vring_num(struct vhost_dev *dev,
+                                      struct vhost_vring_state *ring);
+
+int vhost_kernel_set_vring_base(struct vhost_dev *dev,
+                                       struct vhost_vring_state *ring);
+
+int vhost_kernel_get_vring_base(struct vhost_dev *dev,
+                                       struct vhost_vring_state *ring);
+
+int vhost_kernel_set_vring_kick(struct vhost_dev *dev,
+                                       struct vhost_vring_file *file);
+
+int vhost_kernel_set_vring_call(struct vhost_dev *dev,
+                                       struct vhost_vring_file *file);
+
+int vhost_kernel_set_owner(struct vhost_dev *dev);
+
+int vhost_kernel_get_features(struct vhost_dev *dev,
+                                     uint64_t *features);
+
+
 #endif /* VHOST_BACKEND_H */
-- 
2.21.1



^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH v1 06/10] vhsot_net: introduce set_config & get_config function
  2020-06-22 15:37 [PATCH v1 00/10] vDPA support in qemu Cindy Lu
                   ` (4 preceding siblings ...)
  2020-06-22 15:37 ` [PATCH v1 05/10] vhost-backend: export the vhost backend helper Cindy Lu
@ 2020-06-22 15:37 ` Cindy Lu
  2020-06-23  7:18   ` Jason Wang
  2020-06-22 15:37 ` [PATCH v1 07/10] vhost: introduce new VhostOps vhost_dev_start Cindy Lu
                   ` (5 subsequent siblings)
  11 siblings, 1 reply; 46+ messages in thread
From: Cindy Lu @ 2020-06-22 15:37 UTC (permalink / raw)
  To: mst, armbru, eblake, cohuck, jasowang
  Cc: mhabets, qemu-devel, rob.miller, saugatm, lulu, hanand, hch,
	eperezma, jgg, shahafs, kevin.tian, parav, vmireyno,
	cunming.liang, gdawar, jiri, xiao.w.wang, stefanha, zhihong.wang,
	aadam, rdunlap, maxime.coquelin, lingshan.zhu

This patch introduces set_config & get_config  method which allows
vhost_net set/get the config to backend

Signed-off-by: Cindy Lu <lulu@redhat.com>
---
 hw/net/vhost_net.c      | 11 +++++++++++
 include/net/vhost_net.h |  5 +++++
 2 files changed, 16 insertions(+)

diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c
index 4096d64aaf..04cc3db264 100644
--- a/hw/net/vhost_net.c
+++ b/hw/net/vhost_net.c
@@ -111,6 +111,17 @@ uint64_t vhost_net_get_features(struct vhost_net *net, uint64_t features)
             features);
 }
 
+int vhost_net_get_config(struct vhost_net *net,  uint8_t *config,
+                         uint32_t config_len)
+{
+    return vhost_dev_get_config(&net->dev, config, config_len);
+}
+int vhost_net_set_config(struct vhost_net *net, const uint8_t *data,
+                         uint32_t offset, uint32_t size, uint32_t flags)
+{
+    return vhost_dev_set_config(&net->dev, data, offset, size, flags);
+}
+
 void vhost_net_ack_features(struct vhost_net *net, uint64_t features)
 {
     net->dev.acked_features = net->dev.backend_features;
diff --git a/include/net/vhost_net.h b/include/net/vhost_net.h
index 77e47398c4..abfb0e8e68 100644
--- a/include/net/vhost_net.h
+++ b/include/net/vhost_net.h
@@ -27,6 +27,11 @@ void vhost_net_cleanup(VHostNetState *net);
 
 uint64_t vhost_net_get_features(VHostNetState *net, uint64_t features);
 void vhost_net_ack_features(VHostNetState *net, uint64_t features);
+int vhost_net_get_config(struct vhost_net *net,  uint8_t *config,
+                         uint32_t config_len);
+
+int vhost_net_set_config(struct vhost_net *net, const uint8_t *data,
+                         uint32_t offset, uint32_t size, uint32_t flags);
 
 bool vhost_net_virtqueue_pending(VHostNetState *net, int n);
 void vhost_net_virtqueue_mask(VHostNetState *net, VirtIODevice *dev,
-- 
2.21.1



^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH v1 07/10] vhost: introduce new VhostOps vhost_dev_start
  2020-06-22 15:37 [PATCH v1 00/10] vDPA support in qemu Cindy Lu
                   ` (5 preceding siblings ...)
  2020-06-22 15:37 ` [PATCH v1 06/10] vhsot_net: introduce set_config & get_config function Cindy Lu
@ 2020-06-22 15:37 ` Cindy Lu
  2020-06-22 15:37 ` [PATCH v1 08/10] vhost: implement vhost_dev_start method Cindy Lu
                   ` (4 subsequent siblings)
  11 siblings, 0 replies; 46+ messages in thread
From: Cindy Lu @ 2020-06-22 15:37 UTC (permalink / raw)
  To: mst, armbru, eblake, cohuck, jasowang
  Cc: mhabets, qemu-devel, rob.miller, saugatm, lulu, hanand, hch,
	eperezma, jgg, shahafs, kevin.tian, parav, vmireyno,
	cunming.liang, gdawar, jiri, xiao.w.wang, stefanha, zhihong.wang,
	aadam, rdunlap, maxime.coquelin, lingshan.zhu

This patch introduces vhost_dev_start() callback which allows the
vhost_net set the start/stop status to backend

Signed-off-by: Cindy Lu <lulu@redhat.com>
---
 include/hw/virtio/vhost-backend.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/include/hw/virtio/vhost-backend.h b/include/hw/virtio/vhost-backend.h
index 300b59c172..c1384bd2c7 100644
--- a/include/hw/virtio/vhost-backend.h
+++ b/include/hw/virtio/vhost-backend.h
@@ -112,6 +112,7 @@ typedef int (*vhost_get_inflight_fd_op)(struct vhost_dev *dev,
 typedef int (*vhost_set_inflight_fd_op)(struct vhost_dev *dev,
                                         struct vhost_inflight *inflight);
 
+typedef int (*vhost_dev_start_op)(struct vhost_dev *dev, bool started);
 typedef struct VhostOps {
     VhostBackendType backend_type;
     vhost_backend_init vhost_backend_init;
@@ -152,6 +153,7 @@ typedef struct VhostOps {
     vhost_backend_mem_section_filter_op vhost_backend_mem_section_filter;
     vhost_get_inflight_fd_op vhost_get_inflight_fd;
     vhost_set_inflight_fd_op vhost_set_inflight_fd;
+    vhost_dev_start_op vhost_dev_start;
 } VhostOps;
 
 extern const VhostOps user_ops;
-- 
2.21.1



^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH v1 08/10] vhost: implement vhost_dev_start method
  2020-06-22 15:37 [PATCH v1 00/10] vDPA support in qemu Cindy Lu
                   ` (6 preceding siblings ...)
  2020-06-22 15:37 ` [PATCH v1 07/10] vhost: introduce new VhostOps vhost_dev_start Cindy Lu
@ 2020-06-22 15:37 ` Cindy Lu
  2020-06-23  7:21   ` Jason Wang
  2020-06-25 14:35   ` Laurent Vivier
  2020-06-22 15:37 ` [PATCH v1 09/10] vhost-vdpa: introduce vhost-vdpa backend Cindy Lu
                   ` (3 subsequent siblings)
  11 siblings, 2 replies; 46+ messages in thread
From: Cindy Lu @ 2020-06-22 15:37 UTC (permalink / raw)
  To: mst, armbru, eblake, cohuck, jasowang
  Cc: mhabets, qemu-devel, rob.miller, saugatm, lulu, hanand, hch,
	eperezma, jgg, shahafs, kevin.tian, parav, vmireyno,
	cunming.liang, gdawar, jiri, xiao.w.wang, stefanha, zhihong.wang,
	aadam, rdunlap, maxime.coquelin, lingshan.zhu

use the vhost_dev_start callback to send the status to backend

Signed-off-by: Cindy Lu <lulu@redhat.com>
---
 hw/virtio/vhost.c         | 17 +++++++++++++++++
 include/hw/virtio/vhost.h |  2 ++
 2 files changed, 19 insertions(+)

diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
index 01ebe12f28..bfd7f9ce1f 100644
--- a/hw/virtio/vhost.c
+++ b/hw/virtio/vhost.c
@@ -744,6 +744,7 @@ static void vhost_iommu_region_del(MemoryListener *listener,
     }
 }
 
+
 static int vhost_virtqueue_set_addr(struct vhost_dev *dev,
                                     struct vhost_virtqueue *vq,
                                     unsigned idx, bool enable_log)
@@ -1661,6 +1662,11 @@ int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev)
         }
     }
 
+    r = vhost_set_start(hdev, true);
+    if (r) {
+        goto fail_log;
+    }
+
     if (vhost_dev_has_iommu(hdev)) {
         hdev->vhost_ops->vhost_set_iotlb_callback(hdev, true);
 
@@ -1697,6 +1703,8 @@ void vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev)
     /* should only be called after backend is connected */
     assert(hdev->vhost_ops);
 
+    vhost_set_start(hdev, false);
+
     for (i = 0; i < hdev->nvqs; ++i) {
         vhost_virtqueue_stop(hdev,
                              vdev,
@@ -1722,3 +1730,12 @@ int vhost_net_set_backend(struct vhost_dev *hdev,
 
     return -1;
 }
+
+int vhost_set_start(struct vhost_dev *hdev, bool started)
+{
+
+    if (hdev->vhost_ops->vhost_dev_start) {
+        hdev->vhost_ops->vhost_dev_start(hdev, started);
+    }
+    return 0;
+}
diff --git a/include/hw/virtio/vhost.h b/include/hw/virtio/vhost.h
index 085450c6f8..59ea53f8c2 100644
--- a/include/hw/virtio/vhost.h
+++ b/include/hw/virtio/vhost.h
@@ -92,6 +92,7 @@ struct vhost_dev {
     const VhostDevConfigOps *config_ops;
 };
 
+
 int vhost_dev_init(struct vhost_dev *hdev, void *opaque,
                    VhostBackendType backend_type,
                    uint32_t busyloop_timeout);
@@ -137,4 +138,5 @@ int vhost_dev_set_inflight(struct vhost_dev *dev,
                            struct vhost_inflight *inflight);
 int vhost_dev_get_inflight(struct vhost_dev *dev, uint16_t queue_size,
                            struct vhost_inflight *inflight);
+int vhost_set_start(struct vhost_dev *dev, bool started);
 #endif
-- 
2.21.1



^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH v1 09/10] vhost-vdpa: introduce vhost-vdpa backend
  2020-06-22 15:37 [PATCH v1 00/10] vDPA support in qemu Cindy Lu
                   ` (7 preceding siblings ...)
  2020-06-22 15:37 ` [PATCH v1 08/10] vhost: implement vhost_dev_start method Cindy Lu
@ 2020-06-22 15:37 ` Cindy Lu
  2020-06-23  7:31   ` Jason Wang
                     ` (2 more replies)
  2020-06-22 15:37 ` [PATCH v1 10/10] vhost-vdpa: introduce vhost-vdpa net client Cindy Lu
                   ` (2 subsequent siblings)
  11 siblings, 3 replies; 46+ messages in thread
From: Cindy Lu @ 2020-06-22 15:37 UTC (permalink / raw)
  To: mst, armbru, eblake, cohuck, jasowang
  Cc: mhabets, qemu-devel, rob.miller, saugatm, lulu, hanand, hch,
	eperezma, jgg, shahafs, kevin.tian, parav, vmireyno,
	cunming.liang, gdawar, jiri, xiao.w.wang, stefanha, zhihong.wang,
	Tiwei Bie, aadam, rdunlap, maxime.coquelin, lingshan.zhu

Currently we have 2 types of vhost backends in QEMU: vhost kernel and
vhost-user. The above patch provides a generic device for vDPA purpose,
this vDPA device exposes to user space a non-vendor-specific configuration
interface for setting up a vhost HW accelerator, this patch set introduces
a third vhost backend called vhost-vdpa based on the vDPA interface.

Vhost-vdpa usage:

qemu-system-x86_64 -cpu host -enable-kvm \
    ......
    -netdev type=vhost-vdpa,vhostdev=/dev/vhost-vdpa-id,id=vhost-vdpa0 \
    -device virtio-net-pci,netdev=vhost-vdpa0,page-per-vq=on \

Signed-off-by: Lingshan zhu <lingshan.zhu@intel.com>
Signed-off-by: Tiwei Bie <tiwei.bie@intel.com>
Signed-off-by: Cindy Lu <lulu@redhat.com>
---
 configure                         |  21 ++
 hw/net/vhost_net.c                |  19 +-
 hw/net/virtio-net.c               |  19 +-
 hw/virtio/Makefile.objs           |   1 +
 hw/virtio/vhost-backend.c         |  22 +-
 hw/virtio/vhost-vdpa.c            | 406 ++++++++++++++++++++++++++++++
 hw/virtio/vhost.c                 |  42 +++-
 include/hw/virtio/vhost-backend.h |   6 +-
 include/hw/virtio/vhost-vdpa.h    |  26 ++
 include/hw/virtio/vhost.h         |   6 +
 qemu-options.hx                   |  12 +
 11 files changed, 555 insertions(+), 25 deletions(-)
 create mode 100644 hw/virtio/vhost-vdpa.c
 create mode 100644 include/hw/virtio/vhost-vdpa.h

diff --git a/configure b/configure
index 23b5e93752..53679ee57f 100755
--- a/configure
+++ b/configure
@@ -1557,6 +1557,10 @@ for opt do
   ;;
   --enable-vhost-user) vhost_user="yes"
   ;;
+  --disable-vhost-vdpa) vhost_vdpa="no"
+  ;;
+  --enable-vhost-vdpa) vhost_vdpa="yes"
+  ;;
   --disable-vhost-kernel) vhost_kernel="no"
   ;;
   --enable-vhost-kernel) vhost_kernel="yes"
@@ -1846,6 +1850,7 @@ disabled with --disable-FEATURE, default is enabled if available:
   vhost-crypto    vhost-user-crypto backend support
   vhost-kernel    vhost kernel backend support
   vhost-user      vhost-user backend support
+  vhost-vdpa      vhost-vdpa kernel backend support
   spice           spice
   rbd             rados block device (rbd)
   libiscsi        iscsi support
@@ -2336,6 +2341,10 @@ test "$vhost_user" = "" && vhost_user=yes
 if test "$vhost_user" = "yes" && test "$mingw32" = "yes"; then
   error_exit "vhost-user isn't available on win32"
 fi
+test "$vhost_vdpa" = "" && vhost_vdpa=$linux
+if test "$vhost_vdpa" = "yes" && test "$linux" != "yes"; then
+  error_exit "vhost-vdpa is only available on Linux"
+fi
 test "$vhost_kernel" = "" && vhost_kernel=$linux
 if test "$vhost_kernel" = "yes" && test "$linux" != "yes"; then
   error_exit "vhost-kernel is only available on Linux"
@@ -2364,6 +2373,11 @@ test "$vhost_user_fs" = "" && vhost_user_fs=$vhost_user
 if test "$vhost_user_fs" = "yes" && test "$vhost_user" = "no"; then
   error_exit "--enable-vhost-user-fs requires --enable-vhost-user"
 fi
+#vhost-vdpa backends
+test "$vhost_net_vdpa" = "" && vhost_net_vdpa=$vhost_vdpa
+if test "$vhost_net_vdpa" = "yes" && test "$vhost_vdpa" = "no"; then
+  error_exit "--enable-vhost-net-vdpa requires --enable-vhost-vdpa"
+fi
 
 # OR the vhost-kernel and vhost-user values for simplicity
 if test "$vhost_net" = ""; then
@@ -6673,6 +6687,7 @@ echo "vhost-scsi support $vhost_scsi"
 echo "vhost-vsock support $vhost_vsock"
 echo "vhost-user support $vhost_user"
 echo "vhost-user-fs support $vhost_user_fs"
+echo "vhost-vdpa support $vhost_vdpa"
 echo "Trace backends    $trace_backends"
 if have_backend "simple"; then
 echo "Trace output file $trace_file-<pid>"
@@ -7170,6 +7185,9 @@ fi
 if test "$vhost_net_user" = "yes" ; then
   echo "CONFIG_VHOST_NET_USER=y" >> $config_host_mak
 fi
+if test "$vhost_net_vdpa" = "yes" ; then
+  echo "CONFIG_VHOST_NET_VDPA=y" >> $config_host_mak
+fi
 if test "$vhost_crypto" = "yes" ; then
   echo "CONFIG_VHOST_CRYPTO=y" >> $config_host_mak
 fi
@@ -7182,6 +7200,9 @@ fi
 if test "$vhost_user" = "yes" ; then
   echo "CONFIG_VHOST_USER=y" >> $config_host_mak
 fi
+if test "$vhost_vdpa" = "yes" ; then
+  echo "CONFIG_VHOST_VDPA=y" >> $config_host_mak
+fi
 if test "$vhost_user_fs" = "yes" ; then
   echo "CONFIG_VHOST_USER_FS=y" >> $config_host_mak
 fi
diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c
index 04cc3db264..cc259e571d 100644
--- a/hw/net/vhost_net.c
+++ b/hw/net/vhost_net.c
@@ -17,8 +17,10 @@
 #include "net/net.h"
 #include "net/tap.h"
 #include "net/vhost-user.h"
+#include "net/vhost-vdpa.h"
 
 #include "standard-headers/linux/vhost_types.h"
+#include "linux-headers/linux/vhost.h"
 #include "hw/virtio/virtio-net.h"
 #include "net/vhost_net.h"
 #include "qemu/error-report.h"
@@ -33,12 +35,6 @@
 #include "hw/virtio/vhost.h"
 #include "hw/virtio/virtio-bus.h"
 
-struct vhost_net {
-    struct vhost_dev dev;
-    struct vhost_virtqueue vqs[2];
-    int backend;
-    NetClientState *nc;
-};
 
 /* Features supported by host kernel. */
 static const int kernel_feature_bits[] = {
@@ -84,7 +80,6 @@ static const int user_feature_bits[] = {
 
     VHOST_INVALID_FEATURE_BIT
 };
-
 static const int *vhost_net_get_feature_bits(struct vhost_net *net)
 {
     const int *feature_bits = 0;
@@ -96,6 +91,9 @@ static const int *vhost_net_get_feature_bits(struct vhost_net *net)
     case NET_CLIENT_DRIVER_VHOST_USER:
         feature_bits = user_feature_bits;
         break;
+    case NET_CLIENT_DRIVER_VHOST_VDPA:
+        feature_bits = vdpa_feature_bits;
+        break;
     default:
         error_report("Feature bits not defined for this type: %d",
                 net->nc->info->type);
@@ -348,6 +346,7 @@ int vhost_net_start(VirtIODevice *dev, NetClientState *ncs,
     }
 
     for (i = 0; i < total_queues; i++) {
+
         peer = qemu_get_peer(ncs, i);
         r = vhost_net_start_one(get_vhost_net(peer), dev);
 
@@ -444,6 +443,12 @@ VHostNetState *get_vhost_net(NetClientState *nc)
         vhost_net = vhost_user_get_vhost_net(nc);
         assert(vhost_net);
         break;
+#endif
+#ifdef CONFIG_VHOST_NET_VDPA
+    case NET_CLIENT_DRIVER_VHOST_VDPA:
+        vhost_net = vhost_vdpa_get_vhost_net(nc);
+        assert(vhost_net);
+        break;
 #endif
     default:
         break;
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index a46e3b37a7..8c85e2e1e1 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -42,6 +42,7 @@
 #include "trace.h"
 #include "monitor/qdev.h"
 #include "hw/pci/pci.h"
+#include "hw/virtio/vhost.h"
 
 #define VIRTIO_NET_VM_VERSION    11
 
@@ -131,6 +132,8 @@ static void virtio_net_get_config(VirtIODevice *vdev, uint8_t *config)
 {
     VirtIONet *n = VIRTIO_NET(vdev);
     struct virtio_net_config netcfg;
+    int ret = 0;
+    memset(&netcfg, 0 , sizeof(struct virtio_net_config));
 
     virtio_stw_p(vdev, &netcfg.status, n->status);
     virtio_stw_p(vdev, &netcfg.max_virtqueue_pairs, n->max_queues);
@@ -139,13 +142,21 @@ static void virtio_net_get_config(VirtIODevice *vdev, uint8_t *config)
     virtio_stl_p(vdev, &netcfg.speed, n->net_conf.speed);
     netcfg.duplex = n->net_conf.duplex;
     memcpy(config, &netcfg, n->config_size);
+    NetClientState *nc = qemu_get_queue(n->nic);
+    if (nc->peer->info->type == NET_CLIENT_DRIVER_VHOST_VDPA) {
+        ret = vhost_net_get_config(get_vhost_net(nc->peer), (uint8_t *)&netcfg,
+                             n->config_size);
+        if (ret != -1) {
+            memcpy(config, &netcfg, n->config_size);
+        }
+    }
 }
 
 static void virtio_net_set_config(VirtIODevice *vdev, const uint8_t *config)
 {
     VirtIONet *n = VIRTIO_NET(vdev);
+    NetClientState *nc = qemu_get_queue(n->nic);
     struct virtio_net_config netcfg = {};
-
     memcpy(&netcfg, config, n->config_size);
 
     if (!virtio_vdev_has_feature(vdev, VIRTIO_NET_F_CTRL_MAC_ADDR) &&
@@ -154,6 +165,11 @@ static void virtio_net_set_config(VirtIODevice *vdev, const uint8_t *config)
         memcpy(n->mac, netcfg.mac, ETH_ALEN);
         qemu_format_nic_info_str(qemu_get_queue(n->nic), n->mac);
     }
+    if (nc->peer->info->type == NET_CLIENT_DRIVER_VHOST_VDPA) {
+        vhost_net_set_config(get_vhost_net(nc->peer), (uint8_t *)&netcfg,
+                               0, n->config_size,
+                               VHOST_SET_CONFIG_TYPE_MASTER);
+      }
 }
 
 static bool virtio_net_started(VirtIONet *n, uint8_t status)
@@ -2958,7 +2974,6 @@ static void virtio_net_device_realize(DeviceState *dev, Error **errp)
     } else if (n->net_conf.speed >= 0) {
         n->host_features |= (1ULL << VIRTIO_NET_F_SPEED_DUPLEX);
     }
-
     if (n->failover) {
         n->primary_listener.should_be_hidden =
             virtio_net_primary_should_be_hidden;
diff --git a/hw/virtio/Makefile.objs b/hw/virtio/Makefile.objs
index 4e4d39a0a4..6b1b1a5fce 100644
--- a/hw/virtio/Makefile.objs
+++ b/hw/virtio/Makefile.objs
@@ -5,6 +5,7 @@ obj-y += virtio.o
 obj-$(CONFIG_VHOST) += vhost.o vhost-backend.o
 common-obj-$(call lnot,$(CONFIG_VHOST)) += vhost-stub.o
 obj-$(CONFIG_VHOST_USER) += vhost-user.o
+obj-$(CONFIG_VHOST_VDPA) += vhost-vdpa.o
 
 common-obj-$(CONFIG_VIRTIO_RNG) += virtio-rng.o
 common-obj-$(CONFIG_VIRTIO_PCI) += virtio-pci.o
diff --git a/hw/virtio/vhost-backend.c b/hw/virtio/vhost-backend.c
index 660e9e8588..84e5b1a833 100644
--- a/hw/virtio/vhost-backend.c
+++ b/hw/virtio/vhost-backend.c
@@ -14,7 +14,7 @@
 #include "qemu/error-report.h"
 #include "qemu/main-loop.h"
 #include "standard-headers/linux/vhost_types.h"
-
+#include "hw/virtio/vhost-vdpa.h"
 #ifdef CONFIG_VHOST_KERNEL
 #include <linux/vhost.h>
 #include <sys/ioctl.h>
@@ -22,10 +22,19 @@
 static int vhost_kernel_call(struct vhost_dev *dev, unsigned long int request,
                              void *arg)
 {
-    int fd = (uintptr_t) dev->opaque;
-
-    assert(dev->vhost_ops->backend_type == VHOST_BACKEND_TYPE_KERNEL);
+    int fd = -1;
+    switch (dev->vhost_ops->backend_type) {
+    case VHOST_BACKEND_TYPE_KERNEL:
+        fd  = (uintptr_t)dev->opaque;
+        break;
+    case VHOST_BACKEND_TYPE_VDPA:
+        fd = ((struct vhost_vdpa *)dev->opaque)->device_fd;
+        break;
+    default:
+        g_assert_not_reached();
+    }
 
+    assert(fd != -1);
     return ioctl(fd, request, arg);
 }
 
@@ -285,6 +294,11 @@ int vhost_set_backend_type(struct vhost_dev *dev, VhostBackendType backend_type)
     case VHOST_BACKEND_TYPE_USER:
         dev->vhost_ops = &user_ops;
         break;
+#endif
+#ifdef CONFIG_VHOST_VDPA
+    case VHOST_BACKEND_TYPE_VDPA:
+        dev->vhost_ops = &vdpa_ops;
+        break;
 #endif
     default:
         error_report("Unknown vhost backend type");
diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c
new file mode 100644
index 0000000000..1724d404ce
--- /dev/null
+++ b/hw/virtio/vhost-vdpa.c
@@ -0,0 +1,406 @@
+/*
+ * vhost-vdpa
+ *
+ *  Copyright(c) 2017-2018 Intel Corporation.
+ *  Copyright(c) 2020 Red Hat, Inc.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#include "qemu/osdep.h"
+#include <linux/vhost.h>
+#include <linux/vfio.h>
+#include <sys/eventfd.h>
+#include <sys/ioctl.h>
+#include "hw/virtio/vhost.h"
+#include "hw/virtio/vhost-backend.h"
+#include "hw/virtio/virtio-net.h"
+#include "hw/virtio/vhost-vdpa.h"
+#include "qemu/main-loop.h"
+#include <linux/kvm.h>
+#include "sysemu/kvm.h"
+
+
+static bool vhost_vdpa_listener_skipped_section(MemoryRegionSection *section)
+{
+    return (!memory_region_is_ram(section->mr) &&
+            !memory_region_is_iommu(section->mr)) ||
+           /*
+            * Sizing an enabled 64-bit BAR can cause spurious mappings to
+            * addresses in the upper part of the 64-bit address space.  These
+            * are never accessed by the CPU and beyond the address width of
+            * some IOMMU hardware.  TODO: VDPA should tell us the IOMMU width.
+            */
+           section->offset_within_address_space & (1ULL << 63);
+}
+
+static int vhost_vdpa_dma_map(struct vhost_vdpa *v, hwaddr iova, hwaddr size,
+                              void *vaddr, bool readonly)
+{
+    struct vhost_msg_v2 msg;
+    int fd = v->device_fd;
+    int ret = 0;
+
+    msg.type =  v->msg_type;
+    msg.iotlb.iova = iova;
+    msg.iotlb.size = size;
+    msg.iotlb.uaddr = (uint64_t)vaddr;
+    msg.iotlb.perm = readonly ? VHOST_ACCESS_RO : VHOST_ACCESS_RW;
+    msg.iotlb.type = VHOST_IOTLB_UPDATE;
+
+    if (write(fd, &msg, sizeof(msg)) != sizeof(msg)) {
+        error_report("failed to write, fd=%d, errno=%d (%s)",
+            fd, errno, strerror(errno));
+        return -EIO ;
+    }
+
+    return ret;
+}
+
+static int vhost_vdpa_dma_unmap(struct vhost_vdpa *v, hwaddr iova,
+                                hwaddr size)
+{
+    struct vhost_msg_v2 msg;
+    int fd = v->device_fd;
+    int ret = 0;
+
+    msg.type =  v->msg_type;
+    msg.iotlb.iova = iova;
+    msg.iotlb.size = size;
+    msg.iotlb.type = VHOST_IOTLB_INVALIDATE;
+
+    if (write(fd, &msg, sizeof(msg)) != sizeof(msg)) {
+        error_report("failed to write, fd=%d, errno=%d (%s)",
+            fd, errno, strerror(errno));
+        return -EIO ;
+    }
+
+    return ret;
+}
+
+static void vhost_vdpa_listener_region_add(MemoryListener *listener,
+                                           MemoryRegionSection *section)
+{
+    struct vhost_vdpa *v = container_of(listener, struct vhost_vdpa, listener);
+    hwaddr iova;
+    Int128 llend, llsize;
+    void *vaddr;
+    int ret;
+
+    if (vhost_vdpa_listener_skipped_section(section)) {
+        return;
+    }
+
+    if (unlikely((section->offset_within_address_space & ~TARGET_PAGE_MASK) !=
+                 (section->offset_within_region & ~TARGET_PAGE_MASK))) {
+        error_report("%s received unaligned region", __func__);
+        return;
+    }
+
+    iova = TARGET_PAGE_ALIGN(section->offset_within_address_space);
+    llend = int128_make64(section->offset_within_address_space);
+    llend = int128_add(llend, section->size);
+    llend = int128_and(llend, int128_exts64(TARGET_PAGE_MASK));
+
+    if (int128_ge(int128_make64(iova), llend)) {
+        return;
+    }
+
+    memory_region_ref(section->mr);
+
+    /* Here we assume that memory_region_is_ram(section->mr)==true */
+
+    vaddr = memory_region_get_ram_ptr(section->mr) +
+            section->offset_within_region +
+            (iova - section->offset_within_address_space);
+
+    llsize = int128_sub(llend, int128_make64(iova));
+
+    ret = vhost_vdpa_dma_map(v, iova, int128_get64(llsize),
+                             vaddr, section->readonly);
+    if (ret) {
+        error_report("vhost vdpa map fail!");
+        if (memory_region_is_ram_device(section->mr)) {
+            /* Allow unexpected mappings not to be fatal for RAM devices */
+            error_report("map ram fail!");
+          return ;
+        }
+        goto fail;
+    }
+
+    return;
+
+fail:
+    if (memory_region_is_ram_device(section->mr)) {
+        error_report("failed to vdpa_dma_map. pci p2p may not work");
+        return;
+
+    }
+    /*
+     * On the initfn path, store the first error in the container so we
+     * can gracefully fail.  Runtime, there's not much we can do other
+     * than throw a hardware error.
+     */
+    error_report("vhost-vdpa: DMA mapping failed, unable to continue");
+    return;
+
+}
+
+static void vhost_vdpa_listener_region_del(MemoryListener *listener,
+                                           MemoryRegionSection *section)
+{
+    struct vhost_vdpa *v = container_of(listener, struct vhost_vdpa, listener);
+    hwaddr iova;
+    Int128 llend, llsize;
+    int ret;
+    bool try_unmap = true;
+
+    if (vhost_vdpa_listener_skipped_section(section)) {
+        return;
+    }
+
+    if (unlikely((section->offset_within_address_space & ~TARGET_PAGE_MASK) !=
+                 (section->offset_within_region & ~TARGET_PAGE_MASK))) {
+        error_report("%s received unaligned region", __func__);
+        return;
+    }
+
+    iova = TARGET_PAGE_ALIGN(section->offset_within_address_space);
+    llend = int128_make64(section->offset_within_address_space);
+    llend = int128_add(llend, section->size);
+    llend = int128_and(llend, int128_exts64(TARGET_PAGE_MASK));
+
+    if (int128_ge(int128_make64(iova), llend)) {
+        return;
+    }
+
+    llsize = int128_sub(llend, int128_make64(iova));
+
+    if (try_unmap) {
+        ret = vhost_vdpa_dma_unmap(v, iova, int128_get64(llsize));
+        if (ret) {
+            error_report("vhost_vdpa dma unmap error!");
+        }
+    }
+
+    memory_region_unref(section->mr);
+}
+/*
+ * IOTLB API is used by vhost-vpda which requires incremental updating
+ * of the mapping. So we can not use generic vhost memory listener which
+ * depends on the addnop().
+ */
+static const MemoryListener vhost_vdpa_memory_listener = {
+    .region_add = vhost_vdpa_listener_region_add,
+    .region_del = vhost_vdpa_listener_region_del,
+};
+
+static int vhost_vdpa_call(struct vhost_dev *dev, unsigned long int request,
+                             void *arg)
+{
+    struct vhost_vdpa *v = dev->opaque;
+    int fd = v->device_fd;
+
+    assert(dev->vhost_ops->backend_type == VHOST_BACKEND_TYPE_VDPA);
+
+    return ioctl(fd, request, arg);
+}
+
+static void vhost_vdpa_add_status(struct vhost_dev *dev, uint8_t status)
+{
+    uint8_t s;
+
+    if (vhost_vdpa_call(dev, VHOST_VDPA_GET_STATUS, &s)) {
+        return;
+    }
+
+    s |= status;
+
+    vhost_vdpa_call(dev, VHOST_VDPA_SET_STATUS, &s);
+}
+
+static int vhost_vdpa_init(struct vhost_dev *dev, void *opaque)
+{
+    struct vhost_vdpa *v;
+    uint64_t features;
+    assert(dev->vhost_ops->backend_type == VHOST_BACKEND_TYPE_VDPA);
+
+    v = opaque;
+    dev->opaque =  opaque ;
+    vhost_vdpa_call(dev, VHOST_GET_FEATURES, &features);
+    dev->backend_features = features;
+    v->listener = vhost_vdpa_memory_listener;
+    v->msg_type = VHOST_IOTLB_MSG_V2;
+
+    vhost_vdpa_add_status(dev, VIRTIO_CONFIG_S_ACKNOWLEDGE |
+                               VIRTIO_CONFIG_S_DRIVER);
+
+    return 0;
+}
+
+static int vhost_vdpa_cleanup(struct vhost_dev *dev)
+{
+    struct vhost_vdpa *v;
+    assert(dev->vhost_ops->backend_type == VHOST_BACKEND_TYPE_VDPA);
+    v = dev->opaque;
+    memory_listener_unregister(&v->listener);
+
+    dev->opaque = NULL;
+    return 0;
+}
+
+static int vhost_vdpa_memslots_limit(struct vhost_dev *dev)
+{
+    return INT_MAX;
+}
+
+static int vhost_vdpa_set_mem_table(struct vhost_dev *dev,
+                                    struct vhost_memory *mem)
+{
+
+    if (mem->padding) {
+        return -1;
+    }
+
+    return 0;
+}
+
+static int vhost_vdpa_set_features(struct vhost_dev *dev,
+                                   uint64_t features)
+{
+    int ret;
+    ret = vhost_vdpa_call(dev, VHOST_SET_FEATURES, &features);
+    uint8_t status = 0;
+    if (ret) {
+        return ret;
+    }
+    vhost_vdpa_add_status(dev, VIRTIO_CONFIG_S_FEATURES_OK);
+    vhost_vdpa_call(dev, VHOST_VDPA_GET_STATUS, &status);
+
+    return !(status & VIRTIO_CONFIG_S_FEATURES_OK);
+}
+
+int vhost_vdpa_get_device_id(struct vhost_dev *dev,
+                                   uint32_t *device_id)
+{
+    return vhost_vdpa_call(dev, VHOST_VDPA_GET_DEVICE_ID, device_id);
+}
+
+static int vhost_vdpa_reset_device(struct vhost_dev *dev)
+{
+    uint8_t status = 0;
+
+    return vhost_vdpa_call(dev, VHOST_VDPA_SET_STATUS, &status);
+}
+
+static int vhost_vdpa_get_vq_index(struct vhost_dev *dev, int idx)
+{
+    assert(idx >= dev->vq_index && idx < dev->vq_index + dev->nvqs);
+
+    return idx - dev->vq_index;
+}
+
+static int vhost_vdpa_set_vring_ready(struct vhost_dev *dev)
+{
+    int i;
+    for (i = 0; i < dev->nvqs; ++i) {
+        struct vhost_vring_state state = {
+            .index = dev->vq_index + i,
+            .num = 1,
+        };
+        vhost_vdpa_call(dev, VHOST_VDPA_SET_VRING_ENABLE, &state);
+    }
+    return 0;
+}
+
+static int vhost_vdpa_set_config(struct vhost_dev *dev, const uint8_t *data,
+                                   uint32_t offset, uint32_t size,
+                                   uint32_t flags)
+{
+    struct vhost_vdpa_config *config;
+    int ret;
+    unsigned long config_size = offsetof(struct vhost_vdpa_config, buf);
+    config = g_malloc(size + config_size);
+    if (config == NULL) {
+        return -1;
+    }
+    config->off = offset;
+    config->len = size;
+    memcpy(config->buf, data, size);
+    ret = vhost_vdpa_call(dev, VHOST_VDPA_SET_CONFIG, config);
+    g_free(config);
+    return ret;
+}
+
+static int vhost_vdpa_get_config(struct vhost_dev *dev, uint8_t *config,
+                                   uint32_t config_len)
+{
+    struct vhost_vdpa_config *v_config;
+    unsigned long config_size = offsetof(struct vhost_vdpa_config, buf);
+    int ret;
+
+    v_config = g_malloc(config_len + config_size);
+    if (v_config == NULL) {
+        return -1;
+    }
+    v_config->len = config_len;
+    v_config->off = 0;
+    ret = vhost_vdpa_call(dev, VHOST_VDPA_GET_CONFIG, v_config);
+    memcpy(config, v_config->buf, config_len);
+    g_free(v_config);
+    return ret;
+ }
+
+static int vhost_vdpa_dev_start(struct vhost_dev *dev, bool started)
+{
+    struct vhost_vdpa *v = dev->opaque;
+    if (started) {
+        uint8_t status = 0;
+        memory_listener_register(&v->listener, &address_space_memory);
+        vhost_vdpa_set_vring_ready(dev);
+        vhost_vdpa_add_status(dev, VIRTIO_CONFIG_S_DRIVER_OK);
+        vhost_vdpa_call(dev, VHOST_VDPA_GET_STATUS, &status);
+
+        return !(status & VIRTIO_CONFIG_S_DRIVER_OK);
+    } else {
+        vhost_vdpa_reset_device(dev);
+        vhost_vdpa_add_status(dev, VIRTIO_CONFIG_S_ACKNOWLEDGE |
+                                   VIRTIO_CONFIG_S_DRIVER);
+        memory_listener_unregister(&v->listener);
+
+        return 0;
+    }
+}
+
+const VhostOps vdpa_ops = {
+        .backend_type = VHOST_BACKEND_TYPE_VDPA,
+        .vhost_backend_init = vhost_vdpa_init,
+        .vhost_backend_cleanup = vhost_vdpa_cleanup,
+        .vhost_set_log_base = vhost_kernel_set_log_base,
+        .vhost_set_vring_addr = vhost_kernel_set_vring_addr,
+        .vhost_set_vring_num = vhost_kernel_set_vring_num,
+        .vhost_set_vring_base = vhost_kernel_set_vring_base,
+        .vhost_get_vring_base = vhost_kernel_get_vring_base,
+        .vhost_set_vring_kick = vhost_kernel_set_vring_kick,
+        .vhost_set_vring_call = vhost_kernel_set_vring_call,
+        .vhost_get_features = vhost_kernel_get_features,
+        .vhost_set_owner = vhost_kernel_set_owner,
+        .vhost_set_vring_endian = NULL,
+        .vhost_backend_memslots_limit = vhost_vdpa_memslots_limit,
+        .vhost_set_mem_table = vhost_vdpa_set_mem_table,
+        .vhost_set_features = vhost_vdpa_set_features,
+        .vhost_reset_device = vhost_vdpa_reset_device,
+        .vhost_get_vq_index = vhost_vdpa_get_vq_index,
+        .vhost_get_config  = vhost_vdpa_get_config,
+        .vhost_set_config = vhost_vdpa_set_config,
+        .vhost_requires_shm_log = NULL,
+        .vhost_migration_done = NULL,
+        .vhost_backend_can_merge = NULL,
+        .vhost_net_set_mtu = NULL,
+        .vhost_set_iotlb_callback = NULL,
+        .vhost_send_device_iotlb_msg = NULL,
+        .vhost_dev_start = vhost_vdpa_dev_start,
+        .vhost_get_device_id = vhost_vdpa_get_device_id,
+};
diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
index bfd7f9ce1f..a75be7216b 100644
--- a/hw/virtio/vhost.c
+++ b/hw/virtio/vhost.c
@@ -744,19 +744,34 @@ static void vhost_iommu_region_del(MemoryListener *listener,
     }
 }
 
+static void vhost_virtqueue_get_addr(struct vhost_dev *dev,
+                                    struct vhost_vring_addr *addr,
+                                    struct vhost_virtqueue *vq)
+{
+    /*vDPA need to use the IOVA here to set to hardware*/
+    if (dev->vhost_ops->backend_type == VHOST_BACKEND_TYPE_VDPA) {
+        addr->desc_user_addr = (uint64_t)(unsigned long)vq->desc_phys;
+        addr->avail_user_addr = (uint64_t)(unsigned long)vq->avail_phys;
+        addr->used_user_addr = (uint64_t)(unsigned long)vq->used_phys;
+    } else {
+        addr->desc_user_addr = (uint64_t)(unsigned long)vq->desc;
+        addr->avail_user_addr = (uint64_t)(unsigned long)vq->avail;
+        addr->used_user_addr = (uint64_t)(unsigned long)vq->used;
+    }
+}
 
 static int vhost_virtqueue_set_addr(struct vhost_dev *dev,
                                     struct vhost_virtqueue *vq,
                                     unsigned idx, bool enable_log)
 {
-    struct vhost_vring_addr addr = {
-        .index = idx,
-        .desc_user_addr = (uint64_t)(unsigned long)vq->desc,
-        .avail_user_addr = (uint64_t)(unsigned long)vq->avail,
-        .used_user_addr = (uint64_t)(unsigned long)vq->used,
-        .log_guest_addr = vq->used_phys,
-        .flags = enable_log ? (1 << VHOST_VRING_F_LOG) : 0,
-    };
+    struct vhost_vring_addr addr;
+    memset(&addr, 0, sizeof(struct vhost_vring_addr));
+
+    vhost_virtqueue_get_addr(dev, &addr, vq);
+    addr.index = idx;
+    addr .log_guest_addr = vq->used_phys;
+    addr .flags = enable_log ? (1 << VHOST_VRING_F_LOG) : 0;
+
     int r = dev->vhost_ops->vhost_set_vring_addr(dev, &addr);
     if (r < 0) {
         VHOST_OPS_DEBUG("vhost_set_vring_addr failed");
@@ -774,7 +789,9 @@ static int vhost_dev_set_features(struct vhost_dev *dev,
         features |= 0x1ULL << VHOST_F_LOG_ALL;
     }
     if (!vhost_dev_has_iommu(dev)) {
-        features &= ~(0x1ULL << VIRTIO_F_IOMMU_PLATFORM);
+        if (dev->vhost_ops->backend_type != VHOST_BACKEND_TYPE_VDPA) {
+            features &= ~(0x1ULL << VIRTIO_F_IOMMU_PLATFORM);
+        }
     }
     r = dev->vhost_ops->vhost_set_features(dev, features);
     if (r < 0) {
@@ -1667,7 +1684,8 @@ int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev)
         goto fail_log;
     }
 
-    if (vhost_dev_has_iommu(hdev)) {
+    if (vhost_dev_has_iommu(hdev) &&
+        hdev->vhost_ops->vhost_set_iotlb_callback) {
         hdev->vhost_ops->vhost_set_iotlb_callback(hdev, true);
 
         /* Update used ring information for IOTLB to work correctly,
@@ -1713,7 +1731,9 @@ void vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev)
     }
 
     if (vhost_dev_has_iommu(hdev)) {
-        hdev->vhost_ops->vhost_set_iotlb_callback(hdev, false);
+        if (hdev->vhost_ops->vhost_set_iotlb_callback) {
+            hdev->vhost_ops->vhost_set_iotlb_callback(hdev, false);
+        }
         memory_listener_unregister(&hdev->iommu_listener);
     }
     vhost_log_put(hdev, true);
diff --git a/include/hw/virtio/vhost-backend.h b/include/hw/virtio/vhost-backend.h
index c1384bd2c7..c418c2fa0e 100644
--- a/include/hw/virtio/vhost-backend.h
+++ b/include/hw/virtio/vhost-backend.h
@@ -17,7 +17,8 @@ typedef enum VhostBackendType {
     VHOST_BACKEND_TYPE_NONE = 0,
     VHOST_BACKEND_TYPE_KERNEL = 1,
     VHOST_BACKEND_TYPE_USER = 2,
-    VHOST_BACKEND_TYPE_MAX = 3,
+    VHOST_BACKEND_TYPE_VDPA = 3,
+    VHOST_BACKEND_TYPE_MAX = 4,
 } VhostBackendType;
 
 typedef enum VhostSetConfigType {
@@ -113,6 +114,7 @@ typedef int (*vhost_set_inflight_fd_op)(struct vhost_dev *dev,
                                         struct vhost_inflight *inflight);
 
 typedef int (*vhost_dev_start_op)(struct vhost_dev *dev, bool started);
+typedef int (*vhost_get_device_id_op)(struct vhost_dev *dev, uint32_t *dev_id);
 typedef struct VhostOps {
     VhostBackendType backend_type;
     vhost_backend_init vhost_backend_init;
@@ -154,9 +156,11 @@ typedef struct VhostOps {
     vhost_get_inflight_fd_op vhost_get_inflight_fd;
     vhost_set_inflight_fd_op vhost_set_inflight_fd;
     vhost_dev_start_op vhost_dev_start;
+    vhost_get_device_id_op vhost_get_device_id;
 } VhostOps;
 
 extern const VhostOps user_ops;
+extern const VhostOps vdpa_ops;
 
 int vhost_set_backend_type(struct vhost_dev *dev,
                            VhostBackendType backend_type);
diff --git a/include/hw/virtio/vhost-vdpa.h b/include/hw/virtio/vhost-vdpa.h
new file mode 100644
index 0000000000..6455663388
--- /dev/null
+++ b/include/hw/virtio/vhost-vdpa.h
@@ -0,0 +1,26 @@
+/*
+ * vhost-vdpa.h
+ *
+ * Copyright(c) 2017-2018 Intel Corporation.
+ * Copyright(c) 2020 Red Hat, Inc.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#ifndef HW_VIRTIO_VHOST_VDPA_H
+#define HW_VIRTIO_VHOST_VDPA_H
+
+#include "hw/virtio/virtio.h"
+
+typedef struct vhost_vdpa {
+    int device_fd;
+    uint32_t msg_type;
+    MemoryListener listener;
+} VhostVDPA;
+
+extern AddressSpace address_space_memory;
+extern int vhost_vdpa_get_device_id(struct vhost_dev *dev,
+                                   uint32_t *device_id);
+#endif
diff --git a/include/hw/virtio/vhost.h b/include/hw/virtio/vhost.h
index 59ea53f8c2..f69b5e4a02 100644
--- a/include/hw/virtio/vhost.h
+++ b/include/hw/virtio/vhost.h
@@ -92,6 +92,12 @@ struct vhost_dev {
     const VhostDevConfigOps *config_ops;
 };
 
+struct vhost_net {
+    struct vhost_dev dev;
+    struct vhost_virtqueue vqs[2];
+    int backend;
+    NetClientState *nc;
+};
 
 int vhost_dev_init(struct vhost_dev *hdev, void *opaque,
                    VhostBackendType backend_type,
diff --git a/qemu-options.hx b/qemu-options.hx
index 292d4e7c0c..d7d0daaa0e 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -2409,6 +2409,10 @@ DEF("netdev", HAS_ARG, QEMU_OPTION_netdev,
 #ifdef CONFIG_POSIX
     "-netdev vhost-user,id=str,chardev=dev[,vhostforce=on|off]\n"
     "                configure a vhost-user network, backed by a chardev 'dev'\n"
+#endif
+#ifdef __linux__
+    "-netdev vhost-vdpa,id=str,vhostdev=/path/to/dev\n"
+    "                configure a vhost-vdpa network,Establish a vhost-vdpa netdev\n"
 #endif
     "-netdev hubport,id=str,hubid=n[,netdev=nd]\n"
     "                configure a hub port on the hub with ID 'n'\n", QEMU_ARCH_ALL)
@@ -2888,6 +2892,14 @@ SRST
              -netdev type=vhost-user,id=net0,chardev=chr0 \
              -device virtio-net-pci,netdev=net0
 
+``-netdev vhost-vdpa,vhostdev=/path/to/dev``
+    Establish a vhost-vdpa netdev.
+
+    vDPA device is a device that uses a datapath which complies with
+    the virtio specifications with a vendor specific control path.
+    vDPA devices can be both physically located on the hardware or
+    emulated by software.
+
 ``-netdev hubport,id=id,hubid=hubid[,netdev=nd]``
     Create a hub port on the emulated hub with ID hubid.
 
-- 
2.21.1



^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH v1 10/10] vhost-vdpa: introduce vhost-vdpa net client
  2020-06-22 15:37 [PATCH v1 00/10] vDPA support in qemu Cindy Lu
                   ` (8 preceding siblings ...)
  2020-06-22 15:37 ` [PATCH v1 09/10] vhost-vdpa: introduce vhost-vdpa backend Cindy Lu
@ 2020-06-22 15:37 ` Cindy Lu
  2020-06-23  7:12   ` Markus Armbruster
  2020-06-23  8:56   ` Jason Wang
  2020-06-23  7:07 ` [PATCH v1 00/10] vDPA support in qemu Markus Armbruster
  2020-06-28  7:06 ` Jason Wang
  11 siblings, 2 replies; 46+ messages in thread
From: Cindy Lu @ 2020-06-22 15:37 UTC (permalink / raw)
  To: mst, armbru, eblake, cohuck, jasowang
  Cc: mhabets, qemu-devel, rob.miller, saugatm, lulu, hanand, hch,
	eperezma, jgg, shahafs, kevin.tian, parav, vmireyno,
	cunming.liang, gdawar, jiri, xiao.w.wang, stefanha, zhihong.wang,
	Tiwei Bie, aadam, rdunlap, maxime.coquelin, lingshan.zhu

This patch set introduces a new net client type: vhost-vdpa.
vhost-vdpa net client will set up a vDPA device which is specified
by a "vhostdev" parameter.

Signed-off-by: Lingshan Zhu <lingshan.zhu@intel.com>
Signed-off-by: Tiwei Bie <tiwei.bie@intel.com>
Signed-off-by: Cindy Lu <lulu@redhat.com>
---
 include/net/vhost-vdpa.h |  21 ++++
 include/net/vhost_net.h  |   1 -
 net/Makefile.objs        |   2 +-
 net/clients.h            |   2 +
 net/net.c                |   3 +
 net/vhost-vdpa.c         | 230 +++++++++++++++++++++++++++++++++++++++
 qapi/net.json            |  23 +++-
 7 files changed, 278 insertions(+), 4 deletions(-)
 create mode 100644 include/net/vhost-vdpa.h
 create mode 100644 net/vhost-vdpa.c

diff --git a/include/net/vhost-vdpa.h b/include/net/vhost-vdpa.h
new file mode 100644
index 0000000000..725c8b1c81
--- /dev/null
+++ b/include/net/vhost-vdpa.h
@@ -0,0 +1,21 @@
+/*
+ * vhost-vdpa.h
+ *
+ * Copyright(c) 2017-2018 Intel Corporation.
+ * Copyright(c) 2020 Red Hat, Inc.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#ifndef VHOST_VDPA_H
+#define VHOST_VDPA_H
+
+struct vhost_net;
+struct vhost_net *vhost_vdpa_get_vhost_net(NetClientState *nc);
+uint64_t vhost_vdpa_get_acked_features(NetClientState *nc);
+
+extern const int vdpa_feature_bits[];
+
+#endif /* VHOST_VDPA_H */
diff --git a/include/net/vhost_net.h b/include/net/vhost_net.h
index abfb0e8e68..4843cdb36f 100644
--- a/include/net/vhost_net.h
+++ b/include/net/vhost_net.h
@@ -44,5 +44,4 @@ int vhost_set_vring_enable(NetClientState * nc, int enable);
 uint64_t vhost_net_get_acked_features(VHostNetState *net);
 
 int vhost_net_set_mtu(struct vhost_net *net, uint16_t mtu);
-
 #endif
diff --git a/net/Makefile.objs b/net/Makefile.objs
index c5d076d19c..5ab45545db 100644
--- a/net/Makefile.objs
+++ b/net/Makefile.objs
@@ -26,7 +26,7 @@ tap-obj-$(CONFIG_SOLARIS) = tap-solaris.o
 tap-obj-y ?= tap-stub.o
 common-obj-$(CONFIG_POSIX) += tap.o $(tap-obj-y)
 common-obj-$(CONFIG_WIN32) += tap-win32.o
-
+common-obj-$(CONFIG_VHOST_NET_VDPA) += vhost-vdpa.o
 vde.o-libs = $(VDE_LIBS)
 
 common-obj-$(CONFIG_CAN_BUS) += can/
diff --git a/net/clients.h b/net/clients.h
index a6ef267e19..92f9b59aed 100644
--- a/net/clients.h
+++ b/net/clients.h
@@ -61,4 +61,6 @@ int net_init_netmap(const Netdev *netdev, const char *name,
 int net_init_vhost_user(const Netdev *netdev, const char *name,
                         NetClientState *peer, Error **errp);
 
+int net_init_vhost_vdpa(const Netdev *netdev, const char *name,
+                        NetClientState *peer, Error **errp);
 #endif /* QEMU_NET_CLIENTS_H */
diff --git a/net/net.c b/net/net.c
index 599fb61028..82624ea9ac 100644
--- a/net/net.c
+++ b/net/net.c
@@ -965,6 +965,9 @@ static int (* const net_client_init_fun[NET_CLIENT_DRIVER__MAX])(
 #ifdef CONFIG_VHOST_NET_USER
         [NET_CLIENT_DRIVER_VHOST_USER] = net_init_vhost_user,
 #endif
+#ifdef CONFIG_VHOST_NET_VDPA
+        [NET_CLIENT_DRIVER_VHOST_VDPA] = net_init_vhost_vdpa,
+#endif
 #ifdef CONFIG_L2TPV3
         [NET_CLIENT_DRIVER_L2TPV3]    = net_init_l2tpv3,
 #endif
diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c
new file mode 100644
index 0000000000..34858a6ea3
--- /dev/null
+++ b/net/vhost-vdpa.c
@@ -0,0 +1,230 @@
+/*
+ * vhost-vdpa.c
+ *
+ * Copyright(c) 2017-2018 Intel Corporation.
+ * Copyright(c) 2020 Red Hat, Inc.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#include "qemu/osdep.h"
+#include "clients.h"
+#include "net/vhost_net.h"
+#include "net/vhost-vdpa.h"
+#include "hw/virtio/vhost-vdpa.h"
+#include "qemu/config-file.h"
+#include "qemu/error-report.h"
+#include "qemu/option.h"
+#include "qapi/error.h"
+#include <sys/ioctl.h>
+#include <err.h>
+#include "standard-headers/linux/virtio_net.h"
+#include "monitor/monitor.h"
+#include "hw/virtio/vhost.h"
+
+/* Todo:need to add the multiqueue support here */
+typedef struct VhostVDPAState {
+    NetClientState nc;
+    struct vhost_vdpa vhost_vdpa;
+    VHostNetState *vhost_net;
+    uint64_t acked_features;
+    bool started;
+} VhostVDPAState;
+
+const int vdpa_feature_bits[] = {
+    VIRTIO_F_NOTIFY_ON_EMPTY,
+    VIRTIO_RING_F_INDIRECT_DESC,
+    VIRTIO_RING_F_EVENT_IDX,
+    VIRTIO_F_ANY_LAYOUT,
+    VIRTIO_F_VERSION_1,
+    VIRTIO_NET_F_CSUM,
+    VIRTIO_NET_F_GUEST_CSUM,
+    VIRTIO_NET_F_GSO,
+    VIRTIO_NET_F_GUEST_TSO4,
+    VIRTIO_NET_F_GUEST_TSO6,
+    VIRTIO_NET_F_GUEST_ECN,
+    VIRTIO_NET_F_GUEST_UFO,
+    VIRTIO_NET_F_HOST_TSO4,
+    VIRTIO_NET_F_HOST_TSO6,
+    VIRTIO_NET_F_HOST_ECN,
+    VIRTIO_NET_F_HOST_UFO,
+    VIRTIO_NET_F_MRG_RXBUF,
+    VIRTIO_NET_F_MTU,
+    VIRTIO_F_IOMMU_PLATFORM,
+    VIRTIO_F_RING_PACKED,
+    VIRTIO_NET_F_GUEST_ANNOUNCE,
+    VHOST_INVALID_FEATURE_BIT
+};
+
+VHostNetState *vhost_vdpa_get_vhost_net(NetClientState *nc)
+{
+    VhostVDPAState *s = DO_UPCAST(VhostVDPAState, nc, nc);
+    assert(nc->info->type == NET_CLIENT_DRIVER_VHOST_VDPA);
+    return s->vhost_net;
+}
+
+uint64_t vhost_vdpa_get_acked_features(NetClientState *nc)
+{
+    VhostVDPAState *s = DO_UPCAST(VhostVDPAState, nc, nc);
+    assert(nc->info->type == NET_CLIENT_DRIVER_VHOST_VDPA);
+    s->acked_features = vhost_net_get_acked_features(s->vhost_net);
+
+    return s->acked_features;
+}
+
+static int vhost_vdpa_net_check_device_id(NetClientState *nc)
+{
+    uint32_t device_id;
+    int ret;
+    struct vhost_net *net;
+    struct vhost_dev *hdev;
+    assert(nc->info->type == NET_CLIENT_DRIVER_VHOST_VDPA);
+    VhostVDPAState *s = DO_UPCAST(VhostVDPAState, nc, nc);
+    net = s->vhost_net;
+    hdev = (struct vhost_dev *)&net->dev;
+    ret = hdev->vhost_ops->vhost_get_device_id(hdev, &device_id);
+    if (device_id != VIRTIO_ID_NET) {
+        return -ENOTSUP;
+    }
+    return ret;
+}
+
+static void vhost_vdpa_del(NetClientState *ncs)
+{
+    VhostVDPAState *s;
+    assert(ncs->info->type == NET_CLIENT_DRIVER_VHOST_VDPA);
+    s = DO_UPCAST(VhostVDPAState, nc, ncs);
+    if (s->vhost_net) {
+        vhost_net_cleanup(s->vhost_net);
+    }
+}
+
+static int vhost_vdpa_add(NetClientState *ncs, void *be)
+{
+    VhostNetOptions options;
+    struct vhost_net *net = NULL;
+    VhostVDPAState *s;
+    int ret;
+
+    options.backend_type = VHOST_BACKEND_TYPE_VDPA;
+    assert(ncs->info->type == NET_CLIENT_DRIVER_VHOST_VDPA);
+    s = DO_UPCAST(VhostVDPAState, nc, ncs);
+    options.net_backend = ncs;
+    options.opaque      = be;
+    options.busyloop_timeout = 0;
+    net = vhost_net_init(&options);
+    if (!net) {
+        error_report("failed to init vhost_net for queue");
+        goto err;
+    }
+    if (s->vhost_net) {
+        vhost_net_cleanup(s->vhost_net);
+        g_free(s->vhost_net);
+    }
+    s->vhost_net = net;
+    ret = vhost_vdpa_net_check_device_id(ncs);
+    if (ret) {
+        goto err;
+    }
+    return 0;
+err:
+    if (net) {
+        vhost_net_cleanup(net);
+    }
+    vhost_vdpa_del(ncs);
+    return -1;
+}
+
+static void vhost_vdpa_cleanup(NetClientState *nc)
+{
+    VhostVDPAState *s = DO_UPCAST(VhostVDPAState, nc, nc);
+
+    if (s->vhost_net) {
+        vhost_net_cleanup(s->vhost_net);
+        g_free(s->vhost_net);
+        s->vhost_net = NULL;
+    }
+}
+
+static bool vhost_vdpa_has_vnet_hdr(NetClientState *nc)
+{
+    assert(nc->info->type == NET_CLIENT_DRIVER_VHOST_VDPA);
+
+    return true;
+}
+
+static bool vhost_vdpa_has_ufo(NetClientState *nc)
+{
+    assert(nc->info->type == NET_CLIENT_DRIVER_VHOST_VDPA);
+    VhostVDPAState *s = DO_UPCAST(VhostVDPAState, nc, nc);
+    uint64_t  features = 0;
+    features |= (1ULL << VIRTIO_NET_F_HOST_UFO);
+    features = vhost_net_get_features(s->vhost_net, features);
+    return !!(features & (1ULL << VIRTIO_NET_F_HOST_UFO));
+
+}
+
+static NetClientInfo net_vhost_vdpa_info = {
+        .type = NET_CLIENT_DRIVER_VHOST_VDPA,
+        .size = sizeof(VhostVDPAState),
+        .cleanup = vhost_vdpa_cleanup,
+        .has_vnet_hdr = vhost_vdpa_has_vnet_hdr,
+        .has_ufo = vhost_vdpa_has_ufo,
+};
+
+static int net_vhost_vdpa_init(NetClientState *peer, const char *device,
+                               const char *name, const char *vhostdev)
+{
+    NetClientState *nc = NULL;
+    VhostVDPAState *s;
+    int vdpa_device_fd = -1;
+    int ret = 0;
+    assert(name);
+    nc = qemu_new_net_client(&net_vhost_vdpa_info, peer, device, name);
+    snprintf(nc->info_str, sizeof(nc->info_str), "vhost-vdpa");
+    nc->queue_index = 0;
+    s = DO_UPCAST(VhostVDPAState, nc, nc);
+    vdpa_device_fd = qemu_open(vhostdev, O_RDWR);
+    if (vdpa_device_fd == -1) {
+        return -errno;
+    }
+    s->vhost_vdpa.device_fd = vdpa_device_fd;
+    ret = vhost_vdpa_add(nc, (void *)&s->vhost_vdpa);
+    assert(s->vhost_net);
+    return ret;
+}
+
+static int net_vhost_check_net(void *opaque, QemuOpts *opts, Error **errp)
+{
+    const char *name = opaque;
+    const char *driver, *netdev;
+
+    driver = qemu_opt_get(opts, "driver");
+    netdev = qemu_opt_get(opts, "netdev");
+    if (!driver || !netdev) {
+        return 0;
+    }
+    if (strcmp(netdev, name) == 0 &&
+        !g_str_has_prefix(driver, "virtio-net-")) {
+        error_setg(errp, "vhost-vdpa requires frontend driver virtio-net-*");
+        return -1;
+    }
+    return 0;
+}
+
+int net_init_vhost_vdpa(const Netdev *netdev, const char *name,
+                        NetClientState *peer, Error **errp)
+{
+    const NetdevVhostVDPAOptions *opts;
+
+    assert(netdev->type == NET_CLIENT_DRIVER_VHOST_VDPA);
+    opts = &netdev->u.vhost_vdpa;
+    /* verify net frontend */
+    if (qemu_opts_foreach(qemu_find_opts("device"), net_vhost_check_net,
+                          (char *)name, errp)) {
+        return -1;
+    }
+    return net_vhost_vdpa_init(peer, "vhost_vdpa", name, opts->vhostdev);
+}
diff --git a/qapi/net.json b/qapi/net.json
index cebb1b52e3..03aad67693 100644
--- a/qapi/net.json
+++ b/qapi/net.json
@@ -428,6 +428,24 @@
     '*vhostforce':    'bool',
     '*queues':        'int' } }
 
+##
+# @NetdevVhostVDPAOptions:
+#
+# Vhost-vdpa network backend
+#
+# @vhostdev: name of a vdpa dev path in sysfs
+#            (default path:/dev/vhost-vdpa-$ID)
+#
+# @queues: number of queues to be created for multiqueue vhost-vdpa
+#          (default: 1)
+#
+# Since: 5.1
+##
+{ 'struct': 'NetdevVhostVDPAOptions',
+  'data': {
+    '*vhostdev':     'str',
+    '*queues':       'int' } }
+
 ##
 # @NetClientDriver:
 #
@@ -437,7 +455,7 @@
 ##
 { 'enum': 'NetClientDriver',
   'data': [ 'none', 'nic', 'user', 'tap', 'l2tpv3', 'socket', 'vde',
-            'bridge', 'hubport', 'netmap', 'vhost-user' ] }
+            'bridge', 'hubport', 'netmap', 'vhost-user', 'vhost-vdpa' ] }
 
 ##
 # @Netdev:
@@ -465,7 +483,8 @@
     'bridge':   'NetdevBridgeOptions',
     'hubport':  'NetdevHubPortOptions',
     'netmap':   'NetdevNetmapOptions',
-    'vhost-user': 'NetdevVhostUserOptions' } }
+    'vhost-user': 'NetdevVhostUserOptions',
+    'vhost-vdpa': 'NetdevVhostVDPAOptions' } }
 
 ##
 # @NetLegacy:
-- 
2.21.1



^ permalink raw reply related	[flat|nested] 46+ messages in thread

* Re: [PATCH v1 00/10] vDPA support in qemu
  2020-06-22 15:37 [PATCH v1 00/10] vDPA support in qemu Cindy Lu
                   ` (9 preceding siblings ...)
  2020-06-22 15:37 ` [PATCH v1 10/10] vhost-vdpa: introduce vhost-vdpa net client Cindy Lu
@ 2020-06-23  7:07 ` Markus Armbruster
  2020-06-23  9:16   ` Cindy Lu
  2020-06-28  7:06 ` Jason Wang
  11 siblings, 1 reply; 46+ messages in thread
From: Markus Armbruster @ 2020-06-23  7:07 UTC (permalink / raw)
  To: Cindy Lu
  Cc: rdunlap, mst, jasowang, qemu-devel, rob.miller, saugatm,
	maxime.coquelin, hch, eperezma, jgg, mhabets, shahafs,
	kevin.tian, parav, vmireyno, cunming.liang, gdawar, jiri,
	xiao.w.wang, stefanha, zhihong.wang, aadam, cohuck, hanand,
	lingshan.zhu

Cindy Lu <lulu@redhat.com> writes:

> vDPA device is a device that uses a datapath which complies with the
> virtio specifications with vendor specific control path. vDPA devices
> can be both physically located on the hardware or emulated by software.
> This RFC introduce the vDPA support in qemu
> TODO 
> 1) vIOMMU support
> 2) live migration support

This gives me the foggiest of ideas on what vDPA is.  Could we use
docs/interop/vhost-vdpa.rst?



^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v1 01/10] net: introduce qemu_get_peer
  2020-06-22 15:37 ` [PATCH v1 01/10] net: introduce qemu_get_peer Cindy Lu
@ 2020-06-23  7:10   ` Jason Wang
  2020-06-23  9:17     ` Cindy Lu
  0 siblings, 1 reply; 46+ messages in thread
From: Jason Wang @ 2020-06-23  7:10 UTC (permalink / raw)
  To: Cindy Lu, mst, armbru, eblake, cohuck
  Cc: mhabets, qemu-devel, rob.miller, saugatm, hanand, hch, eperezma,
	jgg, shahafs, kevin.tian, parav, vmireyno, cunming.liang, gdawar,
	jiri, xiao.w.wang, stefanha, zhihong.wang, aadam, rdunlap,
	maxime.coquelin, lingshan.zhu


On 2020/6/22 下午11:37, Cindy Lu wrote:
> This is a small function that can get the peer
> from given NetClientState and queue_index
>
> Signed-off-by: Cindy Lu <lulu@redhat.com>
> ---
>   include/net/net.h | 1 +
>   net/net.c         | 6 ++++++
>   2 files changed, 7 insertions(+)
>
> diff --git a/include/net/net.h b/include/net/net.h
> index 39085d9444..e7ef42d62b 100644
> --- a/include/net/net.h
> +++ b/include/net/net.h
> @@ -176,6 +176,7 @@ void hmp_info_network(Monitor *mon, const QDict *qdict);
>   void net_socket_rs_init(SocketReadState *rs,
>                           SocketReadStateFinalize *finalize,
>                           bool vnet_hdr);
> +NetClientState *qemu_get_peer(NetClientState *nc, int queue_index);
>   
>   /* NIC info */
>   
> diff --git a/net/net.c b/net/net.c
> index 38778e831d..599fb61028 100644
> --- a/net/net.c
> +++ b/net/net.c
> @@ -324,6 +324,12 @@ void *qemu_get_nic_opaque(NetClientState *nc)
>   
>       return nic->opaque;
>   }


newline please.

Thanks


> +NetClientState *qemu_get_peer(NetClientState *nc, int queue_index)
> +{
> +    assert(nc != NULL);
> +    NetClientState *ncs = nc + queue_index;
> +    return ncs->peer;
> +}
>   
>   static void qemu_cleanup_net_client(NetClientState *nc)
>   {



^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v1 10/10] vhost-vdpa: introduce vhost-vdpa net client
  2020-06-22 15:37 ` [PATCH v1 10/10] vhost-vdpa: introduce vhost-vdpa net client Cindy Lu
@ 2020-06-23  7:12   ` Markus Armbruster
  2020-06-23  9:19     ` Cindy Lu
  2020-06-23  8:56   ` Jason Wang
  1 sibling, 1 reply; 46+ messages in thread
From: Markus Armbruster @ 2020-06-23  7:12 UTC (permalink / raw)
  To: Cindy Lu
  Cc: rdunlap, mst, mhabets, qemu-devel, rob.miller, saugatm, armbru,
	hch, eperezma, jgg, jasowang, shahafs, kevin.tian, parav,
	vmireyno, cunming.liang, gdawar, jiri, xiao.w.wang, stefanha,
	zhihong.wang, maxime.coquelin, Tiwei Bie, aadam, cohuck, hanand,
	lingshan.zhu

QAPI schema review only.

Cindy Lu <lulu@redhat.com> writes:

> This patch set introduces a new net client type: vhost-vdpa.
> vhost-vdpa net client will set up a vDPA device which is specified
> by a "vhostdev" parameter.
>
> Signed-off-by: Lingshan Zhu <lingshan.zhu@intel.com>
> Signed-off-by: Tiwei Bie <tiwei.bie@intel.com>
> Signed-off-by: Cindy Lu <lulu@redhat.com>
[...]
> diff --git a/qapi/net.json b/qapi/net.json
> index cebb1b52e3..03aad67693 100644
> --- a/qapi/net.json
> +++ b/qapi/net.json
> @@ -428,6 +428,24 @@
>      '*vhostforce':    'bool',
>      '*queues':        'int' } }
>  
> +##
> +# @NetdevVhostVDPAOptions:
> +#
> +# Vhost-vdpa network backend

Considering this ends up in QMP reference documentation, could you add a
hint on what "Vhost-vdpa" is?

> +#
> +# @vhostdev: name of a vdpa dev path in sysfs

How is this thing to be spelled in text, vdpa, VDPA or vDPA?

Avoid unnecessary abbreviations in doc text, please: write "device
path", not "dev path".

> +#            (default path:/dev/vhost-vdpa-$ID)

What's $ID?

> +#
> +# @queues: number of queues to be created for multiqueue vhost-vdpa
> +#          (default: 1)
> +#
> +# Since: 5.1
> +##
> +{ 'struct': 'NetdevVhostVDPAOptions',
> +  'data': {
> +    '*vhostdev':     'str',
> +    '*queues':       'int' } }
> +
>  ##
>  # @NetClientDriver:
>  #
> @@ -437,7 +455,7 @@
>  ##
>  { 'enum': 'NetClientDriver',
>    'data': [ 'none', 'nic', 'user', 'tap', 'l2tpv3', 'socket', 'vde',
> -            'bridge', 'hubport', 'netmap', 'vhost-user' ] }
> +            'bridge', 'hubport', 'netmap', 'vhost-user', 'vhost-vdpa' ] }
>  
>  ##
>  # @Netdev:
> @@ -465,7 +483,8 @@
>      'bridge':   'NetdevBridgeOptions',
>      'hubport':  'NetdevHubPortOptions',
>      'netmap':   'NetdevNetmapOptions',
> -    'vhost-user': 'NetdevVhostUserOptions' } }
> +    'vhost-user': 'NetdevVhostUserOptions',
> +    'vhost-vdpa': 'NetdevVhostVDPAOptions' } }
>  
>  ##
>  # @NetLegacy:



^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v1 04/10] virtio-pci: implement queue_enabled method
  2020-06-22 15:37 ` [PATCH v1 04/10] virtio-pci: implement " Cindy Lu
@ 2020-06-23  7:13   ` Jason Wang
  2020-06-23  9:18     ` Cindy Lu
  2020-06-24 13:24   ` Laurent Vivier
  1 sibling, 1 reply; 46+ messages in thread
From: Jason Wang @ 2020-06-23  7:13 UTC (permalink / raw)
  To: Cindy Lu, mst, armbru, eblake, cohuck
  Cc: mhabets, qemu-devel, rob.miller, saugatm, hanand, hch, eperezma,
	jgg, shahafs, kevin.tian, parav, vmireyno, cunming.liang, gdawar,
	jiri, xiao.w.wang, stefanha, zhihong.wang, aadam, rdunlap,
	maxime.coquelin, lingshan.zhu


On 2020/6/22 下午11:37, Cindy Lu wrote:
> From: Jason Wang <jasowang@redhat.com>
>
> With version 1, we can detect whether a queue is enabled via
> queue_enabled.
>
> Signed-off-by: Jason Wang <jasowang@redhat.com>
> Signed-off-by: Cindy Lu <lulu@redhat.com>
> ---
>   hw/virtio/virtio-pci.c | 18 ++++++++++++++++++
>   1 file changed, 18 insertions(+)
>
> diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
> index 4cb784389c..3918aa9f6c 100644
> --- a/hw/virtio/virtio-pci.c
> +++ b/hw/virtio/virtio-pci.c
> @@ -1107,6 +1107,23 @@ static AddressSpace *virtio_pci_get_dma_as(DeviceState *d)
>       return pci_get_address_space(dev);
>   }
>   
> +static bool  virtio_queue_check_enabled(VirtIODevice *vdev, int n)


One space is sufficient between bool and virtio_queue_check_enabled.


> +{
> +    return  virtio_queue_get_desc_addr(vdev, n) != 0;
> +}
> +
> +static bool virtio_pci_queue_enabled(DeviceState *d, int n)
> +{
> +    VirtIOPCIProxy *proxy = VIRTIO_PCI(d);
> +    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
> +
> +    if (virtio_vdev_has_feature(vdev, VIRTIO_F_VERSION_1)) {
> +        return proxy->vqs[vdev->queue_sel].enabled;
> +    }
> +
> +    return  virtio_queue_check_enabled(vdev, n);


Similar issue here.

Thanks


> +}
> +
>   static int virtio_pci_add_mem_cap(VirtIOPCIProxy *proxy,
>                                      struct virtio_pci_cap *cap)
>   {
> @@ -2059,6 +2076,7 @@ static void virtio_pci_bus_class_init(ObjectClass *klass, void *data)
>       k->ioeventfd_enabled = virtio_pci_ioeventfd_enabled;
>       k->ioeventfd_assign = virtio_pci_ioeventfd_assign;
>       k->get_dma_as = virtio_pci_get_dma_as;
> +    k->queue_enabled = virtio_pci_queue_enabled;
>   }
>   
>   static const TypeInfo virtio_pci_bus_info = {



^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v1 06/10] vhsot_net: introduce set_config & get_config function
  2020-06-22 15:37 ` [PATCH v1 06/10] vhsot_net: introduce set_config & get_config function Cindy Lu
@ 2020-06-23  7:18   ` Jason Wang
  2020-06-23  9:22     ` Cindy Lu
  0 siblings, 1 reply; 46+ messages in thread
From: Jason Wang @ 2020-06-23  7:18 UTC (permalink / raw)
  To: Cindy Lu, mst, armbru, eblake, cohuck
  Cc: mhabets, qemu-devel, rob.miller, saugatm, hanand, hch, eperezma,
	jgg, shahafs, kevin.tian, parav, vmireyno, cunming.liang, gdawar,
	jiri, xiao.w.wang, stefanha, zhihong.wang, aadam, rdunlap,
	maxime.coquelin, lingshan.zhu


On 2020/6/22 下午11:37, Cindy Lu wrote:
> This patch introduces set_config & get_config  method which allows


One space is sufficient between get_config and method.


> vhost_net set/get the config to backend


Typo in the subject.


>
> Signed-off-by: Cindy Lu <lulu@redhat.com>
> ---
>   hw/net/vhost_net.c      | 11 +++++++++++
>   include/net/vhost_net.h |  5 +++++
>   2 files changed, 16 insertions(+)
>
> diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c
> index 4096d64aaf..04cc3db264 100644
> --- a/hw/net/vhost_net.c
> +++ b/hw/net/vhost_net.c

Is there any reason that making this net specific? I guess it could be 
used by other vhost devices as well.

Thanks


> @@ -111,6 +111,17 @@ uint64_t vhost_net_get_features(struct vhost_net *net, uint64_t features)
>               features);
>   }
>   
> +int vhost_net_get_config(struct vhost_net *net,  uint8_t *config,
> +                         uint32_t config_len)
> +{
> +    return vhost_dev_get_config(&net->dev, config, config_len);
> +}
> +int vhost_net_set_config(struct vhost_net *net, const uint8_t *data,
> +                         uint32_t offset, uint32_t size, uint32_t flags)
> +{
> +    return vhost_dev_set_config(&net->dev, data, offset, size, flags);
> +}
> +
>   void vhost_net_ack_features(struct vhost_net *net, uint64_t features)
>   {
>       net->dev.acked_features = net->dev.backend_features;
> diff --git a/include/net/vhost_net.h b/include/net/vhost_net.h
> index 77e47398c4..abfb0e8e68 100644
> --- a/include/net/vhost_net.h
> +++ b/include/net/vhost_net.h
> @@ -27,6 +27,11 @@ void vhost_net_cleanup(VHostNetState *net);
>   
>   uint64_t vhost_net_get_features(VHostNetState *net, uint64_t features);
>   void vhost_net_ack_features(VHostNetState *net, uint64_t features);
> +int vhost_net_get_config(struct vhost_net *net,  uint8_t *config,
> +                         uint32_t config_len);
> +
> +int vhost_net_set_config(struct vhost_net *net, const uint8_t *data,
> +                         uint32_t offset, uint32_t size, uint32_t flags);
>   
>   bool vhost_net_virtqueue_pending(VHostNetState *net, int n);
>   void vhost_net_virtqueue_mask(VHostNetState *net, VirtIODevice *dev,



^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v1 08/10] vhost: implement vhost_dev_start method
  2020-06-22 15:37 ` [PATCH v1 08/10] vhost: implement vhost_dev_start method Cindy Lu
@ 2020-06-23  7:21   ` Jason Wang
  2020-06-23  9:34     ` Cindy Lu
  2020-06-25 14:35   ` Laurent Vivier
  1 sibling, 1 reply; 46+ messages in thread
From: Jason Wang @ 2020-06-23  7:21 UTC (permalink / raw)
  To: Cindy Lu, mst, armbru, eblake, cohuck
  Cc: mhabets, qemu-devel, rob.miller, saugatm, hanand, hch, eperezma,
	jgg, shahafs, kevin.tian, parav, vmireyno, cunming.liang, gdawar,
	jiri, xiao.w.wang, stefanha, zhihong.wang, aadam, rdunlap,
	maxime.coquelin, lingshan.zhu


On 2020/6/22 下午11:37, Cindy Lu wrote:
> use the vhost_dev_start callback to send the status to backend


I suggest to squash this into previous patch.


>
> Signed-off-by: Cindy Lu <lulu@redhat.com>
> ---
>   hw/virtio/vhost.c         | 17 +++++++++++++++++
>   include/hw/virtio/vhost.h |  2 ++
>   2 files changed, 19 insertions(+)
>
> diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
> index 01ebe12f28..bfd7f9ce1f 100644
> --- a/hw/virtio/vhost.c
> +++ b/hw/virtio/vhost.c
> @@ -744,6 +744,7 @@ static void vhost_iommu_region_del(MemoryListener *listener,
>       }
>   }
>   
> +
>   static int vhost_virtqueue_set_addr(struct vhost_dev *dev,
>                                       struct vhost_virtqueue *vq,
>                                       unsigned idx, bool enable_log)
> @@ -1661,6 +1662,11 @@ int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev)
>           }
>       }
>   
> +    r = vhost_set_start(hdev, true);


I think we need a better name for this function.


> +    if (r) {
> +        goto fail_log;
> +    }
> +
>       if (vhost_dev_has_iommu(hdev)) {
>           hdev->vhost_ops->vhost_set_iotlb_callback(hdev, true);
>   
> @@ -1697,6 +1703,8 @@ void vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev)
>       /* should only be called after backend is connected */
>       assert(hdev->vhost_ops);
>   
> +    vhost_set_start(hdev, false);
> +
>       for (i = 0; i < hdev->nvqs; ++i) {
>           vhost_virtqueue_stop(hdev,
>                                vdev,
> @@ -1722,3 +1730,12 @@ int vhost_net_set_backend(struct vhost_dev *hdev,
>   
>       return -1;
>   }
> +
> +int vhost_set_start(struct vhost_dev *hdev, bool started)
> +{
> +
> +    if (hdev->vhost_ops->vhost_dev_start) {
> +        hdev->vhost_ops->vhost_dev_start(hdev, started);
> +    }
> +    return 0;
> +}
> diff --git a/include/hw/virtio/vhost.h b/include/hw/virtio/vhost.h
> index 085450c6f8..59ea53f8c2 100644
> --- a/include/hw/virtio/vhost.h
> +++ b/include/hw/virtio/vhost.h
> @@ -92,6 +92,7 @@ struct vhost_dev {
>       const VhostDevConfigOps *config_ops;
>   };
>   
> +
>   int vhost_dev_init(struct vhost_dev *hdev, void *opaque,
>                      VhostBackendType backend_type,
>                      uint32_t busyloop_timeout);
> @@ -137,4 +138,5 @@ int vhost_dev_set_inflight(struct vhost_dev *dev,
>                              struct vhost_inflight *inflight);
>   int vhost_dev_get_inflight(struct vhost_dev *dev, uint16_t queue_size,
>                              struct vhost_inflight *inflight);
> +int vhost_set_start(struct vhost_dev *dev, bool started);


Any reason for exporting this? It looks to me there's no real user out 
this file.

Thanks


>   #endif



^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v1 09/10] vhost-vdpa: introduce vhost-vdpa backend
  2020-06-22 15:37 ` [PATCH v1 09/10] vhost-vdpa: introduce vhost-vdpa backend Cindy Lu
@ 2020-06-23  7:31   ` Jason Wang
  2020-06-23  9:38     ` Cindy Lu
  2020-06-25 12:36   ` Laurent Vivier
  2020-06-30  7:18   ` Maxime Coquelin
  2 siblings, 1 reply; 46+ messages in thread
From: Jason Wang @ 2020-06-23  7:31 UTC (permalink / raw)
  To: Cindy Lu, mst, armbru, eblake, cohuck
  Cc: mhabets, qemu-devel, rob.miller, saugatm, hanand, hch, eperezma,
	jgg, shahafs, kevin.tian, parav, vmireyno, cunming.liang, gdawar,
	jiri, xiao.w.wang, stefanha, zhihong.wang, Tiwei Bie, aadam,
	rdunlap, maxime.coquelin, lingshan.zhu


On 2020/6/22 下午11:37, Cindy Lu wrote:
> Currently we have 2 types of vhost backends in QEMU: vhost kernel and
> vhost-user. The above patch provides a generic device for vDPA purpose,
> this vDPA device exposes to user space a non-vendor-specific configuration
> interface for setting up a vhost HW accelerator, this patch set introduces
> a third vhost backend called vhost-vdpa based on the vDPA interface.
>
> Vhost-vdpa usage:
>
> qemu-system-x86_64 -cpu host -enable-kvm \
>      ......
>      -netdev type=vhost-vdpa,vhostdev=/dev/vhost-vdpa-id,id=vhost-vdpa0 \
>      -device virtio-net-pci,netdev=vhost-vdpa0,page-per-vq=on \
>
> Signed-off-by: Lingshan zhu <lingshan.zhu@intel.com>
> Signed-off-by: Tiwei Bie <tiwei.bie@intel.com>
> Signed-off-by: Cindy Lu <lulu@redhat.com>
> ---
>   configure                         |  21 ++
>   hw/net/vhost_net.c                |  19 +-
>   hw/net/virtio-net.c               |  19 +-
>   hw/virtio/Makefile.objs           |   1 +
>   hw/virtio/vhost-backend.c         |  22 +-
>   hw/virtio/vhost-vdpa.c            | 406 ++++++++++++++++++++++++++++++
>   hw/virtio/vhost.c                 |  42 +++-
>   include/hw/virtio/vhost-backend.h |   6 +-
>   include/hw/virtio/vhost-vdpa.h    |  26 ++
>   include/hw/virtio/vhost.h         |   6 +
>   qemu-options.hx                   |  12 +
>   11 files changed, 555 insertions(+), 25 deletions(-)
>   create mode 100644 hw/virtio/vhost-vdpa.c
>   create mode 100644 include/hw/virtio/vhost-vdpa.h
>
> diff --git a/configure b/configure
> index 23b5e93752..53679ee57f 100755
> --- a/configure
> +++ b/configure
> @@ -1557,6 +1557,10 @@ for opt do
>     ;;
>     --enable-vhost-user) vhost_user="yes"
>     ;;
> +  --disable-vhost-vdpa) vhost_vdpa="no"
> +  ;;
> +  --enable-vhost-vdpa) vhost_vdpa="yes"
> +  ;;
>     --disable-vhost-kernel) vhost_kernel="no"
>     ;;
>     --enable-vhost-kernel) vhost_kernel="yes"
> @@ -1846,6 +1850,7 @@ disabled with --disable-FEATURE, default is enabled if available:
>     vhost-crypto    vhost-user-crypto backend support
>     vhost-kernel    vhost kernel backend support
>     vhost-user      vhost-user backend support
> +  vhost-vdpa      vhost-vdpa kernel backend support
>     spice           spice
>     rbd             rados block device (rbd)
>     libiscsi        iscsi support
> @@ -2336,6 +2341,10 @@ test "$vhost_user" = "" && vhost_user=yes
>   if test "$vhost_user" = "yes" && test "$mingw32" = "yes"; then
>     error_exit "vhost-user isn't available on win32"
>   fi
> +test "$vhost_vdpa" = "" && vhost_vdpa=$linux
> +if test "$vhost_vdpa" = "yes" && test "$linux" != "yes"; then
> +  error_exit "vhost-vdpa is only available on Linux"
> +fi
>   test "$vhost_kernel" = "" && vhost_kernel=$linux
>   if test "$vhost_kernel" = "yes" && test "$linux" != "yes"; then
>     error_exit "vhost-kernel is only available on Linux"
> @@ -2364,6 +2373,11 @@ test "$vhost_user_fs" = "" && vhost_user_fs=$vhost_user
>   if test "$vhost_user_fs" = "yes" && test "$vhost_user" = "no"; then
>     error_exit "--enable-vhost-user-fs requires --enable-vhost-user"
>   fi
> +#vhost-vdpa backends
> +test "$vhost_net_vdpa" = "" && vhost_net_vdpa=$vhost_vdpa
> +if test "$vhost_net_vdpa" = "yes" && test "$vhost_vdpa" = "no"; then
> +  error_exit "--enable-vhost-net-vdpa requires --enable-vhost-vdpa"
> +fi
>   
>   # OR the vhost-kernel and vhost-user values for simplicity
>   if test "$vhost_net" = ""; then
> @@ -6673,6 +6687,7 @@ echo "vhost-scsi support $vhost_scsi"
>   echo "vhost-vsock support $vhost_vsock"
>   echo "vhost-user support $vhost_user"
>   echo "vhost-user-fs support $vhost_user_fs"
> +echo "vhost-vdpa support $vhost_vdpa"
>   echo "Trace backends    $trace_backends"
>   if have_backend "simple"; then
>   echo "Trace output file $trace_file-<pid>"
> @@ -7170,6 +7185,9 @@ fi
>   if test "$vhost_net_user" = "yes" ; then
>     echo "CONFIG_VHOST_NET_USER=y" >> $config_host_mak
>   fi
> +if test "$vhost_net_vdpa" = "yes" ; then
> +  echo "CONFIG_VHOST_NET_VDPA=y" >> $config_host_mak
> +fi
>   if test "$vhost_crypto" = "yes" ; then
>     echo "CONFIG_VHOST_CRYPTO=y" >> $config_host_mak
>   fi
> @@ -7182,6 +7200,9 @@ fi
>   if test "$vhost_user" = "yes" ; then
>     echo "CONFIG_VHOST_USER=y" >> $config_host_mak
>   fi
> +if test "$vhost_vdpa" = "yes" ; then
> +  echo "CONFIG_VHOST_VDPA=y" >> $config_host_mak
> +fi
>   if test "$vhost_user_fs" = "yes" ; then
>     echo "CONFIG_VHOST_USER_FS=y" >> $config_host_mak
>   fi
> diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c
> index 04cc3db264..cc259e571d 100644
> --- a/hw/net/vhost_net.c
> +++ b/hw/net/vhost_net.c
> @@ -17,8 +17,10 @@
>   #include "net/net.h"
>   #include "net/tap.h"
>   #include "net/vhost-user.h"
> +#include "net/vhost-vdpa.h"
>   
>   #include "standard-headers/linux/vhost_types.h"
> +#include "linux-headers/linux/vhost.h"
>   #include "hw/virtio/virtio-net.h"
>   #include "net/vhost_net.h"
>   #include "qemu/error-report.h"
> @@ -33,12 +35,6 @@
>   #include "hw/virtio/vhost.h"
>   #include "hw/virtio/virtio-bus.h"
>   
> -struct vhost_net {
> -    struct vhost_dev dev;
> -    struct vhost_virtqueue vqs[2];
> -    int backend;
> -    NetClientState *nc;
> -};
>   
>   /* Features supported by host kernel. */
>   static const int kernel_feature_bits[] = {
> @@ -84,7 +80,6 @@ static const int user_feature_bits[] = {
>   
>       VHOST_INVALID_FEATURE_BIT
>   };
> -


Unnecessary change.


>   static const int *vhost_net_get_feature_bits(struct vhost_net *net)
>   {
>       const int *feature_bits = 0;
> @@ -96,6 +91,9 @@ static const int *vhost_net_get_feature_bits(struct vhost_net *net)
>       case NET_CLIENT_DRIVER_VHOST_USER:
>           feature_bits = user_feature_bits;
>           break;
> +    case NET_CLIENT_DRIVER_VHOST_VDPA:
> +        feature_bits = vdpa_feature_bits;
> +        break;
>       default:
>           error_report("Feature bits not defined for this type: %d",
>                   net->nc->info->type);
> @@ -348,6 +346,7 @@ int vhost_net_start(VirtIODevice *dev, NetClientState *ncs,
>       }
>   
>       for (i = 0; i < total_queues; i++) {
> +


Unnecessary change.


>           peer = qemu_get_peer(ncs, i);
>           r = vhost_net_start_one(get_vhost_net(peer), dev);
>   
> @@ -444,6 +443,12 @@ VHostNetState *get_vhost_net(NetClientState *nc)
>           vhost_net = vhost_user_get_vhost_net(nc);
>           assert(vhost_net);
>           break;
> +#endif
> +#ifdef CONFIG_VHOST_NET_VDPA
> +    case NET_CLIENT_DRIVER_VHOST_VDPA:
> +        vhost_net = vhost_vdpa_get_vhost_net(nc);
> +        assert(vhost_net);
> +        break;
>   #endif
>       default:
>           break;
> diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
> index a46e3b37a7..8c85e2e1e1 100644
> --- a/hw/net/virtio-net.c
> +++ b/hw/net/virtio-net.c
> @@ -42,6 +42,7 @@
>   #include "trace.h"
>   #include "monitor/qdev.h"
>   #include "hw/pci/pci.h"
> +#include "hw/virtio/vhost.h"
>   
>   #define VIRTIO_NET_VM_VERSION    11
>   
> @@ -131,6 +132,8 @@ static void virtio_net_get_config(VirtIODevice *vdev, uint8_t *config)
>   {
>       VirtIONet *n = VIRTIO_NET(vdev);
>       struct virtio_net_config netcfg;
> +    int ret = 0;
> +    memset(&netcfg, 0 , sizeof(struct virtio_net_config));
>   
>       virtio_stw_p(vdev, &netcfg.status, n->status);
>       virtio_stw_p(vdev, &netcfg.max_virtqueue_pairs, n->max_queues);
> @@ -139,13 +142,21 @@ static void virtio_net_get_config(VirtIODevice *vdev, uint8_t *config)
>       virtio_stl_p(vdev, &netcfg.speed, n->net_conf.speed);
>       netcfg.duplex = n->net_conf.duplex;
>       memcpy(config, &netcfg, n->config_size);
> +    NetClientState *nc = qemu_get_queue(n->nic);
> +    if (nc->peer->info->type == NET_CLIENT_DRIVER_VHOST_VDPA) {
> +        ret = vhost_net_get_config(get_vhost_net(nc->peer), (uint8_t *)&netcfg,
> +                             n->config_size);
> +        if (ret != -1) {
> +            memcpy(config, &netcfg, n->config_size);
> +        }
> +    }


This is kind of sub-optimal.

I think the a better approach is deal all the stuffs inside 
vhost_net_get_config().


>   }
>   
>   static void virtio_net_set_config(VirtIODevice *vdev, const uint8_t *config)
>   {
>       VirtIONet *n = VIRTIO_NET(vdev);
> +    NetClientState *nc = qemu_get_queue(n->nic);
>       struct virtio_net_config netcfg = {};
> -


Unnecessary change.


>       memcpy(&netcfg, config, n->config_size);
>   
>       if (!virtio_vdev_has_feature(vdev, VIRTIO_NET_F_CTRL_MAC_ADDR) &&
> @@ -154,6 +165,11 @@ static void virtio_net_set_config(VirtIODevice *vdev, const uint8_t *config)
>           memcpy(n->mac, netcfg.mac, ETH_ALEN);
>           qemu_format_nic_info_str(qemu_get_queue(n->nic), n->mac);
>       }
> +    if (nc->peer->info->type == NET_CLIENT_DRIVER_VHOST_VDPA) {
> +        vhost_net_set_config(get_vhost_net(nc->peer), (uint8_t *)&netcfg,
> +                               0, n->config_size,
> +                               VHOST_SET_CONFIG_TYPE_MASTER);
> +      }


Similar issues as get_config.


>   }
>   
>   static bool virtio_net_started(VirtIONet *n, uint8_t status)
> @@ -2958,7 +2974,6 @@ static void virtio_net_device_realize(DeviceState *dev, Error **errp)
>       } else if (n->net_conf.speed >= 0) {
>           n->host_features |= (1ULL << VIRTIO_NET_F_SPEED_DUPLEX);
>       }
> -


Unnecessary change.


>       if (n->failover) {
>           n->primary_listener.should_be_hidden =
>               virtio_net_primary_should_be_hidden;
> diff --git a/hw/virtio/Makefile.objs b/hw/virtio/Makefile.objs
> index 4e4d39a0a4..6b1b1a5fce 100644
> --- a/hw/virtio/Makefile.objs
> +++ b/hw/virtio/Makefile.objs
> @@ -5,6 +5,7 @@ obj-y += virtio.o
>   obj-$(CONFIG_VHOST) += vhost.o vhost-backend.o
>   common-obj-$(call lnot,$(CONFIG_VHOST)) += vhost-stub.o
>   obj-$(CONFIG_VHOST_USER) += vhost-user.o
> +obj-$(CONFIG_VHOST_VDPA) += vhost-vdpa.o
>   
>   common-obj-$(CONFIG_VIRTIO_RNG) += virtio-rng.o
>   common-obj-$(CONFIG_VIRTIO_PCI) += virtio-pci.o
> diff --git a/hw/virtio/vhost-backend.c b/hw/virtio/vhost-backend.c
> index 660e9e8588..84e5b1a833 100644
> --- a/hw/virtio/vhost-backend.c
> +++ b/hw/virtio/vhost-backend.c
> @@ -14,7 +14,7 @@
>   #include "qemu/error-report.h"
>   #include "qemu/main-loop.h"
>   #include "standard-headers/linux/vhost_types.h"
> -
> +#include "hw/virtio/vhost-vdpa.h"
>   #ifdef CONFIG_VHOST_KERNEL
>   #include <linux/vhost.h>
>   #include <sys/ioctl.h>
> @@ -22,10 +22,19 @@
>   static int vhost_kernel_call(struct vhost_dev *dev, unsigned long int request,
>                                void *arg)
>   {
> -    int fd = (uintptr_t) dev->opaque;
> -
> -    assert(dev->vhost_ops->backend_type == VHOST_BACKEND_TYPE_KERNEL);
> +    int fd = -1;
> +    switch (dev->vhost_ops->backend_type) {
> +    case VHOST_BACKEND_TYPE_KERNEL:
> +        fd  = (uintptr_t)dev->opaque;
> +        break;
> +    case VHOST_BACKEND_TYPE_VDPA:
> +        fd = ((struct vhost_vdpa *)dev->opaque)->device_fd;
> +        break;
> +    default:
> +        g_assert_not_reached();
> +    }
>   
> +    assert(fd != -1);
>       return ioctl(fd, request, arg);
>   }
>   
> @@ -285,6 +294,11 @@ int vhost_set_backend_type(struct vhost_dev *dev, VhostBackendType backend_type)
>       case VHOST_BACKEND_TYPE_USER:
>           dev->vhost_ops = &user_ops;
>           break;
> +#endif
> +#ifdef CONFIG_VHOST_VDPA
> +    case VHOST_BACKEND_TYPE_VDPA:
> +        dev->vhost_ops = &vdpa_ops;
> +        break;
>   #endif
>       default:
>           error_report("Unknown vhost backend type");
> diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c
> new file mode 100644
> index 0000000000..1724d404ce
> --- /dev/null
> +++ b/hw/virtio/vhost-vdpa.c
> @@ -0,0 +1,406 @@
> +/*
> + * vhost-vdpa
> + *
> + *  Copyright(c) 2017-2018 Intel Corporation.
> + *  Copyright(c) 2020 Red Hat, Inc.
> + *
> + * This work is licensed under the terms of the GNU GPL, version 2 or later.
> + * See the COPYING file in the top-level directory.
> + *
> + */
> +
> +#include "qemu/osdep.h"
> +#include <linux/vhost.h>
> +#include <linux/vfio.h>
> +#include <sys/eventfd.h>
> +#include <sys/ioctl.h>
> +#include "hw/virtio/vhost.h"
> +#include "hw/virtio/vhost-backend.h"
> +#include "hw/virtio/virtio-net.h"
> +#include "hw/virtio/vhost-vdpa.h"
> +#include "qemu/main-loop.h"
> +#include <linux/kvm.h>
> +#include "sysemu/kvm.h"
> +
> +
> +static bool vhost_vdpa_listener_skipped_section(MemoryRegionSection *section)
> +{
> +    return (!memory_region_is_ram(section->mr) &&
> +            !memory_region_is_iommu(section->mr)) ||
> +           /*
> +            * Sizing an enabled 64-bit BAR can cause spurious mappings to
> +            * addresses in the upper part of the 64-bit address space.  These
> +            * are never accessed by the CPU and beyond the address width of
> +            * some IOMMU hardware.  TODO: VDPA should tell us the IOMMU width.


Note that, I post patches for reporting IOVA range, we need add the 
check through that in the future.


> +            */
> +           section->offset_within_address_space & (1ULL << 63);
> +}
> +
> +static int vhost_vdpa_dma_map(struct vhost_vdpa *v, hwaddr iova, hwaddr size,
> +                              void *vaddr, bool readonly)
> +{
> +    struct vhost_msg_v2 msg;
> +    int fd = v->device_fd;
> +    int ret = 0;
> +
> +    msg.type =  v->msg_type;
> +    msg.iotlb.iova = iova;
> +    msg.iotlb.size = size;
> +    msg.iotlb.uaddr = (uint64_t)vaddr;
> +    msg.iotlb.perm = readonly ? VHOST_ACCESS_RO : VHOST_ACCESS_RW;
> +    msg.iotlb.type = VHOST_IOTLB_UPDATE;
> +
> +    if (write(fd, &msg, sizeof(msg)) != sizeof(msg)) {
> +        error_report("failed to write, fd=%d, errno=%d (%s)",
> +            fd, errno, strerror(errno));
> +        return -EIO ;
> +    }
> +
> +    return ret;
> +}
> +
> +static int vhost_vdpa_dma_unmap(struct vhost_vdpa *v, hwaddr iova,
> +                                hwaddr size)
> +{
> +    struct vhost_msg_v2 msg;
> +    int fd = v->device_fd;
> +    int ret = 0;
> +
> +    msg.type =  v->msg_type;
> +    msg.iotlb.iova = iova;
> +    msg.iotlb.size = size;
> +    msg.iotlb.type = VHOST_IOTLB_INVALIDATE;
> +
> +    if (write(fd, &msg, sizeof(msg)) != sizeof(msg)) {
> +        error_report("failed to write, fd=%d, errno=%d (%s)",
> +            fd, errno, strerror(errno));
> +        return -EIO ;
> +    }
> +
> +    return ret;
> +}
> +
> +static void vhost_vdpa_listener_region_add(MemoryListener *listener,
> +                                           MemoryRegionSection *section)
> +{
> +    struct vhost_vdpa *v = container_of(listener, struct vhost_vdpa, listener);
> +    hwaddr iova;
> +    Int128 llend, llsize;
> +    void *vaddr;
> +    int ret;
> +
> +    if (vhost_vdpa_listener_skipped_section(section)) {
> +        return;
> +    }
> +
> +    if (unlikely((section->offset_within_address_space & ~TARGET_PAGE_MASK) !=
> +                 (section->offset_within_region & ~TARGET_PAGE_MASK))) {
> +        error_report("%s received unaligned region", __func__);
> +        return;
> +    }
> +
> +    iova = TARGET_PAGE_ALIGN(section->offset_within_address_space);
> +    llend = int128_make64(section->offset_within_address_space);
> +    llend = int128_add(llend, section->size);
> +    llend = int128_and(llend, int128_exts64(TARGET_PAGE_MASK));
> +
> +    if (int128_ge(int128_make64(iova), llend)) {
> +        return;
> +    }
> +
> +    memory_region_ref(section->mr);
> +
> +    /* Here we assume that memory_region_is_ram(section->mr)==true */
> +
> +    vaddr = memory_region_get_ram_ptr(section->mr) +
> +            section->offset_within_region +
> +            (iova - section->offset_within_address_space);
> +
> +    llsize = int128_sub(llend, int128_make64(iova));
> +
> +    ret = vhost_vdpa_dma_map(v, iova, int128_get64(llsize),
> +                             vaddr, section->readonly);
> +    if (ret) {
> +        error_report("vhost vdpa map fail!");
> +        if (memory_region_is_ram_device(section->mr)) {
> +            /* Allow unexpected mappings not to be fatal for RAM devices */
> +            error_report("map ram fail!");
> +          return ;
> +        }
> +        goto fail;
> +    }
> +
> +    return;
> +
> +fail:
> +    if (memory_region_is_ram_device(section->mr)) {
> +        error_report("failed to vdpa_dma_map. pci p2p may not work");
> +        return;
> +
> +    }
> +    /*
> +     * On the initfn path, store the first error in the container so we
> +     * can gracefully fail.  Runtime, there's not much we can do other
> +     * than throw a hardware error.
> +     */
> +    error_report("vhost-vdpa: DMA mapping failed, unable to continue");
> +    return;
> +
> +}
> +
> +static void vhost_vdpa_listener_region_del(MemoryListener *listener,
> +                                           MemoryRegionSection *section)
> +{
> +    struct vhost_vdpa *v = container_of(listener, struct vhost_vdpa, listener);
> +    hwaddr iova;
> +    Int128 llend, llsize;
> +    int ret;
> +    bool try_unmap = true;
> +
> +    if (vhost_vdpa_listener_skipped_section(section)) {
> +        return;
> +    }
> +
> +    if (unlikely((section->offset_within_address_space & ~TARGET_PAGE_MASK) !=
> +                 (section->offset_within_region & ~TARGET_PAGE_MASK))) {
> +        error_report("%s received unaligned region", __func__);
> +        return;
> +    }
> +
> +    iova = TARGET_PAGE_ALIGN(section->offset_within_address_space);
> +    llend = int128_make64(section->offset_within_address_space);
> +    llend = int128_add(llend, section->size);
> +    llend = int128_and(llend, int128_exts64(TARGET_PAGE_MASK));
> +
> +    if (int128_ge(int128_make64(iova), llend)) {
> +        return;
> +    }
> +
> +    llsize = int128_sub(llend, int128_make64(iova));
> +
> +    if (try_unmap) {
> +        ret = vhost_vdpa_dma_unmap(v, iova, int128_get64(llsize));
> +        if (ret) {
> +            error_report("vhost_vdpa dma unmap error!");
> +        }
> +    }
> +
> +    memory_region_unref(section->mr);
> +}
> +/*
> + * IOTLB API is used by vhost-vpda which requires incremental updating
> + * of the mapping. So we can not use generic vhost memory listener which
> + * depends on the addnop().
> + */
> +static const MemoryListener vhost_vdpa_memory_listener = {
> +    .region_add = vhost_vdpa_listener_region_add,
> +    .region_del = vhost_vdpa_listener_region_del,
> +};
> +
> +static int vhost_vdpa_call(struct vhost_dev *dev, unsigned long int request,
> +                             void *arg)
> +{
> +    struct vhost_vdpa *v = dev->opaque;
> +    int fd = v->device_fd;
> +
> +    assert(dev->vhost_ops->backend_type == VHOST_BACKEND_TYPE_VDPA);
> +
> +    return ioctl(fd, request, arg);
> +}
> +
> +static void vhost_vdpa_add_status(struct vhost_dev *dev, uint8_t status)
> +{
> +    uint8_t s;
> +
> +    if (vhost_vdpa_call(dev, VHOST_VDPA_GET_STATUS, &s)) {
> +        return;
> +    }
> +
> +    s |= status;
> +
> +    vhost_vdpa_call(dev, VHOST_VDPA_SET_STATUS, &s);
> +}
> +
> +static int vhost_vdpa_init(struct vhost_dev *dev, void *opaque)
> +{
> +    struct vhost_vdpa *v;
> +    uint64_t features;
> +    assert(dev->vhost_ops->backend_type == VHOST_BACKEND_TYPE_VDPA);
> +
> +    v = opaque;
> +    dev->opaque =  opaque ;
> +    vhost_vdpa_call(dev, VHOST_GET_FEATURES, &features);
> +    dev->backend_features = features;
> +    v->listener = vhost_vdpa_memory_listener;
> +    v->msg_type = VHOST_IOTLB_MSG_V2;
> +
> +    vhost_vdpa_add_status(dev, VIRTIO_CONFIG_S_ACKNOWLEDGE |
> +                               VIRTIO_CONFIG_S_DRIVER);
> +
> +    return 0;
> +}
> +
> +static int vhost_vdpa_cleanup(struct vhost_dev *dev)
> +{
> +    struct vhost_vdpa *v;
> +    assert(dev->vhost_ops->backend_type == VHOST_BACKEND_TYPE_VDPA);
> +    v = dev->opaque;
> +    memory_listener_unregister(&v->listener);
> +
> +    dev->opaque = NULL;
> +    return 0;
> +}
> +
> +static int vhost_vdpa_memslots_limit(struct vhost_dev *dev)
> +{
> +    return INT_MAX;
> +}
> +
> +static int vhost_vdpa_set_mem_table(struct vhost_dev *dev,
> +                                    struct vhost_memory *mem)
> +{
> +
> +    if (mem->padding) {
> +        return -1;
> +    }
> +
> +    return 0;
> +}
> +
> +static int vhost_vdpa_set_features(struct vhost_dev *dev,
> +                                   uint64_t features)
> +{
> +    int ret;
> +    ret = vhost_vdpa_call(dev, VHOST_SET_FEATURES, &features);
> +    uint8_t status = 0;
> +    if (ret) {
> +        return ret;
> +    }
> +    vhost_vdpa_add_status(dev, VIRTIO_CONFIG_S_FEATURES_OK);
> +    vhost_vdpa_call(dev, VHOST_VDPA_GET_STATUS, &status);
> +
> +    return !(status & VIRTIO_CONFIG_S_FEATURES_OK);
> +}
> +
> +int vhost_vdpa_get_device_id(struct vhost_dev *dev,
> +                                   uint32_t *device_id)
> +{
> +    return vhost_vdpa_call(dev, VHOST_VDPA_GET_DEVICE_ID, device_id);
> +}
> +
> +static int vhost_vdpa_reset_device(struct vhost_dev *dev)
> +{
> +    uint8_t status = 0;
> +
> +    return vhost_vdpa_call(dev, VHOST_VDPA_SET_STATUS, &status);
> +}
> +
> +static int vhost_vdpa_get_vq_index(struct vhost_dev *dev, int idx)
> +{
> +    assert(idx >= dev->vq_index && idx < dev->vq_index + dev->nvqs);
> +
> +    return idx - dev->vq_index;
> +}
> +
> +static int vhost_vdpa_set_vring_ready(struct vhost_dev *dev)
> +{
> +    int i;
> +    for (i = 0; i < dev->nvqs; ++i) {
> +        struct vhost_vring_state state = {
> +            .index = dev->vq_index + i,
> +            .num = 1,
> +        };
> +        vhost_vdpa_call(dev, VHOST_VDPA_SET_VRING_ENABLE, &state);
> +    }
> +    return 0;
> +}
> +
> +static int vhost_vdpa_set_config(struct vhost_dev *dev, const uint8_t *data,
> +                                   uint32_t offset, uint32_t size,
> +                                   uint32_t flags)
> +{
> +    struct vhost_vdpa_config *config;
> +    int ret;
> +    unsigned long config_size = offsetof(struct vhost_vdpa_config, buf);
> +    config = g_malloc(size + config_size);
> +    if (config == NULL) {
> +        return -1;
> +    }
> +    config->off = offset;
> +    config->len = size;
> +    memcpy(config->buf, data, size);
> +    ret = vhost_vdpa_call(dev, VHOST_VDPA_SET_CONFIG, config);
> +    g_free(config);
> +    return ret;
> +}
> +
> +static int vhost_vdpa_get_config(struct vhost_dev *dev, uint8_t *config,
> +                                   uint32_t config_len)
> +{
> +    struct vhost_vdpa_config *v_config;
> +    unsigned long config_size = offsetof(struct vhost_vdpa_config, buf);
> +    int ret;
> +
> +    v_config = g_malloc(config_len + config_size);
> +    if (v_config == NULL) {
> +        return -1;
> +    }
> +    v_config->len = config_len;
> +    v_config->off = 0;
> +    ret = vhost_vdpa_call(dev, VHOST_VDPA_GET_CONFIG, v_config);
> +    memcpy(config, v_config->buf, config_len);
> +    g_free(v_config);
> +    return ret;
> + }
> +
> +static int vhost_vdpa_dev_start(struct vhost_dev *dev, bool started)
> +{
> +    struct vhost_vdpa *v = dev->opaque;


newline is needed.


> +    if (started) {
> +        uint8_t status = 0;
> +        memory_listener_register(&v->listener, &address_space_memory);
> +        vhost_vdpa_set_vring_ready(dev);
> +        vhost_vdpa_add_status(dev, VIRTIO_CONFIG_S_DRIVER_OK);
> +        vhost_vdpa_call(dev, VHOST_VDPA_GET_STATUS, &status);
> +
> +        return !(status & VIRTIO_CONFIG_S_DRIVER_OK);
> +    } else {
> +        vhost_vdpa_reset_device(dev);
> +        vhost_vdpa_add_status(dev, VIRTIO_CONFIG_S_ACKNOWLEDGE |
> +                                   VIRTIO_CONFIG_S_DRIVER);
> +        memory_listener_unregister(&v->listener);
> +
> +        return 0;
> +    }
> +}
> +
> +const VhostOps vdpa_ops = {
> +        .backend_type = VHOST_BACKEND_TYPE_VDPA,
> +        .vhost_backend_init = vhost_vdpa_init,
> +        .vhost_backend_cleanup = vhost_vdpa_cleanup,
> +        .vhost_set_log_base = vhost_kernel_set_log_base,
> +        .vhost_set_vring_addr = vhost_kernel_set_vring_addr,
> +        .vhost_set_vring_num = vhost_kernel_set_vring_num,
> +        .vhost_set_vring_base = vhost_kernel_set_vring_base,
> +        .vhost_get_vring_base = vhost_kernel_get_vring_base,
> +        .vhost_set_vring_kick = vhost_kernel_set_vring_kick,
> +        .vhost_set_vring_call = vhost_kernel_set_vring_call,
> +        .vhost_get_features = vhost_kernel_get_features,
> +        .vhost_set_owner = vhost_kernel_set_owner,
> +        .vhost_set_vring_endian = NULL,
> +        .vhost_backend_memslots_limit = vhost_vdpa_memslots_limit,
> +        .vhost_set_mem_table = vhost_vdpa_set_mem_table,
> +        .vhost_set_features = vhost_vdpa_set_features,
> +        .vhost_reset_device = vhost_vdpa_reset_device,
> +        .vhost_get_vq_index = vhost_vdpa_get_vq_index,
> +        .vhost_get_config  = vhost_vdpa_get_config,
> +        .vhost_set_config = vhost_vdpa_set_config,
> +        .vhost_requires_shm_log = NULL,
> +        .vhost_migration_done = NULL,
> +        .vhost_backend_can_merge = NULL,
> +        .vhost_net_set_mtu = NULL,
> +        .vhost_set_iotlb_callback = NULL,
> +        .vhost_send_device_iotlb_msg = NULL,
> +        .vhost_dev_start = vhost_vdpa_dev_start,
> +        .vhost_get_device_id = vhost_vdpa_get_device_id,
> +};
> diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
> index bfd7f9ce1f..a75be7216b 100644
> --- a/hw/virtio/vhost.c
> +++ b/hw/virtio/vhost.c
> @@ -744,19 +744,34 @@ static void vhost_iommu_region_del(MemoryListener *listener,
>       }
>   }
>   
> +static void vhost_virtqueue_get_addr(struct vhost_dev *dev,
> +                                    struct vhost_vring_addr *addr,
> +                                    struct vhost_virtqueue *vq)
> +{
> +    /*vDPA need to use the IOVA here to set to hardware*/
> +    if (dev->vhost_ops->backend_type == VHOST_BACKEND_TYPE_VDPA) {


Let's introduce a new vhost_ops for this.


> +        addr->desc_user_addr = (uint64_t)(unsigned long)vq->desc_phys;
> +        addr->avail_user_addr = (uint64_t)(unsigned long)vq->avail_phys;
> +        addr->used_user_addr = (uint64_t)(unsigned long)vq->used_phys;
> +    } else {
> +        addr->desc_user_addr = (uint64_t)(unsigned long)vq->desc;
> +        addr->avail_user_addr = (uint64_t)(unsigned long)vq->avail;
> +        addr->used_user_addr = (uint64_t)(unsigned long)vq->used;
> +    }
> +}
>   
>   static int vhost_virtqueue_set_addr(struct vhost_dev *dev,
>                                       struct vhost_virtqueue *vq,
>                                       unsigned idx, bool enable_log)
>   {
> -    struct vhost_vring_addr addr = {
> -        .index = idx,
> -        .desc_user_addr = (uint64_t)(unsigned long)vq->desc,
> -        .avail_user_addr = (uint64_t)(unsigned long)vq->avail,
> -        .used_user_addr = (uint64_t)(unsigned long)vq->used,
> -        .log_guest_addr = vq->used_phys,
> -        .flags = enable_log ? (1 << VHOST_VRING_F_LOG) : 0,
> -    };
> +    struct vhost_vring_addr addr;
> +    memset(&addr, 0, sizeof(struct vhost_vring_addr));
> +
> +    vhost_virtqueue_get_addr(dev, &addr, vq);
> +    addr.index = idx;
> +    addr .log_guest_addr = vq->used_phys;
> +    addr .flags = enable_log ? (1 << VHOST_VRING_F_LOG) : 0;


Unnecessary spaces between addr and log_guest_addr/flags.


> +
>       int r = dev->vhost_ops->vhost_set_vring_addr(dev, &addr);
>       if (r < 0) {
>           VHOST_OPS_DEBUG("vhost_set_vring_addr failed");
> @@ -774,7 +789,9 @@ static int vhost_dev_set_features(struct vhost_dev *dev,
>           features |= 0x1ULL << VHOST_F_LOG_ALL;
>       }
>       if (!vhost_dev_has_iommu(dev)) {
> -        features &= ~(0x1ULL << VIRTIO_F_IOMMU_PLATFORM);



A comment is needed here.


> +        if (dev->vhost_ops->backend_type != VHOST_BACKEND_TYPE_VDPA) {
> +            features &= ~(0x1ULL << VIRTIO_F_IOMMU_PLATFORM);
> +        }
>       }
>       r = dev->vhost_ops->vhost_set_features(dev, features);
>       if (r < 0) {
> @@ -1667,7 +1684,8 @@ int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev)
>           goto fail_log;
>       }
>   
> -    if (vhost_dev_has_iommu(hdev)) {
> +    if (vhost_dev_has_iommu(hdev) &&
> +        hdev->vhost_ops->vhost_set_iotlb_callback) {


A separate patch for this please


>           hdev->vhost_ops->vhost_set_iotlb_callback(hdev, true);
>   
>           /* Update used ring information for IOTLB to work correctly,
> @@ -1713,7 +1731,9 @@ void vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev)
>       }
>   
>       if (vhost_dev_has_iommu(hdev)) {
> -        hdev->vhost_ops->vhost_set_iotlb_callback(hdev, false);
> +        if (hdev->vhost_ops->vhost_set_iotlb_callback) {
> +            hdev->vhost_ops->vhost_set_iotlb_callback(hdev, false);
> +        }


A separate patch for this.


>           memory_listener_unregister(&hdev->iommu_listener);
>       }
>       vhost_log_put(hdev, true);
> diff --git a/include/hw/virtio/vhost-backend.h b/include/hw/virtio/vhost-backend.h
> index c1384bd2c7..c418c2fa0e 100644
> --- a/include/hw/virtio/vhost-backend.h
> +++ b/include/hw/virtio/vhost-backend.h
> @@ -17,7 +17,8 @@ typedef enum VhostBackendType {
>       VHOST_BACKEND_TYPE_NONE = 0,
>       VHOST_BACKEND_TYPE_KERNEL = 1,
>       VHOST_BACKEND_TYPE_USER = 2,
> -    VHOST_BACKEND_TYPE_MAX = 3,
> +    VHOST_BACKEND_TYPE_VDPA = 3,
> +    VHOST_BACKEND_TYPE_MAX = 4,
>   } VhostBackendType;
>   
>   typedef enum VhostSetConfigType {
> @@ -113,6 +114,7 @@ typedef int (*vhost_set_inflight_fd_op)(struct vhost_dev *dev,
>                                           struct vhost_inflight *inflight);
>   
>   typedef int (*vhost_dev_start_op)(struct vhost_dev *dev, bool started);
> +typedef int (*vhost_get_device_id_op)(struct vhost_dev *dev, uint32_t *dev_id);
>   typedef struct VhostOps {
>       VhostBackendType backend_type;
>       vhost_backend_init vhost_backend_init;
> @@ -154,9 +156,11 @@ typedef struct VhostOps {
>       vhost_get_inflight_fd_op vhost_get_inflight_fd;
>       vhost_set_inflight_fd_op vhost_set_inflight_fd;
>       vhost_dev_start_op vhost_dev_start;
> +    vhost_get_device_id_op vhost_get_device_id;
>   } VhostOps;


A separate patch for introducing this please.


>   
>   extern const VhostOps user_ops;
> +extern const VhostOps vdpa_ops;
>   
>   int vhost_set_backend_type(struct vhost_dev *dev,
>                              VhostBackendType backend_type);
> diff --git a/include/hw/virtio/vhost-vdpa.h b/include/hw/virtio/vhost-vdpa.h
> new file mode 100644
> index 0000000000..6455663388
> --- /dev/null
> +++ b/include/hw/virtio/vhost-vdpa.h
> @@ -0,0 +1,26 @@
> +/*
> + * vhost-vdpa.h
> + *
> + * Copyright(c) 2017-2018 Intel Corporation.
> + * Copyright(c) 2020 Red Hat, Inc.
> + *
> + * This work is licensed under the terms of the GNU GPL, version 2 or later.
> + * See the COPYING file in the top-level directory.
> + *
> + */
> +
> +#ifndef HW_VIRTIO_VHOST_VDPA_H
> +#define HW_VIRTIO_VHOST_VDPA_H
> +
> +#include "hw/virtio/virtio.h"
> +
> +typedef struct vhost_vdpa {
> +    int device_fd;
> +    uint32_t msg_type;
> +    MemoryListener listener;
> +} VhostVDPA;
> +
> +extern AddressSpace address_space_memory;
> +extern int vhost_vdpa_get_device_id(struct vhost_dev *dev,
> +                                   uint32_t *device_id);
> +#endif
> diff --git a/include/hw/virtio/vhost.h b/include/hw/virtio/vhost.h
> index 59ea53f8c2..f69b5e4a02 100644
> --- a/include/hw/virtio/vhost.h
> +++ b/include/hw/virtio/vhost.h
> @@ -92,6 +92,12 @@ struct vhost_dev {
>       const VhostDevConfigOps *config_ops;
>   };
>   
> +struct vhost_net {
> +    struct vhost_dev dev;
> +    struct vhost_virtqueue vqs[2];
> +    int backend;
> +    NetClientState *nc;
> +};


A separate patch for this exporting please.

Thanks


>   
>   int vhost_dev_init(struct vhost_dev *hdev, void *opaque,
>                      VhostBackendType backend_type,
> diff --git a/qemu-options.hx b/qemu-options.hx
> index 292d4e7c0c..d7d0daaa0e 100644
> --- a/qemu-options.hx
> +++ b/qemu-options.hx
> @@ -2409,6 +2409,10 @@ DEF("netdev", HAS_ARG, QEMU_OPTION_netdev,
>   #ifdef CONFIG_POSIX
>       "-netdev vhost-user,id=str,chardev=dev[,vhostforce=on|off]\n"
>       "                configure a vhost-user network, backed by a chardev 'dev'\n"
> +#endif
> +#ifdef __linux__
> +    "-netdev vhost-vdpa,id=str,vhostdev=/path/to/dev\n"
> +    "                configure a vhost-vdpa network,Establish a vhost-vdpa netdev\n"
>   #endif
>       "-netdev hubport,id=str,hubid=n[,netdev=nd]\n"
>       "                configure a hub port on the hub with ID 'n'\n", QEMU_ARCH_ALL)
> @@ -2888,6 +2892,14 @@ SRST
>                -netdev type=vhost-user,id=net0,chardev=chr0 \
>                -device virtio-net-pci,netdev=net0
>   
> +``-netdev vhost-vdpa,vhostdev=/path/to/dev``
> +    Establish a vhost-vdpa netdev.
> +
> +    vDPA device is a device that uses a datapath which complies with
> +    the virtio specifications with a vendor specific control path.
> +    vDPA devices can be both physically located on the hardware or
> +    emulated by software.
> +
>   ``-netdev hubport,id=id,hubid=hubid[,netdev=nd]``
>       Create a hub port on the emulated hub with ID hubid.
>   



^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v1 10/10] vhost-vdpa: introduce vhost-vdpa net client
  2020-06-22 15:37 ` [PATCH v1 10/10] vhost-vdpa: introduce vhost-vdpa net client Cindy Lu
  2020-06-23  7:12   ` Markus Armbruster
@ 2020-06-23  8:56   ` Jason Wang
  2020-06-23  9:57     ` Cindy Lu
  1 sibling, 1 reply; 46+ messages in thread
From: Jason Wang @ 2020-06-23  8:56 UTC (permalink / raw)
  To: Cindy Lu, mst, armbru, eblake, cohuck
  Cc: mhabets, qemu-devel, rob.miller, saugatm, maxime.coquelin, hch,
	eperezma, jgg, shahafs, kevin.tian, parav, vmireyno,
	cunming.liang, gdawar, jiri, xiao.w.wang, stefanha, zhihong.wang,
	Tiwei Bie, aadam, rdunlap, hanand, lingshan.zhu


On 2020/6/22 下午11:37, Cindy Lu wrote:
> This patch set introduces a new net client type: vhost-vdpa.
> vhost-vdpa net client will set up a vDPA device which is specified
> by a "vhostdev" parameter.
>
> Signed-off-by: Lingshan Zhu <lingshan.zhu@intel.com>
> Signed-off-by: Tiwei Bie <tiwei.bie@intel.com>
> Signed-off-by: Cindy Lu <lulu@redhat.com>
> ---
>   include/net/vhost-vdpa.h |  21 ++++
>   include/net/vhost_net.h  |   1 -
>   net/Makefile.objs        |   2 +-
>   net/clients.h            |   2 +
>   net/net.c                |   3 +
>   net/vhost-vdpa.c         | 230 +++++++++++++++++++++++++++++++++++++++
>   qapi/net.json            |  23 +++-
>   7 files changed, 278 insertions(+), 4 deletions(-)
>   create mode 100644 include/net/vhost-vdpa.h
>   create mode 100644 net/vhost-vdpa.c
>
> diff --git a/include/net/vhost-vdpa.h b/include/net/vhost-vdpa.h
> new file mode 100644
> index 0000000000..725c8b1c81
> --- /dev/null
> +++ b/include/net/vhost-vdpa.h
> @@ -0,0 +1,21 @@
> +/*
> + * vhost-vdpa.h
> + *
> + * Copyright(c) 2017-2018 Intel Corporation.
> + * Copyright(c) 2020 Red Hat, Inc.
> + *
> + * This work is licensed under the terms of the GNU GPL, version 2 or later.
> + * See the COPYING file in the top-level directory.
> + *
> + */
> +
> +#ifndef VHOST_VDPA_H
> +#define VHOST_VDPA_H
> +
> +struct vhost_net;
> +struct vhost_net *vhost_vdpa_get_vhost_net(NetClientState *nc);
> +uint64_t vhost_vdpa_get_acked_features(NetClientState *nc);
> +
> +extern const int vdpa_feature_bits[];
> +
> +#endif /* VHOST_VDPA_H */
> diff --git a/include/net/vhost_net.h b/include/net/vhost_net.h
> index abfb0e8e68..4843cdb36f 100644
> --- a/include/net/vhost_net.h
> +++ b/include/net/vhost_net.h
> @@ -44,5 +44,4 @@ int vhost_set_vring_enable(NetClientState * nc, int enable);
>   uint64_t vhost_net_get_acked_features(VHostNetState *net);
>   
>   int vhost_net_set_mtu(struct vhost_net *net, uint16_t mtu);
> -


Let's keep this newline.


>   #endif
> diff --git a/net/Makefile.objs b/net/Makefile.objs
> index c5d076d19c..5ab45545db 100644
> --- a/net/Makefile.objs
> +++ b/net/Makefile.objs
> @@ -26,7 +26,7 @@ tap-obj-$(CONFIG_SOLARIS) = tap-solaris.o
>   tap-obj-y ?= tap-stub.o
>   common-obj-$(CONFIG_POSIX) += tap.o $(tap-obj-y)
>   common-obj-$(CONFIG_WIN32) += tap-win32.o
> -


And this.


> +common-obj-$(CONFIG_VHOST_NET_VDPA) += vhost-vdpa.o
>   vde.o-libs = $(VDE_LIBS)
>   
>   common-obj-$(CONFIG_CAN_BUS) += can/
> diff --git a/net/clients.h b/net/clients.h
> index a6ef267e19..92f9b59aed 100644
> --- a/net/clients.h
> +++ b/net/clients.h
> @@ -61,4 +61,6 @@ int net_init_netmap(const Netdev *netdev, const char *name,
>   int net_init_vhost_user(const Netdev *netdev, const char *name,
>                           NetClientState *peer, Error **errp);
>   
> +int net_init_vhost_vdpa(const Netdev *netdev, const char *name,
> +                        NetClientState *peer, Error **errp);
>   #endif /* QEMU_NET_CLIENTS_H */
> diff --git a/net/net.c b/net/net.c
> index 599fb61028..82624ea9ac 100644
> --- a/net/net.c
> +++ b/net/net.c
> @@ -965,6 +965,9 @@ static int (* const net_client_init_fun[NET_CLIENT_DRIVER__MAX])(
>   #ifdef CONFIG_VHOST_NET_USER
>           [NET_CLIENT_DRIVER_VHOST_USER] = net_init_vhost_user,
>   #endif
> +#ifdef CONFIG_VHOST_NET_VDPA
> +        [NET_CLIENT_DRIVER_VHOST_VDPA] = net_init_vhost_vdpa,
> +#endif
>   #ifdef CONFIG_L2TPV3
>           [NET_CLIENT_DRIVER_L2TPV3]    = net_init_l2tpv3,
>   #endif
> diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c
> new file mode 100644
> index 0000000000..34858a6ea3
> --- /dev/null
> +++ b/net/vhost-vdpa.c
> @@ -0,0 +1,230 @@
> +/*
> + * vhost-vdpa.c
> + *
> + * Copyright(c) 2017-2018 Intel Corporation.
> + * Copyright(c) 2020 Red Hat, Inc.
> + *
> + * This work is licensed under the terms of the GNU GPL, version 2 or later.
> + * See the COPYING file in the top-level directory.
> + *
> + */
> +
> +#include "qemu/osdep.h"
> +#include "clients.h"
> +#include "net/vhost_net.h"
> +#include "net/vhost-vdpa.h"
> +#include "hw/virtio/vhost-vdpa.h"
> +#include "qemu/config-file.h"
> +#include "qemu/error-report.h"
> +#include "qemu/option.h"
> +#include "qapi/error.h"
> +#include <sys/ioctl.h>
> +#include <err.h>
> +#include "standard-headers/linux/virtio_net.h"
> +#include "monitor/monitor.h"
> +#include "hw/virtio/vhost.h"
> +
> +/* Todo:need to add the multiqueue support here */
> +typedef struct VhostVDPAState {
> +    NetClientState nc;
> +    struct vhost_vdpa vhost_vdpa;
> +    VHostNetState *vhost_net;
> +    uint64_t acked_features;
> +    bool started;
> +} VhostVDPAState;
> +
> +const int vdpa_feature_bits[] = {
> +    VIRTIO_F_NOTIFY_ON_EMPTY,
> +    VIRTIO_RING_F_INDIRECT_DESC,
> +    VIRTIO_RING_F_EVENT_IDX,
> +    VIRTIO_F_ANY_LAYOUT,
> +    VIRTIO_F_VERSION_1,
> +    VIRTIO_NET_F_CSUM,
> +    VIRTIO_NET_F_GUEST_CSUM,
> +    VIRTIO_NET_F_GSO,
> +    VIRTIO_NET_F_GUEST_TSO4,
> +    VIRTIO_NET_F_GUEST_TSO6,
> +    VIRTIO_NET_F_GUEST_ECN,
> +    VIRTIO_NET_F_GUEST_UFO,
> +    VIRTIO_NET_F_HOST_TSO4,
> +    VIRTIO_NET_F_HOST_TSO6,
> +    VIRTIO_NET_F_HOST_ECN,
> +    VIRTIO_NET_F_HOST_UFO,
> +    VIRTIO_NET_F_MRG_RXBUF,
> +    VIRTIO_NET_F_MTU,
> +    VIRTIO_F_IOMMU_PLATFORM,
> +    VIRTIO_F_RING_PACKED,
> +    VIRTIO_NET_F_GUEST_ANNOUNCE,
> +    VHOST_INVALID_FEATURE_BIT
> +};
> +
> +VHostNetState *vhost_vdpa_get_vhost_net(NetClientState *nc)
> +{
> +    VhostVDPAState *s = DO_UPCAST(VhostVDPAState, nc, nc);
> +    assert(nc->info->type == NET_CLIENT_DRIVER_VHOST_VDPA);
> +    return s->vhost_net;
> +}
> +
> +uint64_t vhost_vdpa_get_acked_features(NetClientState *nc)
> +{
> +    VhostVDPAState *s = DO_UPCAST(VhostVDPAState, nc, nc);
> +    assert(nc->info->type == NET_CLIENT_DRIVER_VHOST_VDPA);
> +    s->acked_features = vhost_net_get_acked_features(s->vhost_net);
> +
> +    return s->acked_features;
> +}
> +
> +static int vhost_vdpa_net_check_device_id(NetClientState *nc)
> +{
> +    uint32_t device_id;
> +    int ret;
> +    struct vhost_net *net;
> +    struct vhost_dev *hdev;
> +    assert(nc->info->type == NET_CLIENT_DRIVER_VHOST_VDPA);
> +    VhostVDPAState *s = DO_UPCAST(VhostVDPAState, nc, nc);


Let's try to avoid those unnecessary conversion and check since the 
caller knows e.g VhostVDPAState.


> +    net = s->vhost_net;
> +    hdev = (struct vhost_dev *)&net->dev;
> +    ret = hdev->vhost_ops->vhost_get_device_id(hdev, &device_id);
> +    if (device_id != VIRTIO_ID_NET) {
> +        return -ENOTSUP;
> +    }
> +    return ret;
> +}
> +
> +static void vhost_vdpa_del(NetClientState *ncs)
> +{
> +    VhostVDPAState *s;
> +    assert(ncs->info->type == NET_CLIENT_DRIVER_VHOST_VDPA);
> +    s = DO_UPCAST(VhostVDPAState, nc, ncs);
> +    if (s->vhost_net) {
> +        vhost_net_cleanup(s->vhost_net);
> +    }
> +}
> +
> +static int vhost_vdpa_add(NetClientState *ncs, void *be)
> +{
> +    VhostNetOptions options;
> +    struct vhost_net *net = NULL;
> +    VhostVDPAState *s;
> +    int ret;
> +
> +    options.backend_type = VHOST_BACKEND_TYPE_VDPA;
> +    assert(ncs->info->type == NET_CLIENT_DRIVER_VHOST_VDPA);
> +    s = DO_UPCAST(VhostVDPAState, nc, ncs);
> +    options.net_backend = ncs;
> +    options.opaque      = be;
> +    options.busyloop_timeout = 0;
> +    net = vhost_net_init(&options);
> +    if (!net) {
> +        error_report("failed to init vhost_net for queue");
> +        goto err;
> +    }
> +    if (s->vhost_net) {
> +        vhost_net_cleanup(s->vhost_net);
> +        g_free(s->vhost_net);
> +    }
> +    s->vhost_net = net;
> +    ret = vhost_vdpa_net_check_device_id(ncs);


Eli pointed out it's better to validate device Id before vhost_net_init().

Otherwise driver may see e.g DRIVER before getting device id.


> +    if (ret) {
> +        goto err;
> +    }
> +    return 0;
> +err:
> +    if (net) {
> +        vhost_net_cleanup(net);
> +    }
> +    vhost_vdpa_del(ncs);
> +    return -1;
> +}
> +
> +static void vhost_vdpa_cleanup(NetClientState *nc)
> +{
> +    VhostVDPAState *s = DO_UPCAST(VhostVDPAState, nc, nc);
> +
> +    if (s->vhost_net) {
> +        vhost_net_cleanup(s->vhost_net);
> +        g_free(s->vhost_net);
> +        s->vhost_net = NULL;
> +    }
> +}
> +
> +static bool vhost_vdpa_has_vnet_hdr(NetClientState *nc)
> +{
> +    assert(nc->info->type == NET_CLIENT_DRIVER_VHOST_VDPA);
> +
> +    return true;
> +}
> +
> +static bool vhost_vdpa_has_ufo(NetClientState *nc)
> +{
> +    assert(nc->info->type == NET_CLIENT_DRIVER_VHOST_VDPA);
> +    VhostVDPAState *s = DO_UPCAST(VhostVDPAState, nc, nc);
> +    uint64_t  features = 0;


Unnecessary spaces between uint64_t and features.


> +    features |= (1ULL << VIRTIO_NET_F_HOST_UFO);
> +    features = vhost_net_get_features(s->vhost_net, features);
> +    return !!(features & (1ULL << VIRTIO_NET_F_HOST_UFO));
> +
> +}
> +
> +static NetClientInfo net_vhost_vdpa_info = {
> +        .type = NET_CLIENT_DRIVER_VHOST_VDPA,
> +        .size = sizeof(VhostVDPAState),
> +        .cleanup = vhost_vdpa_cleanup,
> +        .has_vnet_hdr = vhost_vdpa_has_vnet_hdr,
> +        .has_ufo = vhost_vdpa_has_ufo,
> +};
> +
> +static int net_vhost_vdpa_init(NetClientState *peer, const char *device,
> +                               const char *name, const char *vhostdev)
> +{
> +    NetClientState *nc = NULL;
> +    VhostVDPAState *s;
> +    int vdpa_device_fd = -1;
> +    int ret = 0;
> +    assert(name);
> +    nc = qemu_new_net_client(&net_vhost_vdpa_info, peer, device, name);
> +    snprintf(nc->info_str, sizeof(nc->info_str), "vhost-vdpa");


Do we need an identifier for this vhost-vdpa?

Thanks


> +    nc->queue_index = 0;
> +    s = DO_UPCAST(VhostVDPAState, nc, nc);
> +    vdpa_device_fd = qemu_open(vhostdev, O_RDWR);
> +    if (vdpa_device_fd == -1) {
> +        return -errno;
> +    }
> +    s->vhost_vdpa.device_fd = vdpa_device_fd;
> +    ret = vhost_vdpa_add(nc, (void *)&s->vhost_vdpa);
> +    assert(s->vhost_net);
> +    return ret;
> +}
> +
> +static int net_vhost_check_net(void *opaque, QemuOpts *opts, Error **errp)
> +{
> +    const char *name = opaque;
> +    const char *driver, *netdev;
> +
> +    driver = qemu_opt_get(opts, "driver");
> +    netdev = qemu_opt_get(opts, "netdev");
> +    if (!driver || !netdev) {
> +        return 0;
> +    }
> +    if (strcmp(netdev, name) == 0 &&
> +        !g_str_has_prefix(driver, "virtio-net-")) {
> +        error_setg(errp, "vhost-vdpa requires frontend driver virtio-net-*");
> +        return -1;
> +    }
> +    return 0;
> +}
> +
> +int net_init_vhost_vdpa(const Netdev *netdev, const char *name,
> +                        NetClientState *peer, Error **errp)
> +{
> +    const NetdevVhostVDPAOptions *opts;
> +
> +    assert(netdev->type == NET_CLIENT_DRIVER_VHOST_VDPA);
> +    opts = &netdev->u.vhost_vdpa;
> +    /* verify net frontend */
> +    if (qemu_opts_foreach(qemu_find_opts("device"), net_vhost_check_net,
> +                          (char *)name, errp)) {
> +        return -1;
> +    }
> +    return net_vhost_vdpa_init(peer, "vhost_vdpa", name, opts->vhostdev);
> +}
> diff --git a/qapi/net.json b/qapi/net.json
> index cebb1b52e3..03aad67693 100644
> --- a/qapi/net.json
> +++ b/qapi/net.json
> @@ -428,6 +428,24 @@
>       '*vhostforce':    'bool',
>       '*queues':        'int' } }
>   
> +##
> +# @NetdevVhostVDPAOptions:
> +#
> +# Vhost-vdpa network backend
> +#
> +# @vhostdev: name of a vdpa dev path in sysfs
> +#            (default path:/dev/vhost-vdpa-$ID)
> +#
> +# @queues: number of queues to be created for multiqueue vhost-vdpa
> +#          (default: 1)
> +#
> +# Since: 5.1
> +##
> +{ 'struct': 'NetdevVhostVDPAOptions',
> +  'data': {
> +    '*vhostdev':     'str',
> +    '*queues':       'int' } }
> +
>   ##
>   # @NetClientDriver:
>   #
> @@ -437,7 +455,7 @@
>   ##
>   { 'enum': 'NetClientDriver',
>     'data': [ 'none', 'nic', 'user', 'tap', 'l2tpv3', 'socket', 'vde',
> -            'bridge', 'hubport', 'netmap', 'vhost-user' ] }
> +            'bridge', 'hubport', 'netmap', 'vhost-user', 'vhost-vdpa' ] }
>   
>   ##
>   # @Netdev:
> @@ -465,7 +483,8 @@
>       'bridge':   'NetdevBridgeOptions',
>       'hubport':  'NetdevHubPortOptions',
>       'netmap':   'NetdevNetmapOptions',
> -    'vhost-user': 'NetdevVhostUserOptions' } }
> +    'vhost-user': 'NetdevVhostUserOptions',
> +    'vhost-vdpa': 'NetdevVhostVDPAOptions' } }
>   
>   ##
>   # @NetLegacy:



^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v1 00/10] vDPA support in qemu
  2020-06-23  7:07 ` [PATCH v1 00/10] vDPA support in qemu Markus Armbruster
@ 2020-06-23  9:16   ` Cindy Lu
  2020-06-23  9:43     ` Jason Wang
  0 siblings, 1 reply; 46+ messages in thread
From: Cindy Lu @ 2020-06-23  9:16 UTC (permalink / raw)
  To: Markus Armbruster
  Cc: rdunlap, Michael Tsirkin, Jason Wang, qemu-devel, Rob Miller,
	saugatm, Maxime Coquelin, hch, Eugenio Perez Martin, jgg,
	mhabets, Shahaf Shuler, kevin.tian, parav, Vitaly Mireyno, Liang,
	Cunming, gdawar, jiri, xiao.w.wang, Stefan Hajnoczi, Wang,
	Zhihong, Ariel Adam, Cornelia Huck, hanand, Zhu, Lingshan

On Tue, Jun 23, 2020 at 3:07 PM Markus Armbruster <armbru@redhat.com> wrote:
>
> Cindy Lu <lulu@redhat.com> writes:
>
> > vDPA device is a device that uses a datapath which complies with the
> > virtio specifications with vendor specific control path. vDPA devices
> > can be both physically located on the hardware or emulated by software.
> > This RFC introduce the vDPA support in qemu
> > TODO
> > 1) vIOMMU support
> > 2) live migration support
>
> This gives me the foggiest of ideas on what vDPA is.  Could we use
> docs/interop/vhost-vdpa.rst?
>
Sure will add this



^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v1 01/10] net: introduce qemu_get_peer
  2020-06-23  7:10   ` Jason Wang
@ 2020-06-23  9:17     ` Cindy Lu
  0 siblings, 0 replies; 46+ messages in thread
From: Cindy Lu @ 2020-06-23  9:17 UTC (permalink / raw)
  To: Jason Wang
  Cc: Cornelia Huck, Michael Tsirkin, mhabets, qemu-devel, hanand,
	Rob Miller, saugatm, Markus Armbruster, hch,
	Eugenio Perez Martin, jgg, Shahaf Shuler, kevin.tian, parav,
	Vitaly Mireyno, Liang, Cunming, gdawar, jiri, xiao.w.wang,
	Stefan Hajnoczi, Wang, Zhihong, Ariel Adam, rdunlap,
	Maxime Coquelin, Zhu, Lingshan

On Tue, Jun 23, 2020 at 3:10 PM Jason Wang <jasowang@redhat.com> wrote:
>
>
> On 2020/6/22 下午11:37, Cindy Lu wrote:
> > This is a small function that can get the peer
> > from given NetClientState and queue_index
> >
> > Signed-off-by: Cindy Lu <lulu@redhat.com>
> > ---
> >   include/net/net.h | 1 +
> >   net/net.c         | 6 ++++++
> >   2 files changed, 7 insertions(+)
> >
> > diff --git a/include/net/net.h b/include/net/net.h
> > index 39085d9444..e7ef42d62b 100644
> > --- a/include/net/net.h
> > +++ b/include/net/net.h
> > @@ -176,6 +176,7 @@ void hmp_info_network(Monitor *mon, const QDict *qdict);
> >   void net_socket_rs_init(SocketReadState *rs,
> >                           SocketReadStateFinalize *finalize,
> >                           bool vnet_hdr);
> > +NetClientState *qemu_get_peer(NetClientState *nc, int queue_index);
> >
> >   /* NIC info */
> >
> > diff --git a/net/net.c b/net/net.c
> > index 38778e831d..599fb61028 100644
> > --- a/net/net.c
> > +++ b/net/net.c
> > @@ -324,6 +324,12 @@ void *qemu_get_nic_opaque(NetClientState *nc)
> >
> >       return nic->opaque;
> >   }
>
>
> newline please.
>
> Thanks
>
will add  this
>
> > +NetClientState *qemu_get_peer(NetClientState *nc, int queue_index)
> > +{
> > +    assert(nc != NULL);
> > +    NetClientState *ncs = nc + queue_index;
> > +    return ncs->peer;
> > +}
> >
> >   static void qemu_cleanup_net_client(NetClientState *nc)
> >   {
>



^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v1 04/10] virtio-pci: implement queue_enabled method
  2020-06-23  7:13   ` Jason Wang
@ 2020-06-23  9:18     ` Cindy Lu
  0 siblings, 0 replies; 46+ messages in thread
From: Cindy Lu @ 2020-06-23  9:18 UTC (permalink / raw)
  To: Jason Wang
  Cc: Cornelia Huck, Michael Tsirkin, mhabets, qemu-devel, hanand,
	Rob Miller, saugatm, Markus Armbruster, hch,
	Eugenio Perez Martin, jgg, Shahaf Shuler, kevin.tian, parav,
	Vitaly Mireyno, Liang, Cunming, gdawar, jiri, xiao.w.wang,
	Stefan Hajnoczi, Wang, Zhihong, Ariel Adam, rdunlap,
	Maxime Coquelin, Zhu, Lingshan

On Tue, Jun 23, 2020 at 3:13 PM Jason Wang <jasowang@redhat.com> wrote:
>
>
> On 2020/6/22 下午11:37, Cindy Lu wrote:
> > From: Jason Wang <jasowang@redhat.com>
> >
> > With version 1, we can detect whether a queue is enabled via
> > queue_enabled.
> >
> > Signed-off-by: Jason Wang <jasowang@redhat.com>
> > Signed-off-by: Cindy Lu <lulu@redhat.com>
> > ---
> >   hw/virtio/virtio-pci.c | 18 ++++++++++++++++++
> >   1 file changed, 18 insertions(+)
> >
> > diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
> > index 4cb784389c..3918aa9f6c 100644
> > --- a/hw/virtio/virtio-pci.c
> > +++ b/hw/virtio/virtio-pci.c
> > @@ -1107,6 +1107,23 @@ static AddressSpace *virtio_pci_get_dma_as(DeviceState *d)
> >       return pci_get_address_space(dev);
> >   }
> >
> > +static bool  virtio_queue_check_enabled(VirtIODevice *vdev, int n)
>
>
> One space is sufficient between bool and virtio_queue_check_enabled.
>
>
> > +{
> > +    return  virtio_queue_get_desc_addr(vdev, n) != 0;
> > +}
> > +
> > +static bool virtio_pci_queue_enabled(DeviceState *d, int n)
> > +{
> > +    VirtIOPCIProxy *proxy = VIRTIO_PCI(d);
> > +    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
> > +
> > +    if (virtio_vdev_has_feature(vdev, VIRTIO_F_VERSION_1)) {
> > +        return proxy->vqs[vdev->queue_sel].enabled;
> > +    }
> > +
> > +    return  virtio_queue_check_enabled(vdev, n);
>
>
> Similar issue here.
>
> Thanks
>
Thanks, I will correct this
>
> > +}
> > +
> >   static int virtio_pci_add_mem_cap(VirtIOPCIProxy *proxy,
> >                                      struct virtio_pci_cap *cap)
> >   {
> > @@ -2059,6 +2076,7 @@ static void virtio_pci_bus_class_init(ObjectClass *klass, void *data)
> >       k->ioeventfd_enabled = virtio_pci_ioeventfd_enabled;
> >       k->ioeventfd_assign = virtio_pci_ioeventfd_assign;
> >       k->get_dma_as = virtio_pci_get_dma_as;
> > +    k->queue_enabled = virtio_pci_queue_enabled;
> >   }
> >
> >   static const TypeInfo virtio_pci_bus_info = {
>



^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v1 10/10] vhost-vdpa: introduce vhost-vdpa net client
  2020-06-23  7:12   ` Markus Armbruster
@ 2020-06-23  9:19     ` Cindy Lu
  0 siblings, 0 replies; 46+ messages in thread
From: Cindy Lu @ 2020-06-23  9:19 UTC (permalink / raw)
  To: Markus Armbruster
  Cc: rdunlap, Michael Tsirkin, Jason Wang, qemu-devel, Rob Miller,
	saugatm, Maxime Coquelin, hch, Eugenio Perez Martin, jgg,
	mhabets, Shahaf Shuler, kevin.tian, parav, Vitaly Mireyno, Liang,
	Cunming, gdawar, jiri, xiao.w.wang, Stefan Hajnoczi, Wang,
	Zhihong, Tiwei Bie, Ariel Adam, Cornelia Huck, hanand, Zhu,
	Lingshan

On Tue, Jun 23, 2020 at 3:13 PM Markus Armbruster <armbru@redhat.com> wrote:
>
> QAPI schema review only.
>
> Cindy Lu <lulu@redhat.com> writes:
>
> > This patch set introduces a new net client type: vhost-vdpa.
> > vhost-vdpa net client will set up a vDPA device which is specified
> > by a "vhostdev" parameter.
> >
> > Signed-off-by: Lingshan Zhu <lingshan.zhu@intel.com>
> > Signed-off-by: Tiwei Bie <tiwei.bie@intel.com>
> > Signed-off-by: Cindy Lu <lulu@redhat.com>
> [...]
> > diff --git a/qapi/net.json b/qapi/net.json
> > index cebb1b52e3..03aad67693 100644
> > --- a/qapi/net.json
> > +++ b/qapi/net.json
> > @@ -428,6 +428,24 @@
> >      '*vhostforce':    'bool',
> >      '*queues':        'int' } }
> >
> > +##
> > +# @NetdevVhostVDPAOptions:
> > +#
> > +# Vhost-vdpa network backend
>
> Considering this ends up in QMP reference documentation, could you add a
> hint on what "Vhost-vdpa" is?
>
> > +#
> > +# @vhostdev: name of a vdpa dev path in sysfs
>
> How is this thing to be spelled in text, vdpa, VDPA or vDPA?
>
> Avoid unnecessary abbreviations in doc text, please: write "device
> path", not "dev path".
>
> > +#            (default path:/dev/vhost-vdpa-$ID)
>
> What's $ID?
>
Thanks, I will rewrite this part and make it clear
> > +#
> > +# @queues: number of queues to be created for multiqueue vhost-vdpa
> > +#          (default: 1)
> > +#
> > +# Since: 5.1
> > +##
> > +{ 'struct': 'NetdevVhostVDPAOptions',
> > +  'data': {
> > +    '*vhostdev':     'str',
> > +    '*queues':       'int' } }
> > +
> >  ##
> >  # @NetClientDriver:
> >  #
> > @@ -437,7 +455,7 @@
> >  ##
> >  { 'enum': 'NetClientDriver',
> >    'data': [ 'none', 'nic', 'user', 'tap', 'l2tpv3', 'socket', 'vde',
> > -            'bridge', 'hubport', 'netmap', 'vhost-user' ] }
> > +            'bridge', 'hubport', 'netmap', 'vhost-user', 'vhost-vdpa' ] }
> >
> >  ##
> >  # @Netdev:
> > @@ -465,7 +483,8 @@
> >      'bridge':   'NetdevBridgeOptions',
> >      'hubport':  'NetdevHubPortOptions',
> >      'netmap':   'NetdevNetmapOptions',
> > -    'vhost-user': 'NetdevVhostUserOptions' } }
> > +    'vhost-user': 'NetdevVhostUserOptions',
> > +    'vhost-vdpa': 'NetdevVhostVDPAOptions' } }
> >
> >  ##
> >  # @NetLegacy:
>



^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v1 06/10] vhsot_net: introduce set_config & get_config function
  2020-06-23  7:18   ` Jason Wang
@ 2020-06-23  9:22     ` Cindy Lu
  0 siblings, 0 replies; 46+ messages in thread
From: Cindy Lu @ 2020-06-23  9:22 UTC (permalink / raw)
  To: Jason Wang
  Cc: Cornelia Huck, Michael Tsirkin, mhabets, qemu-devel, hanand,
	Rob Miller, saugatm, Markus Armbruster, hch,
	Eugenio Perez Martin, jgg, Shahaf Shuler, kevin.tian, parav,
	Vitaly Mireyno, Liang, Cunming, gdawar, jiri, xiao.w.wang,
	Stefan Hajnoczi, Wang, Zhihong, Ariel Adam, rdunlap,
	Maxime Coquelin, Zhu, Lingshan

On Tue, Jun 23, 2020 at 3:18 PM Jason Wang <jasowang@redhat.com> wrote:
>
>
> On 2020/6/22 下午11:37, Cindy Lu wrote:
> > This patch introduces set_config & get_config  method which allows
>
>
> One space is sufficient between get_config and method.
>
>
> > vhost_net set/get the config to backend
>
>
> Typo in the subject.
>
>
thanks jason, I will correct this
> >
> > Signed-off-by: Cindy Lu <lulu@redhat.com>
> > ---
> >   hw/net/vhost_net.c      | 11 +++++++++++
> >   include/net/vhost_net.h |  5 +++++
> >   2 files changed, 16 insertions(+)
> >
> > diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c
> > index 4096d64aaf..04cc3db264 100644
> > --- a/hw/net/vhost_net.c
> > +++ b/hw/net/vhost_net.c
>
> Is there any reason that making this net specific? I guess it could be
> used by other vhost devices as well.
>
> Thanks
>
Thanks jason I will correct this
>
> > @@ -111,6 +111,17 @@ uint64_t vhost_net_get_features(struct vhost_net *net, uint64_t features)
> >               features);
> >   }
> >
> > +int vhost_net_get_config(struct vhost_net *net,  uint8_t *config,
> > +                         uint32_t config_len)
> > +{
> > +    return vhost_dev_get_config(&net->dev, config, config_len);
> > +}
> > +int vhost_net_set_config(struct vhost_net *net, const uint8_t *data,
> > +                         uint32_t offset, uint32_t size, uint32_t flags)
> > +{
> > +    return vhost_dev_set_config(&net->dev, data, offset, size, flags);
> > +}
> > +
> >   void vhost_net_ack_features(struct vhost_net *net, uint64_t features)
> >   {
> >       net->dev.acked_features = net->dev.backend_features;
> > diff --git a/include/net/vhost_net.h b/include/net/vhost_net.h
> > index 77e47398c4..abfb0e8e68 100644
> > --- a/include/net/vhost_net.h
> > +++ b/include/net/vhost_net.h
> > @@ -27,6 +27,11 @@ void vhost_net_cleanup(VHostNetState *net);
> >
> >   uint64_t vhost_net_get_features(VHostNetState *net, uint64_t features);
> >   void vhost_net_ack_features(VHostNetState *net, uint64_t features);
> > +int vhost_net_get_config(struct vhost_net *net,  uint8_t *config,
> > +                         uint32_t config_len);
> > +
> > +int vhost_net_set_config(struct vhost_net *net, const uint8_t *data,
> > +                         uint32_t offset, uint32_t size, uint32_t flags);
> >
> >   bool vhost_net_virtqueue_pending(VHostNetState *net, int n);
> >   void vhost_net_virtqueue_mask(VHostNetState *net, VirtIODevice *dev,
>



^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v1 08/10] vhost: implement vhost_dev_start method
  2020-06-23  7:21   ` Jason Wang
@ 2020-06-23  9:34     ` Cindy Lu
  2020-06-23  9:37       ` Jason Wang
  0 siblings, 1 reply; 46+ messages in thread
From: Cindy Lu @ 2020-06-23  9:34 UTC (permalink / raw)
  To: Jason Wang
  Cc: Cornelia Huck, Michael Tsirkin, mhabets, qemu-devel, hanand,
	Rob Miller, saugatm, Markus Armbruster, hch,
	Eugenio Perez Martin, jgg, Shahaf Shuler, kevin.tian, parav,
	Vitaly Mireyno, Liang, Cunming, gdawar, jiri, xiao.w.wang,
	Stefan Hajnoczi, Wang, Zhihong, Ariel Adam, rdunlap,
	Maxime Coquelin, Zhu, Lingshan

On Tue, Jun 23, 2020 at 3:21 PM Jason Wang <jasowang@redhat.com> wrote:
>
>
> On 2020/6/22 下午11:37, Cindy Lu wrote:
> > use the vhost_dev_start callback to send the status to backend
>
>
> I suggest to squash this into previous patch.
>
Sure will do
>
> >
> > Signed-off-by: Cindy Lu <lulu@redhat.com>
> > ---
> >   hw/virtio/vhost.c         | 17 +++++++++++++++++
> >   include/hw/virtio/vhost.h |  2 ++
> >   2 files changed, 19 insertions(+)
> >
> > diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
> > index 01ebe12f28..bfd7f9ce1f 100644
> > --- a/hw/virtio/vhost.c
> > +++ b/hw/virtio/vhost.c
> > @@ -744,6 +744,7 @@ static void vhost_iommu_region_del(MemoryListener *listener,
> >       }
> >   }
> >
> > +
> >   static int vhost_virtqueue_set_addr(struct vhost_dev *dev,
> >                                       struct vhost_virtqueue *vq,
> >                                       unsigned idx, bool enable_log)
> > @@ -1661,6 +1662,11 @@ int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev)
> >           }
> >       }
> >
> > +    r = vhost_set_start(hdev, true);
>
>
> I think we need a better name for this function.
>
Shall we change it to vhost_set_device_start ? Since the
vhost_dev_start was occupied by other function
>
> > +    if (r) {
> > +        goto fail_log;
> > +    }
> > +
> >       if (vhost_dev_has_iommu(hdev)) {
> >           hdev->vhost_ops->vhost_set_iotlb_callback(hdev, true);
> >
> > @@ -1697,6 +1703,8 @@ void vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev)
> >       /* should only be called after backend is connected */
> >       assert(hdev->vhost_ops);
> >
> > +    vhost_set_start(hdev, false);
> > +
> >       for (i = 0; i < hdev->nvqs; ++i) {
> >           vhost_virtqueue_stop(hdev,
> >                                vdev,
> > @@ -1722,3 +1730,12 @@ int vhost_net_set_backend(struct vhost_dev *hdev,
> >
> >       return -1;
> >   }
> > +
> > +int vhost_set_start(struct vhost_dev *hdev, bool started)
> > +{
> > +
> > +    if (hdev->vhost_ops->vhost_dev_start) {
> > +        hdev->vhost_ops->vhost_dev_start(hdev, started);
> > +    }
> > +    return 0;
> > +}
> > diff --git a/include/hw/virtio/vhost.h b/include/hw/virtio/vhost.h
> > index 085450c6f8..59ea53f8c2 100644
> > --- a/include/hw/virtio/vhost.h
> > +++ b/include/hw/virtio/vhost.h
> > @@ -92,6 +92,7 @@ struct vhost_dev {
> >       const VhostDevConfigOps *config_ops;
> >   };
> >
> > +
> >   int vhost_dev_init(struct vhost_dev *hdev, void *opaque,
> >                      VhostBackendType backend_type,
> >                      uint32_t busyloop_timeout);
> > @@ -137,4 +138,5 @@ int vhost_dev_set_inflight(struct vhost_dev *dev,
> >                              struct vhost_inflight *inflight);
> >   int vhost_dev_get_inflight(struct vhost_dev *dev, uint16_t queue_size,
> >                              struct vhost_inflight *inflight);
> > +int vhost_set_start(struct vhost_dev *dev, bool started);
>
>
> Any reason for exporting this? It looks to me there's no real user out
> this file.
>
> Thanks
>
Sure will fix this
>
> >   #endif
>



^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v1 08/10] vhost: implement vhost_dev_start method
  2020-06-23  9:34     ` Cindy Lu
@ 2020-06-23  9:37       ` Jason Wang
  2020-06-23  9:39         ` Cindy Lu
  0 siblings, 1 reply; 46+ messages in thread
From: Jason Wang @ 2020-06-23  9:37 UTC (permalink / raw)
  To: Cindy Lu
  Cc: Cornelia Huck, Michael Tsirkin, mhabets, qemu-devel, hanand,
	Rob Miller, saugatm, Markus Armbruster, hch,
	Eugenio Perez Martin, jgg, Shahaf Shuler, kevin.tian, parav,
	Vitaly Mireyno, Liang, Cunming, gdawar, jiri, xiao.w.wang,
	Stefan Hajnoczi, Wang, Zhihong, Ariel Adam, rdunlap,
	Maxime Coquelin, Zhu, Lingshan


On 2020/6/23 下午5:34, Cindy Lu wrote:
> On Tue, Jun 23, 2020 at 3:21 PM Jason Wang<jasowang@redhat.com>  wrote:
>> On 2020/6/22 下午11:37, Cindy Lu wrote:
>>> use the vhost_dev_start callback to send the status to backend
>> I suggest to squash this into previous patch.
>>
> Sure will do
>>> Signed-off-by: Cindy Lu<lulu@redhat.com>
>>> ---
>>>    hw/virtio/vhost.c         | 17 +++++++++++++++++
>>>    include/hw/virtio/vhost.h |  2 ++
>>>    2 files changed, 19 insertions(+)
>>>
>>> diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
>>> index 01ebe12f28..bfd7f9ce1f 100644
>>> --- a/hw/virtio/vhost.c
>>> +++ b/hw/virtio/vhost.c
>>> @@ -744,6 +744,7 @@ static void vhost_iommu_region_del(MemoryListener *listener,
>>>        }
>>>    }
>>>
>>> +
>>>    static int vhost_virtqueue_set_addr(struct vhost_dev *dev,
>>>                                        struct vhost_virtqueue *vq,
>>>                                        unsigned idx, bool enable_log)
>>> @@ -1661,6 +1662,11 @@ int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev)
>>>            }
>>>        }
>>>
>>> +    r = vhost_set_start(hdev, true);
>> I think we need a better name for this function.
>>
> Shall we change it to vhost_set_device_start ? Since the
> vhost_dev_start was occupied by other function


Or maybe just open code the vhost_set_start here since there's no other 
users.

Thanks




^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v1 09/10] vhost-vdpa: introduce vhost-vdpa backend
  2020-06-23  7:31   ` Jason Wang
@ 2020-06-23  9:38     ` Cindy Lu
  0 siblings, 0 replies; 46+ messages in thread
From: Cindy Lu @ 2020-06-23  9:38 UTC (permalink / raw)
  To: Jason Wang
  Cc: Cornelia Huck, Michael Tsirkin, mhabets, qemu-devel, hanand,
	Rob Miller, saugatm, Markus Armbruster, hch,
	Eugenio Perez Martin, jgg, Shahaf Shuler, kevin.tian, parav,
	Vitaly Mireyno, Liang, Cunming, gdawar, jiri, xiao.w.wang,
	Stefan Hajnoczi, Wang, Zhihong, Tiwei Bie, Ariel Adam, rdunlap,
	Maxime Coquelin, Zhu, Lingshan

On Tue, Jun 23, 2020 at 3:31 PM Jason Wang <jasowang@redhat.com> wrote:
>
>
> On 2020/6/22 下午11:37, Cindy Lu wrote:
> > Currently we have 2 types of vhost backends in QEMU: vhost kernel and
> > vhost-user. The above patch provides a generic device for vDPA purpose,
> > this vDPA device exposes to user space a non-vendor-specific configuration
> > interface for setting up a vhost HW accelerator, this patch set introduces
> > a third vhost backend called vhost-vdpa based on the vDPA interface.
> >
> > Vhost-vdpa usage:
> >
> > qemu-system-x86_64 -cpu host -enable-kvm \
> >      ......
> >      -netdev type=vhost-vdpa,vhostdev=/dev/vhost-vdpa-id,id=vhost-vdpa0 \
> >      -device virtio-net-pci,netdev=vhost-vdpa0,page-per-vq=on \
> >
> > Signed-off-by: Lingshan zhu <lingshan.zhu@intel.com>
> > Signed-off-by: Tiwei Bie <tiwei.bie@intel.com>
> > Signed-off-by: Cindy Lu <lulu@redhat.com>
> > ---
> >   configure                         |  21 ++
> >   hw/net/vhost_net.c                |  19 +-
> >   hw/net/virtio-net.c               |  19 +-
> >   hw/virtio/Makefile.objs           |   1 +
> >   hw/virtio/vhost-backend.c         |  22 +-
> >   hw/virtio/vhost-vdpa.c            | 406 ++++++++++++++++++++++++++++++
> >   hw/virtio/vhost.c                 |  42 +++-
> >   include/hw/virtio/vhost-backend.h |   6 +-
> >   include/hw/virtio/vhost-vdpa.h    |  26 ++
> >   include/hw/virtio/vhost.h         |   6 +
> >   qemu-options.hx                   |  12 +
> >   11 files changed, 555 insertions(+), 25 deletions(-)
> >   create mode 100644 hw/virtio/vhost-vdpa.c
> >   create mode 100644 include/hw/virtio/vhost-vdpa.h
> >
> > diff --git a/configure b/configure
> > index 23b5e93752..53679ee57f 100755
> > --- a/configure
> > +++ b/configure
> > @@ -1557,6 +1557,10 @@ for opt do
> >     ;;
> >     --enable-vhost-user) vhost_user="yes"
> >     ;;
> > +  --disable-vhost-vdpa) vhost_vdpa="no"
> > +  ;;
> > +  --enable-vhost-vdpa) vhost_vdpa="yes"
> > +  ;;
> >     --disable-vhost-kernel) vhost_kernel="no"
> >     ;;
> >     --enable-vhost-kernel) vhost_kernel="yes"
> > @@ -1846,6 +1850,7 @@ disabled with --disable-FEATURE, default is enabled if available:
> >     vhost-crypto    vhost-user-crypto backend support
> >     vhost-kernel    vhost kernel backend support
> >     vhost-user      vhost-user backend support
> > +  vhost-vdpa      vhost-vdpa kernel backend support
> >     spice           spice
> >     rbd             rados block device (rbd)
> >     libiscsi        iscsi support
> > @@ -2336,6 +2341,10 @@ test "$vhost_user" = "" && vhost_user=yes
> >   if test "$vhost_user" = "yes" && test "$mingw32" = "yes"; then
> >     error_exit "vhost-user isn't available on win32"
> >   fi
> > +test "$vhost_vdpa" = "" && vhost_vdpa=$linux
> > +if test "$vhost_vdpa" = "yes" && test "$linux" != "yes"; then
> > +  error_exit "vhost-vdpa is only available on Linux"
> > +fi
> >   test "$vhost_kernel" = "" && vhost_kernel=$linux
> >   if test "$vhost_kernel" = "yes" && test "$linux" != "yes"; then
> >     error_exit "vhost-kernel is only available on Linux"
> > @@ -2364,6 +2373,11 @@ test "$vhost_user_fs" = "" && vhost_user_fs=$vhost_user
> >   if test "$vhost_user_fs" = "yes" && test "$vhost_user" = "no"; then
> >     error_exit "--enable-vhost-user-fs requires --enable-vhost-user"
> >   fi
> > +#vhost-vdpa backends
> > +test "$vhost_net_vdpa" = "" && vhost_net_vdpa=$vhost_vdpa
> > +if test "$vhost_net_vdpa" = "yes" && test "$vhost_vdpa" = "no"; then
> > +  error_exit "--enable-vhost-net-vdpa requires --enable-vhost-vdpa"
> > +fi
> >
> >   # OR the vhost-kernel and vhost-user values for simplicity
> >   if test "$vhost_net" = ""; then
> > @@ -6673,6 +6687,7 @@ echo "vhost-scsi support $vhost_scsi"
> >   echo "vhost-vsock support $vhost_vsock"
> >   echo "vhost-user support $vhost_user"
> >   echo "vhost-user-fs support $vhost_user_fs"
> > +echo "vhost-vdpa support $vhost_vdpa"
> >   echo "Trace backends    $trace_backends"
> >   if have_backend "simple"; then
> >   echo "Trace output file $trace_file-<pid>"
> > @@ -7170,6 +7185,9 @@ fi
> >   if test "$vhost_net_user" = "yes" ; then
> >     echo "CONFIG_VHOST_NET_USER=y" >> $config_host_mak
> >   fi
> > +if test "$vhost_net_vdpa" = "yes" ; then
> > +  echo "CONFIG_VHOST_NET_VDPA=y" >> $config_host_mak
> > +fi
> >   if test "$vhost_crypto" = "yes" ; then
> >     echo "CONFIG_VHOST_CRYPTO=y" >> $config_host_mak
> >   fi
> > @@ -7182,6 +7200,9 @@ fi
> >   if test "$vhost_user" = "yes" ; then
> >     echo "CONFIG_VHOST_USER=y" >> $config_host_mak
> >   fi
> > +if test "$vhost_vdpa" = "yes" ; then
> > +  echo "CONFIG_VHOST_VDPA=y" >> $config_host_mak
> > +fi
> >   if test "$vhost_user_fs" = "yes" ; then
> >     echo "CONFIG_VHOST_USER_FS=y" >> $config_host_mak
> >   fi
> > diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c
> > index 04cc3db264..cc259e571d 100644
> > --- a/hw/net/vhost_net.c
> > +++ b/hw/net/vhost_net.c
> > @@ -17,8 +17,10 @@
> >   #include "net/net.h"
> >   #include "net/tap.h"
> >   #include "net/vhost-user.h"
> > +#include "net/vhost-vdpa.h"
> >
> >   #include "standard-headers/linux/vhost_types.h"
> > +#include "linux-headers/linux/vhost.h"
> >   #include "hw/virtio/virtio-net.h"
> >   #include "net/vhost_net.h"
> >   #include "qemu/error-report.h"
> > @@ -33,12 +35,6 @@
> >   #include "hw/virtio/vhost.h"
> >   #include "hw/virtio/virtio-bus.h"
> >
> > -struct vhost_net {
> > -    struct vhost_dev dev;
> > -    struct vhost_virtqueue vqs[2];
> > -    int backend;
> > -    NetClientState *nc;
> > -};
> >
> >   /* Features supported by host kernel. */
> >   static const int kernel_feature_bits[] = {
> > @@ -84,7 +80,6 @@ static const int user_feature_bits[] = {
> >
> >       VHOST_INVALID_FEATURE_BIT
> >   };
> > -
>
>
> Unnecessary change.
>
>
Will remove this
> >   static const int *vhost_net_get_feature_bits(struct vhost_net *net)
> >   {
> >       const int *feature_bits = 0;
> > @@ -96,6 +91,9 @@ static const int *vhost_net_get_feature_bits(struct vhost_net *net)
> >       case NET_CLIENT_DRIVER_VHOST_USER:
> >           feature_bits = user_feature_bits;
> >           break;
> > +    case NET_CLIENT_DRIVER_VHOST_VDPA:
> > +        feature_bits = vdpa_feature_bits;
> > +        break;
> >       default:
> >           error_report("Feature bits not defined for this type: %d",
> >                   net->nc->info->type);
> > @@ -348,6 +346,7 @@ int vhost_net_start(VirtIODevice *dev, NetClientState *ncs,
> >       }
> >
> >       for (i = 0; i < total_queues; i++) {
> > +
>
>
> Unnecessary change.
>
Will remove this
>
> >           peer = qemu_get_peer(ncs, i);
> >           r = vhost_net_start_one(get_vhost_net(peer), dev);
> >
> > @@ -444,6 +443,12 @@ VHostNetState *get_vhost_net(NetClientState *nc)
> >           vhost_net = vhost_user_get_vhost_net(nc);
> >           assert(vhost_net);
> >           break;
> > +#endif
> > +#ifdef CONFIG_VHOST_NET_VDPA
> > +    case NET_CLIENT_DRIVER_VHOST_VDPA:
> > +        vhost_net = vhost_vdpa_get_vhost_net(nc);
> > +        assert(vhost_net);
> > +        break;
> >   #endif
> >       default:
> >           break;
> > diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
> > index a46e3b37a7..8c85e2e1e1 100644
> > --- a/hw/net/virtio-net.c
> > +++ b/hw/net/virtio-net.c
> > @@ -42,6 +42,7 @@
> >   #include "trace.h"
> >   #include "monitor/qdev.h"
> >   #include "hw/pci/pci.h"
> > +#include "hw/virtio/vhost.h"
> >
> >   #define VIRTIO_NET_VM_VERSION    11
> >
> > @@ -131,6 +132,8 @@ static void virtio_net_get_config(VirtIODevice *vdev, uint8_t *config)
> >   {
> >       VirtIONet *n = VIRTIO_NET(vdev);
> >       struct virtio_net_config netcfg;
> > +    int ret = 0;
> > +    memset(&netcfg, 0 , sizeof(struct virtio_net_config));
> >
> >       virtio_stw_p(vdev, &netcfg.status, n->status);
> >       virtio_stw_p(vdev, &netcfg.max_virtqueue_pairs, n->max_queues);
> > @@ -139,13 +142,21 @@ static void virtio_net_get_config(VirtIODevice *vdev, uint8_t *config)
> >       virtio_stl_p(vdev, &netcfg.speed, n->net_conf.speed);
> >       netcfg.duplex = n->net_conf.duplex;
> >       memcpy(config, &netcfg, n->config_size);
> > +    NetClientState *nc = qemu_get_queue(n->nic);
> > +    if (nc->peer->info->type == NET_CLIENT_DRIVER_VHOST_VDPA) {
> > +        ret = vhost_net_get_config(get_vhost_net(nc->peer), (uint8_t *)&netcfg,
> > +                             n->config_size);
> > +        if (ret != -1) {
> > +            memcpy(config, &netcfg, n->config_size);
> > +        }
> > +    }
>
>
> This is kind of sub-optimal.
>
> I think the a better approach is deal all the stuffs inside
> vhost_net_get_config().
>
>
Sure will do
> >   }
> >
> >   static void virtio_net_set_config(VirtIODevice *vdev, const uint8_t *config)
> >   {
> >       VirtIONet *n = VIRTIO_NET(vdev);
> > +    NetClientState *nc = qemu_get_queue(n->nic);
> >       struct virtio_net_config netcfg = {};
> > -
>
>
> Unnecessary change.
>
Will remove this
>
> >       memcpy(&netcfg, config, n->config_size);
> >
> >       if (!virtio_vdev_has_feature(vdev, VIRTIO_NET_F_CTRL_MAC_ADDR) &&
> > @@ -154,6 +165,11 @@ static void virtio_net_set_config(VirtIODevice *vdev, const uint8_t *config)
> >           memcpy(n->mac, netcfg.mac, ETH_ALEN);
> >           qemu_format_nic_info_str(qemu_get_queue(n->nic), n->mac);
> >       }
> > +    if (nc->peer->info->type == NET_CLIENT_DRIVER_VHOST_VDPA) {
> > +        vhost_net_set_config(get_vhost_net(nc->peer), (uint8_t *)&netcfg,
> > +                               0, n->config_size,
> > +                               VHOST_SET_CONFIG_TYPE_MASTER);
> > +      }
>
>
> Similar issues as get_config.
>
>
> >   }
> >
> >   static bool virtio_net_started(VirtIONet *n, uint8_t status)
> > @@ -2958,7 +2974,6 @@ static void virtio_net_device_realize(DeviceState *dev, Error **errp)
> >       } else if (n->net_conf.speed >= 0) {
> >           n->host_features |= (1ULL << VIRTIO_NET_F_SPEED_DUPLEX);
> >       }
> > -
>
>
> Unnecessary change.
>
Will remove this
>
> >       if (n->failover) {
> >           n->primary_listener.should_be_hidden =
> >               virtio_net_primary_should_be_hidden;
> > diff --git a/hw/virtio/Makefile.objs b/hw/virtio/Makefile.objs
> > index 4e4d39a0a4..6b1b1a5fce 100644
> > --- a/hw/virtio/Makefile.objs
> > +++ b/hw/virtio/Makefile.objs
> > @@ -5,6 +5,7 @@ obj-y += virtio.o
> >   obj-$(CONFIG_VHOST) += vhost.o vhost-backend.o
> >   common-obj-$(call lnot,$(CONFIG_VHOST)) += vhost-stub.o
> >   obj-$(CONFIG_VHOST_USER) += vhost-user.o
> > +obj-$(CONFIG_VHOST_VDPA) += vhost-vdpa.o
> >
> >   common-obj-$(CONFIG_VIRTIO_RNG) += virtio-rng.o
> >   common-obj-$(CONFIG_VIRTIO_PCI) += virtio-pci.o
> > diff --git a/hw/virtio/vhost-backend.c b/hw/virtio/vhost-backend.c
> > index 660e9e8588..84e5b1a833 100644
> > --- a/hw/virtio/vhost-backend.c
> > +++ b/hw/virtio/vhost-backend.c
> > @@ -14,7 +14,7 @@
> >   #include "qemu/error-report.h"
> >   #include "qemu/main-loop.h"
> >   #include "standard-headers/linux/vhost_types.h"
> > -
> > +#include "hw/virtio/vhost-vdpa.h"
> >   #ifdef CONFIG_VHOST_KERNEL
> >   #include <linux/vhost.h>
> >   #include <sys/ioctl.h>
> > @@ -22,10 +22,19 @@
> >   static int vhost_kernel_call(struct vhost_dev *dev, unsigned long int request,
> >                                void *arg)
> >   {
> > -    int fd = (uintptr_t) dev->opaque;
> > -
> > -    assert(dev->vhost_ops->backend_type == VHOST_BACKEND_TYPE_KERNEL);
> > +    int fd = -1;
> > +    switch (dev->vhost_ops->backend_type) {
> > +    case VHOST_BACKEND_TYPE_KERNEL:
> > +        fd  = (uintptr_t)dev->opaque;
> > +        break;
> > +    case VHOST_BACKEND_TYPE_VDPA:
> > +        fd = ((struct vhost_vdpa *)dev->opaque)->device_fd;
> > +        break;
> > +    default:
> > +        g_assert_not_reached();
> > +    }
> >
> > +    assert(fd != -1);
> >       return ioctl(fd, request, arg);
> >   }
> >
> > @@ -285,6 +294,11 @@ int vhost_set_backend_type(struct vhost_dev *dev, VhostBackendType backend_type)
> >       case VHOST_BACKEND_TYPE_USER:
> >           dev->vhost_ops = &user_ops;
> >           break;
> > +#endif
> > +#ifdef CONFIG_VHOST_VDPA
> > +    case VHOST_BACKEND_TYPE_VDPA:
> > +        dev->vhost_ops = &vdpa_ops;
> > +        break;
> >   #endif
> >       default:
> >           error_report("Unknown vhost backend type");
> > diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c
> > new file mode 100644
> > index 0000000000..1724d404ce
> > --- /dev/null
> > +++ b/hw/virtio/vhost-vdpa.c
> > @@ -0,0 +1,406 @@
> > +/*
> > + * vhost-vdpa
> > + *
> > + *  Copyright(c) 2017-2018 Intel Corporation.
> > + *  Copyright(c) 2020 Red Hat, Inc.
> > + *
> > + * This work is licensed under the terms of the GNU GPL, version 2 or later.
> > + * See the COPYING file in the top-level directory.
> > + *
> > + */
> > +
> > +#include "qemu/osdep.h"
> > +#include <linux/vhost.h>
> > +#include <linux/vfio.h>
> > +#include <sys/eventfd.h>
> > +#include <sys/ioctl.h>
> > +#include "hw/virtio/vhost.h"
> > +#include "hw/virtio/vhost-backend.h"
> > +#include "hw/virtio/virtio-net.h"
> > +#include "hw/virtio/vhost-vdpa.h"
> > +#include "qemu/main-loop.h"
> > +#include <linux/kvm.h>
> > +#include "sysemu/kvm.h"
> > +
> > +
> > +static bool vhost_vdpa_listener_skipped_section(MemoryRegionSection *section)
> > +{
> > +    return (!memory_region_is_ram(section->mr) &&
> > +            !memory_region_is_iommu(section->mr)) ||
> > +           /*
> > +            * Sizing an enabled 64-bit BAR can cause spurious mappings to
> > +            * addresses in the upper part of the 64-bit address space.  These
> > +            * are never accessed by the CPU and beyond the address width of
> > +            * some IOMMU hardware.  TODO: VDPA should tell us the IOMMU width.
>
>
> Note that, I post patches for reporting IOVA range, we need add the
> check through that in the future.
>
>
> > +            */
> > +           section->offset_within_address_space & (1ULL << 63);
> > +}
> > +
> > +static int vhost_vdpa_dma_map(struct vhost_vdpa *v, hwaddr iova, hwaddr size,
> > +                              void *vaddr, bool readonly)
> > +{
> > +    struct vhost_msg_v2 msg;
> > +    int fd = v->device_fd;
> > +    int ret = 0;
> > +
> > +    msg.type =  v->msg_type;
> > +    msg.iotlb.iova = iova;
> > +    msg.iotlb.size = size;
> > +    msg.iotlb.uaddr = (uint64_t)vaddr;
> > +    msg.iotlb.perm = readonly ? VHOST_ACCESS_RO : VHOST_ACCESS_RW;
> > +    msg.iotlb.type = VHOST_IOTLB_UPDATE;
> > +
> > +    if (write(fd, &msg, sizeof(msg)) != sizeof(msg)) {
> > +        error_report("failed to write, fd=%d, errno=%d (%s)",
> > +            fd, errno, strerror(errno));
> > +        return -EIO ;
> > +    }
> > +
> > +    return ret;
> > +}
> > +
> > +static int vhost_vdpa_dma_unmap(struct vhost_vdpa *v, hwaddr iova,
> > +                                hwaddr size)
> > +{
> > +    struct vhost_msg_v2 msg;
> > +    int fd = v->device_fd;
> > +    int ret = 0;
> > +
> > +    msg.type =  v->msg_type;
> > +    msg.iotlb.iova = iova;
> > +    msg.iotlb.size = size;
> > +    msg.iotlb.type = VHOST_IOTLB_INVALIDATE;
> > +
> > +    if (write(fd, &msg, sizeof(msg)) != sizeof(msg)) {
> > +        error_report("failed to write, fd=%d, errno=%d (%s)",
> > +            fd, errno, strerror(errno));
> > +        return -EIO ;
> > +    }
> > +
> > +    return ret;
> > +}
> > +
> > +static void vhost_vdpa_listener_region_add(MemoryListener *listener,
> > +                                           MemoryRegionSection *section)
> > +{
> > +    struct vhost_vdpa *v = container_of(listener, struct vhost_vdpa, listener);
> > +    hwaddr iova;
> > +    Int128 llend, llsize;
> > +    void *vaddr;
> > +    int ret;
> > +
> > +    if (vhost_vdpa_listener_skipped_section(section)) {
> > +        return;
> > +    }
> > +
> > +    if (unlikely((section->offset_within_address_space & ~TARGET_PAGE_MASK) !=
> > +                 (section->offset_within_region & ~TARGET_PAGE_MASK))) {
> > +        error_report("%s received unaligned region", __func__);
> > +        return;
> > +    }
> > +
> > +    iova = TARGET_PAGE_ALIGN(section->offset_within_address_space);
> > +    llend = int128_make64(section->offset_within_address_space);
> > +    llend = int128_add(llend, section->size);
> > +    llend = int128_and(llend, int128_exts64(TARGET_PAGE_MASK));
> > +
> > +    if (int128_ge(int128_make64(iova), llend)) {
> > +        return;
> > +    }
> > +
> > +    memory_region_ref(section->mr);
> > +
> > +    /* Here we assume that memory_region_is_ram(section->mr)==true */
> > +
> > +    vaddr = memory_region_get_ram_ptr(section->mr) +
> > +            section->offset_within_region +
> > +            (iova - section->offset_within_address_space);
> > +
> > +    llsize = int128_sub(llend, int128_make64(iova));
> > +
> > +    ret = vhost_vdpa_dma_map(v, iova, int128_get64(llsize),
> > +                             vaddr, section->readonly);
> > +    if (ret) {
> > +        error_report("vhost vdpa map fail!");
> > +        if (memory_region_is_ram_device(section->mr)) {
> > +            /* Allow unexpected mappings not to be fatal for RAM devices */
> > +            error_report("map ram fail!");
> > +          return ;
> > +        }
> > +        goto fail;
> > +    }
> > +
> > +    return;
> > +
> > +fail:
> > +    if (memory_region_is_ram_device(section->mr)) {
> > +        error_report("failed to vdpa_dma_map. pci p2p may not work");
> > +        return;
> > +
> > +    }
> > +    /*
> > +     * On the initfn path, store the first error in the container so we
> > +     * can gracefully fail.  Runtime, there's not much we can do other
> > +     * than throw a hardware error.
> > +     */
> > +    error_report("vhost-vdpa: DMA mapping failed, unable to continue");
> > +    return;
> > +
> > +}
> > +
> > +static void vhost_vdpa_listener_region_del(MemoryListener *listener,
> > +                                           MemoryRegionSection *section)
> > +{
> > +    struct vhost_vdpa *v = container_of(listener, struct vhost_vdpa, listener);
> > +    hwaddr iova;
> > +    Int128 llend, llsize;
> > +    int ret;
> > +    bool try_unmap = true;
> > +
> > +    if (vhost_vdpa_listener_skipped_section(section)) {
> > +        return;
> > +    }
> > +
> > +    if (unlikely((section->offset_within_address_space & ~TARGET_PAGE_MASK) !=
> > +                 (section->offset_within_region & ~TARGET_PAGE_MASK))) {
> > +        error_report("%s received unaligned region", __func__);
> > +        return;
> > +    }
> > +
> > +    iova = TARGET_PAGE_ALIGN(section->offset_within_address_space);
> > +    llend = int128_make64(section->offset_within_address_space);
> > +    llend = int128_add(llend, section->size);
> > +    llend = int128_and(llend, int128_exts64(TARGET_PAGE_MASK));
> > +
> > +    if (int128_ge(int128_make64(iova), llend)) {
> > +        return;
> > +    }
> > +
> > +    llsize = int128_sub(llend, int128_make64(iova));
> > +
> > +    if (try_unmap) {
> > +        ret = vhost_vdpa_dma_unmap(v, iova, int128_get64(llsize));
> > +        if (ret) {
> > +            error_report("vhost_vdpa dma unmap error!");
> > +        }
> > +    }
> > +
> > +    memory_region_unref(section->mr);
> > +}
> > +/*
> > + * IOTLB API is used by vhost-vpda which requires incremental updating
> > + * of the mapping. So we can not use generic vhost memory listener which
> > + * depends on the addnop().
> > + */
> > +static const MemoryListener vhost_vdpa_memory_listener = {
> > +    .region_add = vhost_vdpa_listener_region_add,
> > +    .region_del = vhost_vdpa_listener_region_del,
> > +};
> > +
> > +static int vhost_vdpa_call(struct vhost_dev *dev, unsigned long int request,
> > +                             void *arg)
> > +{
> > +    struct vhost_vdpa *v = dev->opaque;
> > +    int fd = v->device_fd;
> > +
> > +    assert(dev->vhost_ops->backend_type == VHOST_BACKEND_TYPE_VDPA);
> > +
> > +    return ioctl(fd, request, arg);
> > +}
> > +
> > +static void vhost_vdpa_add_status(struct vhost_dev *dev, uint8_t status)
> > +{
> > +    uint8_t s;
> > +
> > +    if (vhost_vdpa_call(dev, VHOST_VDPA_GET_STATUS, &s)) {
> > +        return;
> > +    }
> > +
> > +    s |= status;
> > +
> > +    vhost_vdpa_call(dev, VHOST_VDPA_SET_STATUS, &s);
> > +}
> > +
> > +static int vhost_vdpa_init(struct vhost_dev *dev, void *opaque)
> > +{
> > +    struct vhost_vdpa *v;
> > +    uint64_t features;
> > +    assert(dev->vhost_ops->backend_type == VHOST_BACKEND_TYPE_VDPA);
> > +
> > +    v = opaque;
> > +    dev->opaque =  opaque ;
> > +    vhost_vdpa_call(dev, VHOST_GET_FEATURES, &features);
> > +    dev->backend_features = features;
> > +    v->listener = vhost_vdpa_memory_listener;
> > +    v->msg_type = VHOST_IOTLB_MSG_V2;
> > +
> > +    vhost_vdpa_add_status(dev, VIRTIO_CONFIG_S_ACKNOWLEDGE |
> > +                               VIRTIO_CONFIG_S_DRIVER);
> > +
> > +    return 0;
> > +}
> > +
> > +static int vhost_vdpa_cleanup(struct vhost_dev *dev)
> > +{
> > +    struct vhost_vdpa *v;
> > +    assert(dev->vhost_ops->backend_type == VHOST_BACKEND_TYPE_VDPA);
> > +    v = dev->opaque;
> > +    memory_listener_unregister(&v->listener);
> > +
> > +    dev->opaque = NULL;
> > +    return 0;
> > +}
> > +
> > +static int vhost_vdpa_memslots_limit(struct vhost_dev *dev)
> > +{
> > +    return INT_MAX;
> > +}
> > +
> > +static int vhost_vdpa_set_mem_table(struct vhost_dev *dev,
> > +                                    struct vhost_memory *mem)
> > +{
> > +
> > +    if (mem->padding) {
> > +        return -1;
> > +    }
> > +
> > +    return 0;
> > +}
> > +
> > +static int vhost_vdpa_set_features(struct vhost_dev *dev,
> > +                                   uint64_t features)
> > +{
> > +    int ret;
> > +    ret = vhost_vdpa_call(dev, VHOST_SET_FEATURES, &features);
> > +    uint8_t status = 0;
> > +    if (ret) {
> > +        return ret;
> > +    }
> > +    vhost_vdpa_add_status(dev, VIRTIO_CONFIG_S_FEATURES_OK);
> > +    vhost_vdpa_call(dev, VHOST_VDPA_GET_STATUS, &status);
> > +
> > +    return !(status & VIRTIO_CONFIG_S_FEATURES_OK);
> > +}
> > +
> > +int vhost_vdpa_get_device_id(struct vhost_dev *dev,
> > +                                   uint32_t *device_id)
> > +{
> > +    return vhost_vdpa_call(dev, VHOST_VDPA_GET_DEVICE_ID, device_id);
> > +}
> > +
> > +static int vhost_vdpa_reset_device(struct vhost_dev *dev)
> > +{
> > +    uint8_t status = 0;
> > +
> > +    return vhost_vdpa_call(dev, VHOST_VDPA_SET_STATUS, &status);
> > +}
> > +
> > +static int vhost_vdpa_get_vq_index(struct vhost_dev *dev, int idx)
> > +{
> > +    assert(idx >= dev->vq_index && idx < dev->vq_index + dev->nvqs);
> > +
> > +    return idx - dev->vq_index;
> > +}
> > +
> > +static int vhost_vdpa_set_vring_ready(struct vhost_dev *dev)
> > +{
> > +    int i;
> > +    for (i = 0; i < dev->nvqs; ++i) {
> > +        struct vhost_vring_state state = {
> > +            .index = dev->vq_index + i,
> > +            .num = 1,
> > +        };
> > +        vhost_vdpa_call(dev, VHOST_VDPA_SET_VRING_ENABLE, &state);
> > +    }
> > +    return 0;
> > +}
> > +
> > +static int vhost_vdpa_set_config(struct vhost_dev *dev, const uint8_t *data,
> > +                                   uint32_t offset, uint32_t size,
> > +                                   uint32_t flags)
> > +{
> > +    struct vhost_vdpa_config *config;
> > +    int ret;
> > +    unsigned long config_size = offsetof(struct vhost_vdpa_config, buf);
> > +    config = g_malloc(size + config_size);
> > +    if (config == NULL) {
> > +        return -1;
> > +    }
> > +    config->off = offset;
> > +    config->len = size;
> > +    memcpy(config->buf, data, size);
> > +    ret = vhost_vdpa_call(dev, VHOST_VDPA_SET_CONFIG, config);
> > +    g_free(config);
> > +    return ret;
> > +}
> > +
> > +static int vhost_vdpa_get_config(struct vhost_dev *dev, uint8_t *config,
> > +                                   uint32_t config_len)
> > +{
> > +    struct vhost_vdpa_config *v_config;
> > +    unsigned long config_size = offsetof(struct vhost_vdpa_config, buf);
> > +    int ret;
> > +
> > +    v_config = g_malloc(config_len + config_size);
> > +    if (v_config == NULL) {
> > +        return -1;
> > +    }
> > +    v_config->len = config_len;
> > +    v_config->off = 0;
> > +    ret = vhost_vdpa_call(dev, VHOST_VDPA_GET_CONFIG, v_config);
> > +    memcpy(config, v_config->buf, config_len);
> > +    g_free(v_config);
> > +    return ret;
> > + }
> > +
> > +static int vhost_vdpa_dev_start(struct vhost_dev *dev, bool started)
> > +{
> > +    struct vhost_vdpa *v = dev->opaque;
>
>
> newline is needed.
>
>
will add this
> > +    if (started) {
> > +        uint8_t status = 0;
> > +        memory_listener_register(&v->listener, &address_space_memory);
> > +        vhost_vdpa_set_vring_ready(dev);
> > +        vhost_vdpa_add_status(dev, VIRTIO_CONFIG_S_DRIVER_OK);
> > +        vhost_vdpa_call(dev, VHOST_VDPA_GET_STATUS, &status);
> > +
> > +        return !(status & VIRTIO_CONFIG_S_DRIVER_OK);
> > +    } else {
> > +        vhost_vdpa_reset_device(dev);
> > +        vhost_vdpa_add_status(dev, VIRTIO_CONFIG_S_ACKNOWLEDGE |
> > +                                   VIRTIO_CONFIG_S_DRIVER);
> > +        memory_listener_unregister(&v->listener);
> > +
> > +        return 0;
> > +    }
> > +}
> > +
> > +const VhostOps vdpa_ops = {
> > +        .backend_type = VHOST_BACKEND_TYPE_VDPA,
> > +        .vhost_backend_init = vhost_vdpa_init,
> > +        .vhost_backend_cleanup = vhost_vdpa_cleanup,
> > +        .vhost_set_log_base = vhost_kernel_set_log_base,
> > +        .vhost_set_vring_addr = vhost_kernel_set_vring_addr,
> > +        .vhost_set_vring_num = vhost_kernel_set_vring_num,
> > +        .vhost_set_vring_base = vhost_kernel_set_vring_base,
> > +        .vhost_get_vring_base = vhost_kernel_get_vring_base,
> > +        .vhost_set_vring_kick = vhost_kernel_set_vring_kick,
> > +        .vhost_set_vring_call = vhost_kernel_set_vring_call,
> > +        .vhost_get_features = vhost_kernel_get_features,
> > +        .vhost_set_owner = vhost_kernel_set_owner,
> > +        .vhost_set_vring_endian = NULL,
> > +        .vhost_backend_memslots_limit = vhost_vdpa_memslots_limit,
> > +        .vhost_set_mem_table = vhost_vdpa_set_mem_table,
> > +        .vhost_set_features = vhost_vdpa_set_features,
> > +        .vhost_reset_device = vhost_vdpa_reset_device,
> > +        .vhost_get_vq_index = vhost_vdpa_get_vq_index,
> > +        .vhost_get_config  = vhost_vdpa_get_config,
> > +        .vhost_set_config = vhost_vdpa_set_config,
> > +        .vhost_requires_shm_log = NULL,
> > +        .vhost_migration_done = NULL,
> > +        .vhost_backend_can_merge = NULL,
> > +        .vhost_net_set_mtu = NULL,
> > +        .vhost_set_iotlb_callback = NULL,
> > +        .vhost_send_device_iotlb_msg = NULL,
> > +        .vhost_dev_start = vhost_vdpa_dev_start,
> > +        .vhost_get_device_id = vhost_vdpa_get_device_id,
> > +};
> > diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
> > index bfd7f9ce1f..a75be7216b 100644
> > --- a/hw/virtio/vhost.c
> > +++ b/hw/virtio/vhost.c
> > @@ -744,19 +744,34 @@ static void vhost_iommu_region_del(MemoryListener *listener,
> >       }
> >   }
> >
> > +static void vhost_virtqueue_get_addr(struct vhost_dev *dev,
> > +                                    struct vhost_vring_addr *addr,
> > +                                    struct vhost_virtqueue *vq)
> > +{
> > +    /*vDPA need to use the IOVA here to set to hardware*/
> > +    if (dev->vhost_ops->backend_type == VHOST_BACKEND_TYPE_VDPA) {
>
>
> Let's introduce a new vhost_ops for this.
>
will add this
>
> > +        addr->desc_user_addr = (uint64_t)(unsigned long)vq->desc_phys;
> > +        addr->avail_user_addr = (uint64_t)(unsigned long)vq->avail_phys;
> > +        addr->used_user_addr = (uint64_t)(unsigned long)vq->used_phys;
> > +    } else {
> > +        addr->desc_user_addr = (uint64_t)(unsigned long)vq->desc;
> > +        addr->avail_user_addr = (uint64_t)(unsigned long)vq->avail;
> > +        addr->used_user_addr = (uint64_t)(unsigned long)vq->used;
> > +    }
> > +}
> >
> >   static int vhost_virtqueue_set_addr(struct vhost_dev *dev,
> >                                       struct vhost_virtqueue *vq,
> >                                       unsigned idx, bool enable_log)
> >   {
> > -    struct vhost_vring_addr addr = {
> > -        .index = idx,
> > -        .desc_user_addr = (uint64_t)(unsigned long)vq->desc,
> > -        .avail_user_addr = (uint64_t)(unsigned long)vq->avail,
> > -        .used_user_addr = (uint64_t)(unsigned long)vq->used,
> > -        .log_guest_addr = vq->used_phys,
> > -        .flags = enable_log ? (1 << VHOST_VRING_F_LOG) : 0,
> > -    };
> > +    struct vhost_vring_addr addr;
> > +    memset(&addr, 0, sizeof(struct vhost_vring_addr));
> > +
> > +    vhost_virtqueue_get_addr(dev, &addr, vq);
> > +    addr.index = idx;
> > +    addr .log_guest_addr = vq->used_phys;
> > +    addr .flags = enable_log ? (1 << VHOST_VRING_F_LOG) : 0;
>
>
> Unnecessary spaces between addr and log_guest_addr/flags.
>
>
Will remove this
> > +
> >       int r = dev->vhost_ops->vhost_set_vring_addr(dev, &addr);
> >       if (r < 0) {
> >           VHOST_OPS_DEBUG("vhost_set_vring_addr failed");
> > @@ -774,7 +789,9 @@ static int vhost_dev_set_features(struct vhost_dev *dev,
> >           features |= 0x1ULL << VHOST_F_LOG_ALL;
> >       }
> >       if (!vhost_dev_has_iommu(dev)) {
> > -        features &= ~(0x1ULL << VIRTIO_F_IOMMU_PLATFORM);
>
>
>
> A comment is needed here.
>
will add this
>
> > +        if (dev->vhost_ops->backend_type != VHOST_BACKEND_TYPE_VDPA) {
> > +            features &= ~(0x1ULL << VIRTIO_F_IOMMU_PLATFORM);
> > +        }
> >       }
> >       r = dev->vhost_ops->vhost_set_features(dev, features);
> >       if (r < 0) {
> > @@ -1667,7 +1684,8 @@ int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev)
> >           goto fail_log;
> >       }
> >
> > -    if (vhost_dev_has_iommu(hdev)) {
> > +    if (vhost_dev_has_iommu(hdev) &&
> > +        hdev->vhost_ops->vhost_set_iotlb_callback) {
>
>
> A separate patch for this please
>
>
> >           hdev->vhost_ops->vhost_set_iotlb_callback(hdev, true);
> >
> >           /* Update used ring information for IOTLB to work correctly,
> > @@ -1713,7 +1731,9 @@ void vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev)
> >       }
> >
> >       if (vhost_dev_has_iommu(hdev)) {
> > -        hdev->vhost_ops->vhost_set_iotlb_callback(hdev, false);
> > +        if (hdev->vhost_ops->vhost_set_iotlb_callback) {
> > +            hdev->vhost_ops->vhost_set_iotlb_callback(hdev, false);
> > +        }
>
>
> A separate patch for this.
>
will do
>
> >           memory_listener_unregister(&hdev->iommu_listener);
> >       }
> >       vhost_log_put(hdev, true);
> > diff --git a/include/hw/virtio/vhost-backend.h b/include/hw/virtio/vhost-backend.h
> > index c1384bd2c7..c418c2fa0e 100644
> > --- a/include/hw/virtio/vhost-backend.h
> > +++ b/include/hw/virtio/vhost-backend.h
> > @@ -17,7 +17,8 @@ typedef enum VhostBackendType {
> >       VHOST_BACKEND_TYPE_NONE = 0,
> >       VHOST_BACKEND_TYPE_KERNEL = 1,
> >       VHOST_BACKEND_TYPE_USER = 2,
> > -    VHOST_BACKEND_TYPE_MAX = 3,
> > +    VHOST_BACKEND_TYPE_VDPA = 3,
> > +    VHOST_BACKEND_TYPE_MAX = 4,
> >   } VhostBackendType;
> >
> >   typedef enum VhostSetConfigType {
> > @@ -113,6 +114,7 @@ typedef int (*vhost_set_inflight_fd_op)(struct vhost_dev *dev,
> >                                           struct vhost_inflight *inflight);
> >
> >   typedef int (*vhost_dev_start_op)(struct vhost_dev *dev, bool started);
> > +typedef int (*vhost_get_device_id_op)(struct vhost_dev *dev, uint32_t *dev_id);
> >   typedef struct VhostOps {
> >       VhostBackendType backend_type;
> >       vhost_backend_init vhost_backend_init;
> > @@ -154,9 +156,11 @@ typedef struct VhostOps {
> >       vhost_get_inflight_fd_op vhost_get_inflight_fd;
> >       vhost_set_inflight_fd_op vhost_set_inflight_fd;
> >       vhost_dev_start_op vhost_dev_start;
> > +    vhost_get_device_id_op vhost_get_device_id;
> >   } VhostOps;
>
>
> A separate patch for introducing this please.
>
>
will do
> >
> >   extern const VhostOps user_ops;
> > +extern const VhostOps vdpa_ops;
> >
> >   int vhost_set_backend_type(struct vhost_dev *dev,
> >                              VhostBackendType backend_type);
> > diff --git a/include/hw/virtio/vhost-vdpa.h b/include/hw/virtio/vhost-vdpa.h
> > new file mode 100644
> > index 0000000000..6455663388
> > --- /dev/null
> > +++ b/include/hw/virtio/vhost-vdpa.h
> > @@ -0,0 +1,26 @@
> > +/*
> > + * vhost-vdpa.h
> > + *
> > + * Copyright(c) 2017-2018 Intel Corporation.
> > + * Copyright(c) 2020 Red Hat, Inc.
> > + *
> > + * This work is licensed under the terms of the GNU GPL, version 2 or later.
> > + * See the COPYING file in the top-level directory.
> > + *
> > + */
> > +
> > +#ifndef HW_VIRTIO_VHOST_VDPA_H
> > +#define HW_VIRTIO_VHOST_VDPA_H
> > +
> > +#include "hw/virtio/virtio.h"
> > +
> > +typedef struct vhost_vdpa {
> > +    int device_fd;
> > +    uint32_t msg_type;
> > +    MemoryListener listener;
> > +} VhostVDPA;
> > +
> > +extern AddressSpace address_space_memory;
> > +extern int vhost_vdpa_get_device_id(struct vhost_dev *dev,
> > +                                   uint32_t *device_id);
> > +#endif
> > diff --git a/include/hw/virtio/vhost.h b/include/hw/virtio/vhost.h
> > index 59ea53f8c2..f69b5e4a02 100644
> > --- a/include/hw/virtio/vhost.h
> > +++ b/include/hw/virtio/vhost.h
> > @@ -92,6 +92,12 @@ struct vhost_dev {
> >       const VhostDevConfigOps *config_ops;
> >   };
> >
> > +struct vhost_net {
> > +    struct vhost_dev dev;
> > +    struct vhost_virtqueue vqs[2];
> > +    int backend;
> > +    NetClientState *nc;
> > +};
>
>
> A separate patch for this exporting please.
>
> Thanks
>
>
will do
> >
> >   int vhost_dev_init(struct vhost_dev *hdev, void *opaque,
> >                      VhostBackendType backend_type,
> > diff --git a/qemu-options.hx b/qemu-options.hx
> > index 292d4e7c0c..d7d0daaa0e 100644
> > --- a/qemu-options.hx
> > +++ b/qemu-options.hx
> > @@ -2409,6 +2409,10 @@ DEF("netdev", HAS_ARG, QEMU_OPTION_netdev,
> >   #ifdef CONFIG_POSIX
> >       "-netdev vhost-user,id=str,chardev=dev[,vhostforce=on|off]\n"
> >       "                configure a vhost-user network, backed by a chardev 'dev'\n"
> > +#endif
> > +#ifdef __linux__
> > +    "-netdev vhost-vdpa,id=str,vhostdev=/path/to/dev\n"
> > +    "                configure a vhost-vdpa network,Establish a vhost-vdpa netdev\n"
> >   #endif
> >       "-netdev hubport,id=str,hubid=n[,netdev=nd]\n"
> >       "                configure a hub port on the hub with ID 'n'\n", QEMU_ARCH_ALL)
> > @@ -2888,6 +2892,14 @@ SRST
> >                -netdev type=vhost-user,id=net0,chardev=chr0 \
> >                -device virtio-net-pci,netdev=net0
> >
> > +``-netdev vhost-vdpa,vhostdev=/path/to/dev``
> > +    Establish a vhost-vdpa netdev.
> > +
> > +    vDPA device is a device that uses a datapath which complies with
> > +    the virtio specifications with a vendor specific control path.
> > +    vDPA devices can be both physically located on the hardware or
> > +    emulated by software.
> > +
> >   ``-netdev hubport,id=id,hubid=hubid[,netdev=nd]``
> >       Create a hub port on the emulated hub with ID hubid.
> >
>



^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v1 08/10] vhost: implement vhost_dev_start method
  2020-06-23  9:37       ` Jason Wang
@ 2020-06-23  9:39         ` Cindy Lu
  0 siblings, 0 replies; 46+ messages in thread
From: Cindy Lu @ 2020-06-23  9:39 UTC (permalink / raw)
  To: Jason Wang
  Cc: Cornelia Huck, Michael Tsirkin, mhabets, qemu-devel, hanand,
	Rob Miller, saugatm, Markus Armbruster, hch,
	Eugenio Perez Martin, jgg, Shahaf Shuler, kevin.tian, parav,
	Vitaly Mireyno, Liang, Cunming, gdawar, jiri, xiao.w.wang,
	Stefan Hajnoczi, Wang, Zhihong, Ariel Adam, rdunlap,
	Maxime Coquelin, Zhu, Lingshan

On Tue, Jun 23, 2020 at 5:38 PM Jason Wang <jasowang@redhat.com> wrote:
>
>
> On 2020/6/23 下午5:34, Cindy Lu wrote:
> > On Tue, Jun 23, 2020 at 3:21 PM Jason Wang<jasowang@redhat.com>  wrote:
> >> On 2020/6/22 下午11:37, Cindy Lu wrote:
> >>> use the vhost_dev_start callback to send the status to backend
> >> I suggest to squash this into previous patch.
> >>
> > Sure will do
> >>> Signed-off-by: Cindy Lu<lulu@redhat.com>
> >>> ---
> >>>    hw/virtio/vhost.c         | 17 +++++++++++++++++
> >>>    include/hw/virtio/vhost.h |  2 ++
> >>>    2 files changed, 19 insertions(+)
> >>>
> >>> diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
> >>> index 01ebe12f28..bfd7f9ce1f 100644
> >>> --- a/hw/virtio/vhost.c
> >>> +++ b/hw/virtio/vhost.c
> >>> @@ -744,6 +744,7 @@ static void vhost_iommu_region_del(MemoryListener *listener,
> >>>        }
> >>>    }
> >>>
> >>> +
> >>>    static int vhost_virtqueue_set_addr(struct vhost_dev *dev,
> >>>                                        struct vhost_virtqueue *vq,
> >>>                                        unsigned idx, bool enable_log)
> >>> @@ -1661,6 +1662,11 @@ int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev)
> >>>            }
> >>>        }
> >>>
> >>> +    r = vhost_set_start(hdev, true);
> >> I think we need a better name for this function.
> >>
> > Shall we change it to vhost_set_device_start ? Since the
> > vhost_dev_start was occupied by other function
>
>
> Or maybe just open code the vhost_set_start here since there's no other
> users.
>
> Thanks
>
Sure will do
>



^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v1 00/10] vDPA support in qemu
  2020-06-23  9:16   ` Cindy Lu
@ 2020-06-23  9:43     ` Jason Wang
  2020-06-24  9:42       ` Cindy Lu
  0 siblings, 1 reply; 46+ messages in thread
From: Jason Wang @ 2020-06-23  9:43 UTC (permalink / raw)
  To: Cindy Lu, Markus Armbruster
  Cc: rdunlap, Michael Tsirkin, mhabets, qemu-devel, Rob Miller,
	saugatm, hanand, hch, Eugenio Perez Martin, jgg, Shahaf Shuler,
	kevin.tian, parav, Vitaly Mireyno, Liang, Cunming, gdawar, jiri,
	xiao.w.wang, Stefan Hajnoczi, Wang, Zhihong, Ariel Adam,
	Cornelia Huck, Maxime Coquelin, Zhu, Lingshan


On 2020/6/23 下午5:16, Cindy Lu wrote:
> On Tue, Jun 23, 2020 at 3:07 PM Markus Armbruster <armbru@redhat.com> wrote:
>> Cindy Lu <lulu@redhat.com> writes:
>>
>>> vDPA device is a device that uses a datapath which complies with the
>>> virtio specifications with vendor specific control path. vDPA devices
>>> can be both physically located on the hardware or emulated by software.
>>> This RFC introduce the vDPA support in qemu
>>> TODO
>>> 1) vIOMMU support
>>> 2) live migration support
>> This gives me the foggiest of ideas on what vDPA is.  Could we use
>> docs/interop/vhost-vdpa.rst?
>>
> Sure will add this
>
>

Not sure it's the best place since vhost-vdpa is kernel specific.

Maybe kernel docs (TBD) is a better place and we can refer it this file 
in the future.

But it doesn't harm if you said something more here and refer the kernel 
commit here: 
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=4c8cf31885f69e86be0b5b9e6677a26797365e1d

Thanks




^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v1 10/10] vhost-vdpa: introduce vhost-vdpa net client
  2020-06-23  8:56   ` Jason Wang
@ 2020-06-23  9:57     ` Cindy Lu
  0 siblings, 0 replies; 46+ messages in thread
From: Cindy Lu @ 2020-06-23  9:57 UTC (permalink / raw)
  To: Jason Wang
  Cc: rdunlap, Michael Tsirkin, mhabets, qemu-devel, Rob Miller,
	saugatm, Markus Armbruster, hch, Eugenio Perez Martin, jgg,
	Shahaf Shuler, kevin.tian, parav, Vitaly Mireyno, Liang, Cunming,
	gdawar, jiri, xiao.w.wang, Stefan Hajnoczi, Wang, Zhihong,
	Maxime Coquelin, Tiwei Bie, Ariel Adam, Cornelia Huck, hanand,
	Zhu, Lingshan

On Tue, Jun 23, 2020 at 4:57 PM Jason Wang <jasowang@redhat.com> wrote:
>
>
> On 2020/6/22 下午11:37, Cindy Lu wrote:
> > This patch set introduces a new net client type: vhost-vdpa.
> > vhost-vdpa net client will set up a vDPA device which is specified
> > by a "vhostdev" parameter.
> >
> > Signed-off-by: Lingshan Zhu <lingshan.zhu@intel.com>
> > Signed-off-by: Tiwei Bie <tiwei.bie@intel.com>
> > Signed-off-by: Cindy Lu <lulu@redhat.com>
> > ---
> >   include/net/vhost-vdpa.h |  21 ++++
> >   include/net/vhost_net.h  |   1 -
> >   net/Makefile.objs        |   2 +-
> >   net/clients.h            |   2 +
> >   net/net.c                |   3 +
> >   net/vhost-vdpa.c         | 230 +++++++++++++++++++++++++++++++++++++++
> >   qapi/net.json            |  23 +++-
> >   7 files changed, 278 insertions(+), 4 deletions(-)
> >   create mode 100644 include/net/vhost-vdpa.h
> >   create mode 100644 net/vhost-vdpa.c
> >
> > diff --git a/include/net/vhost-vdpa.h b/include/net/vhost-vdpa.h
> > new file mode 100644
> > index 0000000000..725c8b1c81
> > --- /dev/null
> > +++ b/include/net/vhost-vdpa.h
> > @@ -0,0 +1,21 @@
> > +/*
> > + * vhost-vdpa.h
> > + *
> > + * Copyright(c) 2017-2018 Intel Corporation.
> > + * Copyright(c) 2020 Red Hat, Inc.
> > + *
> > + * This work is licensed under the terms of the GNU GPL, version 2 or later.
> > + * See the COPYING file in the top-level directory.
> > + *
> > + */
> > +
> > +#ifndef VHOST_VDPA_H
> > +#define VHOST_VDPA_H
> > +
> > +struct vhost_net;
> > +struct vhost_net *vhost_vdpa_get_vhost_net(NetClientState *nc);
> > +uint64_t vhost_vdpa_get_acked_features(NetClientState *nc);
> > +
> > +extern const int vdpa_feature_bits[];
> > +
> > +#endif /* VHOST_VDPA_H */
> > diff --git a/include/net/vhost_net.h b/include/net/vhost_net.h
> > index abfb0e8e68..4843cdb36f 100644
> > --- a/include/net/vhost_net.h
> > +++ b/include/net/vhost_net.h
> > @@ -44,5 +44,4 @@ int vhost_set_vring_enable(NetClientState * nc, int enable);
> >   uint64_t vhost_net_get_acked_features(VHostNetState *net);
> >
> >   int vhost_net_set_mtu(struct vhost_net *net, uint16_t mtu);
> > -
>
>
> Let's keep this newline.
>
>
> >   #endif
> > diff --git a/net/Makefile.objs b/net/Makefile.objs
> > index c5d076d19c..5ab45545db 100644
> > --- a/net/Makefile.objs
> > +++ b/net/Makefile.objs
> > @@ -26,7 +26,7 @@ tap-obj-$(CONFIG_SOLARIS) = tap-solaris.o
> >   tap-obj-y ?= tap-stub.o
> >   common-obj-$(CONFIG_POSIX) += tap.o $(tap-obj-y)
> >   common-obj-$(CONFIG_WIN32) += tap-win32.o
> > -
>
>
> And this.
>
>
Sure will do, I will double check these issue next time

> > +common-obj-$(CONFIG_VHOST_NET_VDPA) += vhost-vdpa.o
> >   vde.o-libs = $(VDE_LIBS)
> >
> >   common-obj-$(CONFIG_CAN_BUS) += can/
> > diff --git a/net/clients.h b/net/clients.h
> > index a6ef267e19..92f9b59aed 100644
> > --- a/net/clients.h
> > +++ b/net/clients.h
> > @@ -61,4 +61,6 @@ int net_init_netmap(const Netdev *netdev, const char *name,
> >   int net_init_vhost_user(const Netdev *netdev, const char *name,
> >                           NetClientState *peer, Error **errp);
> >
> > +int net_init_vhost_vdpa(const Netdev *netdev, const char *name,
> > +                        NetClientState *peer, Error **errp);
> >   #endif /* QEMU_NET_CLIENTS_H */
> > diff --git a/net/net.c b/net/net.c
> > index 599fb61028..82624ea9ac 100644
> > --- a/net/net.c
> > +++ b/net/net.c
> > @@ -965,6 +965,9 @@ static int (* const net_client_init_fun[NET_CLIENT_DRIVER__MAX])(
> >   #ifdef CONFIG_VHOST_NET_USER
> >           [NET_CLIENT_DRIVER_VHOST_USER] = net_init_vhost_user,
> >   #endif
> > +#ifdef CONFIG_VHOST_NET_VDPA
> > +        [NET_CLIENT_DRIVER_VHOST_VDPA] = net_init_vhost_vdpa,
> > +#endif
> >   #ifdef CONFIG_L2TPV3
> >           [NET_CLIENT_DRIVER_L2TPV3]    = net_init_l2tpv3,
> >   #endif
> > diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c
> > new file mode 100644
> > index 0000000000..34858a6ea3
> > --- /dev/null
> > +++ b/net/vhost-vdpa.c
> > @@ -0,0 +1,230 @@
> > +/*
> > + * vhost-vdpa.c
> > + *
> > + * Copyright(c) 2017-2018 Intel Corporation.
> > + * Copyright(c) 2020 Red Hat, Inc.
> > + *
> > + * This work is licensed under the terms of the GNU GPL, version 2 or later.
> > + * See the COPYING file in the top-level directory.
> > + *
> > + */
> > +
> > +#include "qemu/osdep.h"
> > +#include "clients.h"
> > +#include "net/vhost_net.h"
> > +#include "net/vhost-vdpa.h"
> > +#include "hw/virtio/vhost-vdpa.h"
> > +#include "qemu/config-file.h"
> > +#include "qemu/error-report.h"
> > +#include "qemu/option.h"
> > +#include "qapi/error.h"
> > +#include <sys/ioctl.h>
> > +#include <err.h>
> > +#include "standard-headers/linux/virtio_net.h"
> > +#include "monitor/monitor.h"
> > +#include "hw/virtio/vhost.h"
> > +
> > +/* Todo:need to add the multiqueue support here */
> > +typedef struct VhostVDPAState {
> > +    NetClientState nc;
> > +    struct vhost_vdpa vhost_vdpa;
> > +    VHostNetState *vhost_net;
> > +    uint64_t acked_features;
> > +    bool started;
> > +} VhostVDPAState;
> > +
> > +const int vdpa_feature_bits[] = {
> > +    VIRTIO_F_NOTIFY_ON_EMPTY,
> > +    VIRTIO_RING_F_INDIRECT_DESC,
> > +    VIRTIO_RING_F_EVENT_IDX,
> > +    VIRTIO_F_ANY_LAYOUT,
> > +    VIRTIO_F_VERSION_1,
> > +    VIRTIO_NET_F_CSUM,
> > +    VIRTIO_NET_F_GUEST_CSUM,
> > +    VIRTIO_NET_F_GSO,
> > +    VIRTIO_NET_F_GUEST_TSO4,
> > +    VIRTIO_NET_F_GUEST_TSO6,
> > +    VIRTIO_NET_F_GUEST_ECN,
> > +    VIRTIO_NET_F_GUEST_UFO,
> > +    VIRTIO_NET_F_HOST_TSO4,
> > +    VIRTIO_NET_F_HOST_TSO6,
> > +    VIRTIO_NET_F_HOST_ECN,
> > +    VIRTIO_NET_F_HOST_UFO,
> > +    VIRTIO_NET_F_MRG_RXBUF,
> > +    VIRTIO_NET_F_MTU,
> > +    VIRTIO_F_IOMMU_PLATFORM,
> > +    VIRTIO_F_RING_PACKED,
> > +    VIRTIO_NET_F_GUEST_ANNOUNCE,
> > +    VHOST_INVALID_FEATURE_BIT
> > +};
> > +
> > +VHostNetState *vhost_vdpa_get_vhost_net(NetClientState *nc)
> > +{
> > +    VhostVDPAState *s = DO_UPCAST(VhostVDPAState, nc, nc);
> > +    assert(nc->info->type == NET_CLIENT_DRIVER_VHOST_VDPA);
> > +    return s->vhost_net;
> > +}
> > +
> > +uint64_t vhost_vdpa_get_acked_features(NetClientState *nc)
> > +{
> > +    VhostVDPAState *s = DO_UPCAST(VhostVDPAState, nc, nc);
> > +    assert(nc->info->type == NET_CLIENT_DRIVER_VHOST_VDPA);
> > +    s->acked_features = vhost_net_get_acked_features(s->vhost_net);
> > +
> > +    return s->acked_features;
> > +}
> > +
> > +static int vhost_vdpa_net_check_device_id(NetClientState *nc)
> > +{
> > +    uint32_t device_id;
> > +    int ret;
> > +    struct vhost_net *net;
> > +    struct vhost_dev *hdev;
> > +    assert(nc->info->type == NET_CLIENT_DRIVER_VHOST_VDPA);
> > +    VhostVDPAState *s = DO_UPCAST(VhostVDPAState, nc, nc);
>
>
> Let's try to avoid those unnecessary conversion and check since the
> caller knows e.g VhostVDPAState.
>
sure will change this
>
> > +    net = s->vhost_net;
> > +    hdev = (struct vhost_dev *)&net->dev;
> > +    ret = hdev->vhost_ops->vhost_get_device_id(hdev, &device_id);
> > +    if (device_id != VIRTIO_ID_NET) {
> > +        return -ENOTSUP;
> > +    }
> > +    return ret;
> > +}
> > +
> > +static void vhost_vdpa_del(NetClientState *ncs)
> > +{
> > +    VhostVDPAState *s;
> > +    assert(ncs->info->type == NET_CLIENT_DRIVER_VHOST_VDPA);
> > +    s = DO_UPCAST(VhostVDPAState, nc, ncs);
> > +    if (s->vhost_net) {
> > +        vhost_net_cleanup(s->vhost_net);
> > +    }
> > +}
> > +
> > +static int vhost_vdpa_add(NetClientState *ncs, void *be)
> > +{
> > +    VhostNetOptions options;
> > +    struct vhost_net *net = NULL;
> > +    VhostVDPAState *s;
> > +    int ret;
> > +
> > +    options.backend_type = VHOST_BACKEND_TYPE_VDPA;
> > +    assert(ncs->info->type == NET_CLIENT_DRIVER_VHOST_VDPA);
> > +    s = DO_UPCAST(VhostVDPAState, nc, ncs);
> > +    options.net_backend = ncs;
> > +    options.opaque      = be;
> > +    options.busyloop_timeout = 0;
> > +    net = vhost_net_init(&options);
> > +    if (!net) {
> > +        error_report("failed to init vhost_net for queue");
> > +        goto err;
> > +    }
> > +    if (s->vhost_net) {
> > +        vhost_net_cleanup(s->vhost_net);
> > +        g_free(s->vhost_net);
> > +    }
> > +    s->vhost_net = net;
> > +    ret = vhost_vdpa_net_check_device_id(ncs);
>
>
> Eli pointed out it's better to validate device Id before vhost_net_init().
>
> Otherwise driver may see e.g DRIVER before getting device id.
>
Maybe we can't move this before vhost_net_init(),
because the callback vhost_ops->vhost_get_device_id was init during
vhost_net_init()

>
> > +    if (ret) {
> > +        goto err;
> > +    }
> > +    return 0;
> > +err:
> > +    if (net) {
> > +        vhost_net_cleanup(net);
> > +    }
> > +    vhost_vdpa_del(ncs);
> > +    return -1;
> > +}
> > +
> > +static void vhost_vdpa_cleanup(NetClientState *nc)
> > +{
> > +    VhostVDPAState *s = DO_UPCAST(VhostVDPAState, nc, nc);
> > +
> > +    if (s->vhost_net) {
> > +        vhost_net_cleanup(s->vhost_net);
> > +        g_free(s->vhost_net);
> > +        s->vhost_net = NULL;
> > +    }
> > +}
> > +
> > +static bool vhost_vdpa_has_vnet_hdr(NetClientState *nc)
> > +{
> > +    assert(nc->info->type == NET_CLIENT_DRIVER_VHOST_VDPA);
> > +
> > +    return true;
> > +}
> > +
> > +static bool vhost_vdpa_has_ufo(NetClientState *nc)
> > +{
> > +    assert(nc->info->type == NET_CLIENT_DRIVER_VHOST_VDPA);
> > +    VhostVDPAState *s = DO_UPCAST(VhostVDPAState, nc, nc);
> > +    uint64_t  features = 0;
>
>
> Unnecessary spaces between uint64_t and features.
>
will remove
>
> > +    features |= (1ULL << VIRTIO_NET_F_HOST_UFO);
> > +    features = vhost_net_get_features(s->vhost_net, features);
> > +    return !!(features & (1ULL << VIRTIO_NET_F_HOST_UFO));
> > +
> > +}
> > +
> > +static NetClientInfo net_vhost_vdpa_info = {
> > +        .type = NET_CLIENT_DRIVER_VHOST_VDPA,
> > +        .size = sizeof(VhostVDPAState),
> > +        .cleanup = vhost_vdpa_cleanup,
> > +        .has_vnet_hdr = vhost_vdpa_has_vnet_hdr,
> > +        .has_ufo = vhost_vdpa_has_ufo,
> > +};
> > +
> > +static int net_vhost_vdpa_init(NetClientState *peer, const char *device,
> > +                               const char *name, const char *vhostdev)
> > +{
> > +    NetClientState *nc = NULL;
> > +    VhostVDPAState *s;
> > +    int vdpa_device_fd = -1;
> > +    int ret = 0;
> > +    assert(name);
> > +    nc = qemu_new_net_client(&net_vhost_vdpa_info, peer, device, name);
> > +    snprintf(nc->info_str, sizeof(nc->info_str), "vhost-vdpa");
>
>
> Do we need an for this vhost-vdpa?
>
> Thanks
>
>
Sure will add this
> > +    nc->queue_index = 0;
> > +    s = DO_UPCAST(VhostVDPAState, nc, nc);
> > +    vdpa_device_fd = qemu_open(vhostdev, O_RDWR);
> > +    if (vdpa_device_fd == -1) {
> > +        return -errno;
> > +    }
> > +    s->vhost_vdpa.device_fd = vdpa_device_fd;
> > +    ret = vhost_vdpa_add(nc, (void *)&s->vhost_vdpa);
> > +    assert(s->vhost_net);
> > +    return ret;
> > +}
> > +
> > +static int net_vhost_check_net(void *opaque, QemuOpts *opts, Error **errp)
> > +{
> > +    const char *name = opaque;
> > +    const char *driver, *netdev;
> > +
> > +    driver = qemu_opt_get(opts, "driver");
> > +    netdev = qemu_opt_get(opts, "netdev");
> > +    if (!driver || !netdev) {
> > +        return 0;
> > +    }
> > +    if (strcmp(netdev, name) == 0 &&
> > +        !g_str_has_prefix(driver, "virtio-net-")) {
> > +        error_setg(errp, "vhost-vdpa requires frontend driver virtio-net-*");
> > +        return -1;
> > +    }
> > +    return 0;
> > +}
> > +
> > +int net_init_vhost_vdpa(const Netdev *netdev, const char *name,
> > +                        NetClientState *peer, Error **errp)
> > +{
> > +    const NetdevVhostVDPAOptions *opts;
> > +
> > +    assert(netdev->type == NET_CLIENT_DRIVER_VHOST_VDPA);
> > +    opts = &netdev->u.vhost_vdpa;
> > +    /* verify net frontend */
> > +    if (qemu_opts_foreach(qemu_find_opts("device"), net_vhost_check_net,
> > +                          (char *)name, errp)) {
> > +        return -1;
> > +    }
> > +    return net_vhost_vdpa_init(peer, "vhost_vdpa", name, opts->vhostdev);
> > +}
> > diff --git a/qapi/net.json b/qapi/net.json
> > index cebb1b52e3..03aad67693 100644
> > --- a/qapi/net.json
> > +++ b/qapi/net.json
> > @@ -428,6 +428,24 @@
> >       '*vhostforce':    'bool',
> >       '*queues':        'int' } }
> >
> > +##
> > +# @NetdevVhostVDPAOptions:
> > +#
> > +# Vhost-vdpa network backend
> > +#
> > +# @vhostdev: name of a vdpa dev path in sysfs
> > +#            (default path:/dev/vhost-vdpa-$ID)
> > +#
> > +# @queues: number of queues to be created for multiqueue vhost-vdpa
> > +#          (default: 1)
> > +#
> > +# Since: 5.1
> > +##
> > +{ 'struct': 'NetdevVhostVDPAOptions',
> > +  'data': {
> > +    '*vhostdev':     'str',
> > +    '*queues':       'int' } }
> > +
> >   ##
> >   # @NetClientDriver:
> >   #
> > @@ -437,7 +455,7 @@
> >   ##
> >   { 'enum': 'NetClientDriver',
> >     'data': [ 'none', 'nic', 'user', 'tap', 'l2tpv3', 'socket', 'vde',
> > -            'bridge', 'hubport', 'netmap', 'vhost-user' ] }
> > +            'bridge', 'hubport', 'netmap', 'vhost-user', 'vhost-vdpa' ] }
> >
> >   ##
> >   # @Netdev:
> > @@ -465,7 +483,8 @@
> >       'bridge':   'NetdevBridgeOptions',
> >       'hubport':  'NetdevHubPortOptions',
> >       'netmap':   'NetdevNetmapOptions',
> > -    'vhost-user': 'NetdevVhostUserOptions' } }
> > +    'vhost-user': 'NetdevVhostUserOptions',
> > +    'vhost-vdpa': 'NetdevVhostVDPAOptions' } }
> >
> >   ##
> >   # @NetLegacy:
>



^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v1 00/10] vDPA support in qemu
  2020-06-23  9:43     ` Jason Wang
@ 2020-06-24  9:42       ` Cindy Lu
  2020-06-25  4:48         ` Markus Armbruster
  0 siblings, 1 reply; 46+ messages in thread
From: Cindy Lu @ 2020-06-24  9:42 UTC (permalink / raw)
  To: Jason Wang
  Cc: Cornelia Huck, Michael Tsirkin, mhabets, qemu-devel, hanand,
	Rob Miller, saugatm, Markus Armbruster, hch,
	Eugenio Perez Martin, jgg, Shahaf Shuler, kevin.tian, parav,
	Vitaly Mireyno, Liang, Cunming, gdawar, jiri, xiao.w.wang,
	Stefan Hajnoczi, Wang, Zhihong, Ariel Adam, rdunlap,
	Maxime Coquelin, Zhu, Lingshan

On Tue, Jun 23, 2020 at 5:43 PM Jason Wang <jasowang@redhat.com> wrote:
>
>
> On 2020/6/23 下午5:16, Cindy Lu wrote:
> > On Tue, Jun 23, 2020 at 3:07 PM Markus Armbruster <armbru@redhat.com> wrote:
> >> Cindy Lu <lulu@redhat.com> writes:
> >>
> >>> vDPA device is a device that uses a datapath which complies with the
> >>> virtio specifications with vendor specific control path. vDPA devices
> >>> can be both physically located on the hardware or emulated by software.
> >>> This RFC introduce the vDPA support in qemu
> >>> TODO
> >>> 1) vIOMMU support
> >>> 2) live migration support
> >> This gives me the foggiest of ideas on what vDPA is.  Could we use
> >> docs/interop/vhost-vdpa.rst?
> >>
> > Sure will add this
> >
> >
>
> Not sure it's the best place since vhost-vdpa is kernel specific.
>
> Maybe kernel docs (TBD) is a better place and we can refer it this file
> in the future.
>
> But it doesn't harm if you said something more here and refer the kernel
> commit here:
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=4c8cf31885f69e86be0b5b9e6677a26797365e1d
>
> Thanks
>
>
Hi Markus,
I think I agree with Jason's opinion, kernel docs is a better place.
Maybe we can keep what it is now, and do this job in the future.

Thanks
Cindy



^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v1 02/10] vhost_net: use the function qemu_get_peer
  2020-06-22 15:37 ` [PATCH v1 02/10] vhost_net: use the function qemu_get_peer Cindy Lu
@ 2020-06-24 13:20   ` Laurent Vivier
  0 siblings, 0 replies; 46+ messages in thread
From: Laurent Vivier @ 2020-06-24 13:20 UTC (permalink / raw)
  To: Cindy Lu, mst, armbru, eblake, cohuck, jasowang
  Cc: mhabets, qemu-devel, rob.miller, saugatm, maxime.coquelin, hch,
	eperezma, jgg, shahafs, kevin.tian, parav, vmireyno,
	cunming.liang, gdawar, jiri, xiao.w.wang, stefanha, zhihong.wang,
	aadam, rdunlap, hanand, lingshan.zhu

On 22/06/2020 17:37, Cindy Lu wrote:
> user the qemu_get_peer to replace the old process
> 
> Signed-off-by: Cindy Lu <lulu@redhat.com>
> ---
>  hw/net/vhost_net.c | 16 ++++++++++------
>  1 file changed, 10 insertions(+), 6 deletions(-)
> 

Reviewed-by: Laurent Vivier <lvivier@redhat.com>



^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v1 04/10] virtio-pci: implement queue_enabled method
  2020-06-22 15:37 ` [PATCH v1 04/10] virtio-pci: implement " Cindy Lu
  2020-06-23  7:13   ` Jason Wang
@ 2020-06-24 13:24   ` Laurent Vivier
  2020-06-29  7:02     ` Cindy Lu
  1 sibling, 1 reply; 46+ messages in thread
From: Laurent Vivier @ 2020-06-24 13:24 UTC (permalink / raw)
  To: Cindy Lu, mst, armbru, eblake, cohuck, jasowang
  Cc: mhabets, qemu-devel, rob.miller, saugatm, maxime.coquelin, hch,
	eperezma, jgg, shahafs, kevin.tian, parav, vmireyno,
	cunming.liang, gdawar, jiri, xiao.w.wang, stefanha, zhihong.wang,
	aadam, rdunlap, hanand, lingshan.zhu

On 22/06/2020 17:37, Cindy Lu wrote:
> From: Jason Wang <jasowang@redhat.com>
> 
> With version 1, we can detect whether a queue is enabled via
> queue_enabled.
> 
> Signed-off-by: Jason Wang <jasowang@redhat.com>
> Signed-off-by: Cindy Lu <lulu@redhat.com>
> ---
>  hw/virtio/virtio-pci.c | 18 ++++++++++++++++++
>  1 file changed, 18 insertions(+)
> 
> diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
> index 4cb784389c..3918aa9f6c 100644
> --- a/hw/virtio/virtio-pci.c
> +++ b/hw/virtio/virtio-pci.c
> @@ -1107,6 +1107,23 @@ static AddressSpace *virtio_pci_get_dma_as(DeviceState *d)
>      return pci_get_address_space(dev);
>  }
>  
> +static bool  virtio_queue_check_enabled(VirtIODevice *vdev, int n)
> +{
> +    return  virtio_queue_get_desc_addr(vdev, n) != 0;
> +}

This function is already defined under a different name in
hw/virtio/virtio.c:


   3287 bool virtio_queue_enabled(VirtIODevice *vdev, int n)
   3288 {
   3289     return virtio_queue_get_desc_addr(vdev, n) != 0;
   3290 }

As this file includes "hw/virtio/virtio.h" you can use it directly.

Thanks,
Laurent



^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v1 00/10] vDPA support in qemu
  2020-06-24  9:42       ` Cindy Lu
@ 2020-06-25  4:48         ` Markus Armbruster
  2020-06-28  1:37           ` Cindy Lu
  0 siblings, 1 reply; 46+ messages in thread
From: Markus Armbruster @ 2020-06-25  4:48 UTC (permalink / raw)
  To: Cindy Lu
  Cc: rdunlap, Michael Tsirkin, Jason Wang, qemu-devel, Rob Miller,
	saugatm, Maxime Coquelin, hch, Eugenio Perez Martin, jgg,
	mhabets, Shahaf Shuler, kevin.tian, parav, Vitaly Mireyno, Liang,
	Cunming, gdawar, jiri, xiao.w.wang, Stefan Hajnoczi, Wang,
	Zhihong, Ariel Adam, Cornelia Huck, hanand, Zhu, Lingshan

Cindy Lu <lulu@redhat.com> writes:

> On Tue, Jun 23, 2020 at 5:43 PM Jason Wang <jasowang@redhat.com> wrote:
>>
>>
>> On 2020/6/23 下午5:16, Cindy Lu wrote:
>> > On Tue, Jun 23, 2020 at 3:07 PM Markus Armbruster <armbru@redhat.com> wrote:
>> >> Cindy Lu <lulu@redhat.com> writes:
>> >>
>> >>> vDPA device is a device that uses a datapath which complies with the
>> >>> virtio specifications with vendor specific control path. vDPA devices
>> >>> can be both physically located on the hardware or emulated by software.
>> >>> This RFC introduce the vDPA support in qemu
>> >>> TODO
>> >>> 1) vIOMMU support
>> >>> 2) live migration support
>> >> This gives me the foggiest of ideas on what vDPA is.  Could we use
>> >> docs/interop/vhost-vdpa.rst?
>> >>
>> > Sure will add this
>> >
>> >
>>
>> Not sure it's the best place since vhost-vdpa is kernel specific.
>>
>> Maybe kernel docs (TBD) is a better place and we can refer it this file
>> in the future.
>>
>> But it doesn't harm if you said something more here and refer the kernel
>> commit here:
>> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=4c8cf31885f69e86be0b5b9e6677a26797365e1d
>>
>> Thanks
>>
>>
> Hi Markus,
> I think I agree with Jason's opinion, kernel docs is a better place.
> Maybe we can keep what it is now, and do this job in the future.

I think a super-short description of vDPA here (one sentence?) together
with a link to complete information would be helpful.  If the link's
target doesn't yet exist, adding the link later is okay.



^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v1 09/10] vhost-vdpa: introduce vhost-vdpa backend
  2020-06-22 15:37 ` [PATCH v1 09/10] vhost-vdpa: introduce vhost-vdpa backend Cindy Lu
  2020-06-23  7:31   ` Jason Wang
@ 2020-06-25 12:36   ` Laurent Vivier
  2020-06-28  1:35     ` Cindy Lu
  2020-06-30  7:18   ` Maxime Coquelin
  2 siblings, 1 reply; 46+ messages in thread
From: Laurent Vivier @ 2020-06-25 12:36 UTC (permalink / raw)
  To: Cindy Lu, mst, armbru, eblake, cohuck, jasowang
  Cc: mhabets, qemu-devel, rob.miller, saugatm, maxime.coquelin, hch,
	eperezma, jgg, shahafs, kevin.tian, parav, vmireyno,
	cunming.liang, gdawar, jiri, xiao.w.wang, stefanha, zhihong.wang,
	Tiwei Bie, aadam, rdunlap, hanand, lingshan.zhu

On 22/06/2020 17:37, Cindy Lu wrote:
> Currently we have 2 types of vhost backends in QEMU: vhost kernel and
> vhost-user. The above patch provides a generic device for vDPA purpose,
> this vDPA device exposes to user space a non-vendor-specific configuration
> interface for setting up a vhost HW accelerator, this patch set introduces
> a third vhost backend called vhost-vdpa based on the vDPA interface.
> 
> Vhost-vdpa usage:
> 
> qemu-system-x86_64 -cpu host -enable-kvm \
>     ......
>     -netdev type=vhost-vdpa,vhostdev=/dev/vhost-vdpa-id,id=vhost-vdpa0 \
>     -device virtio-net-pci,netdev=vhost-vdpa0,page-per-vq=on \
> 
> Signed-off-by: Lingshan zhu <lingshan.zhu@intel.com>
> Signed-off-by: Tiwei Bie <tiwei.bie@intel.com>
> Signed-off-by: Cindy Lu <lulu@redhat.com>
> ---
>  configure                         |  21 ++
>  hw/net/vhost_net.c                |  19 +-
>  hw/net/virtio-net.c               |  19 +-
>  hw/virtio/Makefile.objs           |   1 +
>  hw/virtio/vhost-backend.c         |  22 +-
>  hw/virtio/vhost-vdpa.c            | 406 ++++++++++++++++++++++++++++++
>  hw/virtio/vhost.c                 |  42 +++-
>  include/hw/virtio/vhost-backend.h |   6 +-
>  include/hw/virtio/vhost-vdpa.h    |  26 ++
>  include/hw/virtio/vhost.h         |   6 +
>  qemu-options.hx                   |  12 +
>  11 files changed, 555 insertions(+), 25 deletions(-)
>  create mode 100644 hw/virtio/vhost-vdpa.c
>  create mode 100644 include/hw/virtio/vhost-vdpa.h
> 
...
> diff --git a/hw/virtio/vhost-backend.c b/hw/virtio/vhost-backend.c
> index 660e9e8588..84e5b1a833 100644
> --- a/hw/virtio/vhost-backend.c
> +++ b/hw/virtio/vhost-backend.c
> @@ -14,7 +14,7 @@
>  #include "qemu/error-report.h"
>  #include "qemu/main-loop.h"
>  #include "standard-headers/linux/vhost_types.h"
> -
> +#include "hw/virtio/vhost-vdpa.h"
>  #ifdef CONFIG_VHOST_KERNEL
>  #include <linux/vhost.h>
>  #include <sys/ioctl.h>
> @@ -22,10 +22,19 @@
>  static int vhost_kernel_call(struct vhost_dev *dev, unsigned long int request,
>                               void *arg)
>  {
> -    int fd = (uintptr_t) dev->opaque;
> -
> -    assert(dev->vhost_ops->backend_type == VHOST_BACKEND_TYPE_KERNEL);
> +    int fd = -1;

You don't need to initialize fd before the switch() because all cases
will set a value to it or assert.

> +    switch (dev->vhost_ops->backend_type) {
> +    case VHOST_BACKEND_TYPE_KERNEL:
> +        fd  = (uintptr_t)dev->opaque;
> +        break;
> +    case VHOST_BACKEND_TYPE_VDPA:
> +        fd = ((struct vhost_vdpa *)dev->opaque)->device_fd;
> +        break;
> +    default:
> +        g_assert_not_reached();
> +    }
>  
> +    assert(fd != -1);

Perhaps this assert is not needed:
Unitialized value will be catched by "default:", and there was no such
kind of check on "(uintptr_t)dev->opaque" before.

Thanks,
Laurent



^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v1 08/10] vhost: implement vhost_dev_start method
  2020-06-22 15:37 ` [PATCH v1 08/10] vhost: implement vhost_dev_start method Cindy Lu
  2020-06-23  7:21   ` Jason Wang
@ 2020-06-25 14:35   ` Laurent Vivier
  2020-06-29  7:01     ` Cindy Lu
  1 sibling, 1 reply; 46+ messages in thread
From: Laurent Vivier @ 2020-06-25 14:35 UTC (permalink / raw)
  To: Cindy Lu, mst, armbru, eblake, cohuck, jasowang
  Cc: mhabets, qemu-devel, rob.miller, saugatm, maxime.coquelin, hch,
	eperezma, jgg, shahafs, kevin.tian, parav, vmireyno,
	cunming.liang, gdawar, jiri, xiao.w.wang, stefanha, zhihong.wang,
	aadam, rdunlap, hanand, lingshan.zhu

On 22/06/2020 17:37, Cindy Lu wrote:
> use the vhost_dev_start callback to send the status to backend

I agree with Jason, squash this patch with the previous one.

> Signed-off-by: Cindy Lu <lulu@redhat.com>
> ---
>  hw/virtio/vhost.c         | 17 +++++++++++++++++
>  include/hw/virtio/vhost.h |  2 ++
>  2 files changed, 19 insertions(+)
> 
> diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
> index 01ebe12f28..bfd7f9ce1f 100644
> --- a/hw/virtio/vhost.c
> +++ b/hw/virtio/vhost.c
> @@ -744,6 +744,7 @@ static void vhost_iommu_region_del(MemoryListener *listener,
>      }
>  }
>  
> +
>  static int vhost_virtqueue_set_addr(struct vhost_dev *dev,
>                                      struct vhost_virtqueue *vq,
>                                      unsigned idx, bool enable_log)
> @@ -1661,6 +1662,11 @@ int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev)
>          }
>      }
>  
> +    r = vhost_set_start(hdev, true);

Perhaps you can use the same kind of name we have for the queue
(queue_set_started()) and use something like vhost_dev_set_started()?

> +    if (r) {
> +        goto fail_log;
> +    }
> +
>      if (vhost_dev_has_iommu(hdev)) {
>          hdev->vhost_ops->vhost_set_iotlb_callback(hdev, true);
>  
> @@ -1697,6 +1703,8 @@ void vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev)
>      /* should only be called after backend is connected */
>      assert(hdev->vhost_ops);
>  
> +    vhost_set_start(hdev, false);
> +
>      for (i = 0; i < hdev->nvqs; ++i) {
>          vhost_virtqueue_stop(hdev,
>                               vdev,
> @@ -1722,3 +1730,12 @@ int vhost_net_set_backend(struct vhost_dev *hdev,
>  
>      return -1;
>  }
> +
> +int vhost_set_start(struct vhost_dev *hdev, bool started)
> +{
> +
> +    if (hdev->vhost_ops->vhost_dev_start) {
> +        hdev->vhost_ops->vhost_dev_start(hdev, started);

The "return" is missing.

And generally a function that only embeds a call to a hook has the same
as the hook.

> +    }
> +    return 0;
> +}

so something like:

    int vhost_dev_set_started(struct vhost_dev *hdev, bool started)
    {
        if (hdev->vhost_ops->dev_set_started) {
            return hdev->vhost_ops->dev_set_started(hdev, started);
        }
        return 0;
    }


> diff --git a/include/hw/virtio/vhost.h b/include/hw/virtio/vhost.h
> index 085450c6f8..59ea53f8c2 100644
> --- a/include/hw/virtio/vhost.h
> +++ b/include/hw/virtio/vhost.h
> @@ -92,6 +92,7 @@ struct vhost_dev {
>      const VhostDevConfigOps *config_ops;
>  };
>  
> +
>  int vhost_dev_init(struct vhost_dev *hdev, void *opaque,
>                     VhostBackendType backend_type,
>                     uint32_t busyloop_timeout);
> @@ -137,4 +138,5 @@ int vhost_dev_set_inflight(struct vhost_dev *dev,
>                             struct vhost_inflight *inflight);
>  int vhost_dev_get_inflight(struct vhost_dev *dev, uint16_t queue_size,
>                             struct vhost_inflight *inflight);
> +int vhost_set_start(struct vhost_dev *dev, bool started);

There is no need to export it, so set it "static" in hw/virtio/vhost.c
and move the definition before the use.

Thanks,
Laurent



^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v1 05/10] vhost-backend: export the vhost backend helper
  2020-06-22 15:37 ` [PATCH v1 05/10] vhost-backend: export the vhost backend helper Cindy Lu
@ 2020-06-25 15:07   ` Laurent Vivier
  2020-06-30  6:27     ` Cindy Lu
  0 siblings, 1 reply; 46+ messages in thread
From: Laurent Vivier @ 2020-06-25 15:07 UTC (permalink / raw)
  To: Cindy Lu, mst, armbru, eblake, cohuck, jasowang
  Cc: mhabets, qemu-devel, rob.miller, saugatm, maxime.coquelin, hch,
	eperezma, jgg, shahafs, kevin.tian, parav, vmireyno,
	cunming.liang, gdawar, jiri, xiao.w.wang, stefanha, zhihong.wang,
	aadam, rdunlap, hanand, lingshan.zhu

On 22/06/2020 17:37, Cindy Lu wrote:
> export the helper then we can reuse them in other backend
> 
> Signed-off-by: Cindy Lu <lulu@redhat.com>
> ---
>  hw/virtio/vhost-backend.c         | 18 +++++++++---------
>  include/hw/virtio/vhost-backend.h | 28 ++++++++++++++++++++++++++++
>  2 files changed, 37 insertions(+), 9 deletions(-)
> 

This looks weird to export all these functions whereas they are all
already exported by the vhost_ops structure.

So if vhost-vdpa is not a subset of vhost-kernel and if these functions
will diverge from vhost-backend.c definition in the future, perhaps it
is wise to already copy their definitions right now in vhost-vdpa.c
rather than exporting them now and to have to copy them in the future in
vhost-vdpa.c to modify them.

It will also simplify the definition of vhost_kernel_call().

Thanks,
Laurent

> diff --git a/hw/virtio/vhost-backend.c b/hw/virtio/vhost-backend.c
> index 48905383f8..660e9e8588 100644
> --- a/hw/virtio/vhost-backend.c
> +++ b/hw/virtio/vhost-backend.c
> @@ -89,7 +89,7 @@ static int vhost_kernel_scsi_get_abi_version(struct vhost_dev *dev, int *version
>      return vhost_kernel_call(dev, VHOST_SCSI_GET_ABI_VERSION, version);
>  }
>  
> -static int vhost_kernel_set_log_base(struct vhost_dev *dev, uint64_t base,
> +int vhost_kernel_set_log_base(struct vhost_dev *dev, uint64_t base,
>                                       struct vhost_log *log)
>  {
>      return vhost_kernel_call(dev, VHOST_SET_LOG_BASE, &base);
> @@ -101,7 +101,7 @@ static int vhost_kernel_set_mem_table(struct vhost_dev *dev,
>      return vhost_kernel_call(dev, VHOST_SET_MEM_TABLE, mem);
>  }
>  
> -static int vhost_kernel_set_vring_addr(struct vhost_dev *dev,
> +int vhost_kernel_set_vring_addr(struct vhost_dev *dev,
>                                         struct vhost_vring_addr *addr)
>  {
>      return vhost_kernel_call(dev, VHOST_SET_VRING_ADDR, addr);
> @@ -113,31 +113,31 @@ static int vhost_kernel_set_vring_endian(struct vhost_dev *dev,
>      return vhost_kernel_call(dev, VHOST_SET_VRING_ENDIAN, ring);
>  }
>  
> -static int vhost_kernel_set_vring_num(struct vhost_dev *dev,
> +int vhost_kernel_set_vring_num(struct vhost_dev *dev,
>                                        struct vhost_vring_state *ring)
>  {
>      return vhost_kernel_call(dev, VHOST_SET_VRING_NUM, ring);
>  }
>  
> -static int vhost_kernel_set_vring_base(struct vhost_dev *dev,
> +int vhost_kernel_set_vring_base(struct vhost_dev *dev,
>                                         struct vhost_vring_state *ring)
>  {
>      return vhost_kernel_call(dev, VHOST_SET_VRING_BASE, ring);
>  }
>  
> -static int vhost_kernel_get_vring_base(struct vhost_dev *dev,
> +int vhost_kernel_get_vring_base(struct vhost_dev *dev,
>                                         struct vhost_vring_state *ring)
>  {
>      return vhost_kernel_call(dev, VHOST_GET_VRING_BASE, ring);
>  }
>  
> -static int vhost_kernel_set_vring_kick(struct vhost_dev *dev,
> +int vhost_kernel_set_vring_kick(struct vhost_dev *dev,
>                                         struct vhost_vring_file *file)
>  {
>      return vhost_kernel_call(dev, VHOST_SET_VRING_KICK, file);
>  }
>  
> -static int vhost_kernel_set_vring_call(struct vhost_dev *dev,
> +int vhost_kernel_set_vring_call(struct vhost_dev *dev,
>                                         struct vhost_vring_file *file)
>  {
>      return vhost_kernel_call(dev, VHOST_SET_VRING_CALL, file);
> @@ -155,13 +155,13 @@ static int vhost_kernel_set_features(struct vhost_dev *dev,
>      return vhost_kernel_call(dev, VHOST_SET_FEATURES, &features);
>  }
>  
> -static int vhost_kernel_get_features(struct vhost_dev *dev,
> +int vhost_kernel_get_features(struct vhost_dev *dev,
>                                       uint64_t *features)
>  {
>      return vhost_kernel_call(dev, VHOST_GET_FEATURES, features);
>  }
>  
> -static int vhost_kernel_set_owner(struct vhost_dev *dev)
> +int vhost_kernel_set_owner(struct vhost_dev *dev)
>  {
>      return vhost_kernel_call(dev, VHOST_SET_OWNER, NULL);
>  }
> diff --git a/include/hw/virtio/vhost-backend.h b/include/hw/virtio/vhost-backend.h
> index 6f6670783f..300b59c172 100644
> --- a/include/hw/virtio/vhost-backend.h
> +++ b/include/hw/virtio/vhost-backend.h
> @@ -172,4 +172,32 @@ int vhost_backend_handle_iotlb_msg(struct vhost_dev *dev,
>  
>  int vhost_user_gpu_set_socket(struct vhost_dev *dev, int fd);
>  
> +
> +int vhost_kernel_set_log_base(struct vhost_dev *dev, uint64_t base,
> +                                     struct vhost_log *log);
> +
> +int vhost_kernel_set_vring_addr(struct vhost_dev *dev,
> +                                       struct vhost_vring_addr *addr);
> +
> +int vhost_kernel_set_vring_num(struct vhost_dev *dev,
> +                                      struct vhost_vring_state *ring);
> +
> +int vhost_kernel_set_vring_base(struct vhost_dev *dev,
> +                                       struct vhost_vring_state *ring);
> +
> +int vhost_kernel_get_vring_base(struct vhost_dev *dev,
> +                                       struct vhost_vring_state *ring);
> +
> +int vhost_kernel_set_vring_kick(struct vhost_dev *dev,
> +                                       struct vhost_vring_file *file);
> +
> +int vhost_kernel_set_vring_call(struct vhost_dev *dev,
> +                                       struct vhost_vring_file *file);
> +
> +int vhost_kernel_set_owner(struct vhost_dev *dev);
> +
> +int vhost_kernel_get_features(struct vhost_dev *dev,
> +                                     uint64_t *features);
> +
> +
>  #endif /* VHOST_BACKEND_H */
> 



^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v1 09/10] vhost-vdpa: introduce vhost-vdpa backend
  2020-06-25 12:36   ` Laurent Vivier
@ 2020-06-28  1:35     ` Cindy Lu
  0 siblings, 0 replies; 46+ messages in thread
From: Cindy Lu @ 2020-06-28  1:35 UTC (permalink / raw)
  To: Laurent Vivier
  Cc: rdunlap, Michael Tsirkin, mhabets, qemu-devel, Rob Miller,
	saugatm, Markus Armbruster, hch, Eugenio Perez Martin, jgg,
	Jason Wang, Shahaf Shuler, kevin.tian, parav, Vitaly Mireyno,
	Liang, Cunming, gdawar, jiri, xiao.w.wang, Stefan Hajnoczi, Wang,
	Zhihong, Maxime Coquelin, Tiwei Bie, Ariel Adam, Cornelia Huck,
	hanand, Zhu, Lingshan

On Thu, Jun 25, 2020 at 8:37 PM Laurent Vivier <lvivier@redhat.com> wrote:
>
> On 22/06/2020 17:37, Cindy Lu wrote:
> > Currently we have 2 types of vhost backends in QEMU: vhost kernel and
> > vhost-user. The above patch provides a generic device for vDPA purpose,
> > this vDPA device exposes to user space a non-vendor-specific configuration
> > interface for setting up a vhost HW accelerator, this patch set introduces
> > a third vhost backend called vhost-vdpa based on the vDPA interface.
> >
> > Vhost-vdpa usage:
> >
> > qemu-system-x86_64 -cpu host -enable-kvm \
> >     ......
> >     -netdev type=vhost-vdpa,vhostdev=/dev/vhost-vdpa-id,id=vhost-vdpa0 \
> >     -device virtio-net-pci,netdev=vhost-vdpa0,page-per-vq=on \
> >
> > Signed-off-by: Lingshan zhu <lingshan.zhu@intel.com>
> > Signed-off-by: Tiwei Bie <tiwei.bie@intel.com>
> > Signed-off-by: Cindy Lu <lulu@redhat.com>
> > ---
> >  configure                         |  21 ++
> >  hw/net/vhost_net.c                |  19 +-
> >  hw/net/virtio-net.c               |  19 +-
> >  hw/virtio/Makefile.objs           |   1 +
> >  hw/virtio/vhost-backend.c         |  22 +-
> >  hw/virtio/vhost-vdpa.c            | 406 ++++++++++++++++++++++++++++++
> >  hw/virtio/vhost.c                 |  42 +++-
> >  include/hw/virtio/vhost-backend.h |   6 +-
> >  include/hw/virtio/vhost-vdpa.h    |  26 ++
> >  include/hw/virtio/vhost.h         |   6 +
> >  qemu-options.hx                   |  12 +
> >  11 files changed, 555 insertions(+), 25 deletions(-)
> >  create mode 100644 hw/virtio/vhost-vdpa.c
> >  create mode 100644 include/hw/virtio/vhost-vdpa.h
> >
> ...
> > diff --git a/hw/virtio/vhost-backend.c b/hw/virtio/vhost-backend.c
> > index 660e9e8588..84e5b1a833 100644
> > --- a/hw/virtio/vhost-backend.c
> > +++ b/hw/virtio/vhost-backend.c
> > @@ -14,7 +14,7 @@
> >  #include "qemu/error-report.h"
> >  #include "qemu/main-loop.h"
> >  #include "standard-headers/linux/vhost_types.h"
> > -
> > +#include "hw/virtio/vhost-vdpa.h"
> >  #ifdef CONFIG_VHOST_KERNEL
> >  #include <linux/vhost.h>
> >  #include <sys/ioctl.h>
> > @@ -22,10 +22,19 @@
> >  static int vhost_kernel_call(struct vhost_dev *dev, unsigned long int request,
> >                               void *arg)
> >  {
> > -    int fd = (uintptr_t) dev->opaque;
> > -
> > -    assert(dev->vhost_ops->backend_type == VHOST_BACKEND_TYPE_KERNEL);
> > +    int fd = -1;
>
> You don't need to initialize fd before the switch() because all cases
> will set a value to it or assert.
>
> > +    switch (dev->vhost_ops->backend_type) {
> > +    case VHOST_BACKEND_TYPE_KERNEL:
> > +        fd  = (uintptr_t)dev->opaque;
> > +        break;
> > +    case VHOST_BACKEND_TYPE_VDPA:
> > +        fd = ((struct vhost_vdpa *)dev->opaque)->device_fd;
> > +        break;
> > +    default:
> > +        g_assert_not_reached();
> > +    }
> >
> > +    assert(fd != -1);
>
> Perhaps this assert is not needed:
> Unitialized value will be catched by "default:", and there was no such
> kind of check on "(uintptr_t)dev->opaque" before.
>
sure, thanks will fix this
> Thanks,
> Laurent
>



^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v1 00/10] vDPA support in qemu
  2020-06-25  4:48         ` Markus Armbruster
@ 2020-06-28  1:37           ` Cindy Lu
  0 siblings, 0 replies; 46+ messages in thread
From: Cindy Lu @ 2020-06-28  1:37 UTC (permalink / raw)
  To: Markus Armbruster
  Cc: rdunlap, Michael Tsirkin, Jason Wang, qemu-devel, Rob Miller,
	saugatm, Maxime Coquelin, hch, Eugenio Perez Martin, jgg,
	mhabets, Shahaf Shuler, kevin.tian, parav, Vitaly Mireyno, Liang,
	Cunming, gdawar, jiri, xiao.w.wang, Stefan Hajnoczi, Wang,
	Zhihong, Ariel Adam, Cornelia Huck, hanand, Zhu, Lingshan

On Thu, Jun 25, 2020 at 12:48 PM Markus Armbruster <armbru@redhat.com> wrote:
>
> Cindy Lu <lulu@redhat.com> writes:
>
> > On Tue, Jun 23, 2020 at 5:43 PM Jason Wang <jasowang@redhat.com> wrote:
> >>
> >>
> >> On 2020/6/23 下午5:16, Cindy Lu wrote:
> >> > On Tue, Jun 23, 2020 at 3:07 PM Markus Armbruster <armbru@redhat.com> wrote:
> >> >> Cindy Lu <lulu@redhat.com> writes:
> >> >>
> >> >>> vDPA device is a device that uses a datapath which complies with the
> >> >>> virtio specifications with vendor specific control path. vDPA devices
> >> >>> can be both physically located on the hardware or emulated by software.
> >> >>> This RFC introduce the vDPA support in qemu
> >> >>> TODO
> >> >>> 1) vIOMMU support
> >> >>> 2) live migration support
> >> >> This gives me the foggiest of ideas on what vDPA is.  Could we use
> >> >> docs/interop/vhost-vdpa.rst?
> >> >>
> >> > Sure will add this
> >> >
> >> >
> >>
> >> Not sure it's the best place since vhost-vdpa is kernel specific.
> >>
> >> Maybe kernel docs (TBD) is a better place and we can refer it this file
> >> in the future.
> >>
> >> But it doesn't harm if you said something more here and refer the kernel
> >> commit here:
> >> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=4c8cf31885f69e86be0b5b9e6677a26797365e1d
> >>
> >> Thanks
> >>
> >>
> > Hi Markus,
> > I think I agree with Jason's opinion, kernel docs is a better place.
> > Maybe we can keep what it is now, and do this job in the future.
>
> I think a super-short description of vDPA here (one sentence?) together
> with a link to complete information would be helpful.  If the link's
> target doesn't yet exist, adding the link later is okay.
>
sure thanks Markus, will do



^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v1 00/10] vDPA support in qemu
  2020-06-22 15:37 [PATCH v1 00/10] vDPA support in qemu Cindy Lu
                   ` (10 preceding siblings ...)
  2020-06-23  7:07 ` [PATCH v1 00/10] vDPA support in qemu Markus Armbruster
@ 2020-06-28  7:06 ` Jason Wang
  2020-06-28  8:19   ` Cindy Lu
  11 siblings, 1 reply; 46+ messages in thread
From: Jason Wang @ 2020-06-28  7:06 UTC (permalink / raw)
  To: Cindy Lu, mst, armbru, eblake, cohuck
  Cc: mhabets, qemu-devel, rob.miller, saugatm, hanand, hch, eperezma,
	jgg, shahafs, kevin.tian, parav, vmireyno, cunming.liang, gdawar,
	jiri, xiao.w.wang, stefanha, zhihong.wang, aadam, rdunlap,
	maxime.coquelin, lingshan.zhu


On 2020/6/22 下午11:37, Cindy Lu wrote:
> vDPA device is a device that uses a datapath which complies with the
> virtio specifications with vendor specific control path. vDPA devices
> can be both physically located on the hardware or emulated by software.
> This RFC introduce the vDPA support in qemu
> TODO
> 1) vIOMMU support
> 2) live migration support


Jut notice that the config interrupt [1] looks missed in this series.

Please add them in next version.

Thanks

[1] 
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=776f395004d829bbbf18c159ed9beb517a208c71



^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v1 00/10] vDPA support in qemu
  2020-06-28  7:06 ` Jason Wang
@ 2020-06-28  8:19   ` Cindy Lu
  0 siblings, 0 replies; 46+ messages in thread
From: Cindy Lu @ 2020-06-28  8:19 UTC (permalink / raw)
  To: Jason Wang
  Cc: Cornelia Huck, Michael Tsirkin, mhabets, qemu-devel, hanand,
	Rob Miller, saugatm, Markus Armbruster, hch,
	Eugenio Perez Martin, jgg, Shahaf Shuler, kevin.tian, parav,
	Vitaly Mireyno, Liang, Cunming, gdawar, jiri, xiao.w.wang,
	Stefan Hajnoczi, Wang, Zhihong, Ariel Adam, rdunlap,
	Maxime Coquelin, Zhu, Lingshan

On Sun, Jun 28, 2020 at 3:07 PM Jason Wang <jasowang@redhat.com> wrote:
>
>
> On 2020/6/22 下午11:37, Cindy Lu wrote:
> > vDPA device is a device that uses a datapath which complies with the
> > virtio specifications with vendor specific control path. vDPA devices
> > can be both physically located on the hardware or emulated by software.
> > This RFC introduce the vDPA support in qemu
> > TODO
> > 1) vIOMMU support
> > 2) live migration support
>
>
> Jut notice that the config interrupt [1] looks missed in this series.
>
> Please add them in next version.
>
> Thanks
>
> [1]
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=776f395004d829bbbf18c159ed9beb517a208c71
>
sure will add this part



^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v1 08/10] vhost: implement vhost_dev_start method
  2020-06-25 14:35   ` Laurent Vivier
@ 2020-06-29  7:01     ` Cindy Lu
  0 siblings, 0 replies; 46+ messages in thread
From: Cindy Lu @ 2020-06-29  7:01 UTC (permalink / raw)
  To: Laurent Vivier
  Cc: rdunlap, Michael Tsirkin, mhabets, qemu-devel, Rob Miller,
	saugatm, Markus Armbruster, hch, Eugenio Perez Martin, jgg,
	Jason Wang, Shahaf Shuler, kevin.tian, parav, Vitaly Mireyno,
	Liang, Cunming, gdawar, jiri, xiao.w.wang, Stefan Hajnoczi, Wang,
	Zhihong, Maxime Coquelin, Ariel Adam, Cornelia Huck, hanand, Zhu,
	Lingshan

On Thu, Jun 25, 2020 at 10:35 PM Laurent Vivier <lvivier@redhat.com> wrote:
>
> On 22/06/2020 17:37, Cindy Lu wrote:
> > use the vhost_dev_start callback to send the status to backend
>
> I agree with Jason, squash this patch with the previous one.
>
will fix this
> > Signed-off-by: Cindy Lu <lulu@redhat.com>
> > ---
> >  hw/virtio/vhost.c         | 17 +++++++++++++++++
> >  include/hw/virtio/vhost.h |  2 ++
> >  2 files changed, 19 insertions(+)
> >
> > diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
> > index 01ebe12f28..bfd7f9ce1f 100644
> > --- a/hw/virtio/vhost.c
> > +++ b/hw/virtio/vhost.c
> > @@ -744,6 +744,7 @@ static void vhost_iommu_region_del(MemoryListener *listener,
> >      }
> >  }
> >
> > +
> >  static int vhost_virtqueue_set_addr(struct vhost_dev *dev,
> >                                      struct vhost_virtqueue *vq,
> >                                      unsigned idx, bool enable_log)
> > @@ -1661,6 +1662,11 @@ int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev)
> >          }
> >      }
> >
> > +    r = vhost_set_start(hdev, true);
>
> Perhaps you can use the same kind of name we have for the queue
> (queue_set_started()) and use something like vhost_dev_set_started()?
>
sure, will fix this
> > +    if (r) {
> > +        goto fail_log;
> > +    }
> > +
> >      if (vhost_dev_has_iommu(hdev)) {
> >          hdev->vhost_ops->vhost_set_iotlb_callback(hdev, true);
> >
> > @@ -1697,6 +1703,8 @@ void vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev)
> >      /* should only be called after backend is connected */
> >      assert(hdev->vhost_ops);
> >
> > +    vhost_set_start(hdev, false);
> > +
> >      for (i = 0; i < hdev->nvqs; ++i) {
> >          vhost_virtqueue_stop(hdev,
> >                               vdev,
> > @@ -1722,3 +1730,12 @@ int vhost_net_set_backend(struct vhost_dev *hdev,
> >
> >      return -1;
> >  }
> > +
> > +int vhost_set_start(struct vhost_dev *hdev, bool started)
> > +{
> > +
> > +    if (hdev->vhost_ops->vhost_dev_start) {
> > +        hdev->vhost_ops->vhost_dev_start(hdev, started);
>
> The "return" is missing.
>
> And generally a function that only embeds a call to a hook has the same
> as the hook.
>
> > +    }
> > +    return 0;
> > +}
>
> so something like:
>
>     int vhost_dev_set_started(struct vhost_dev *hdev, bool started)
>     {
>         if (hdev->vhost_ops->dev_set_started) {
>             return hdev->vhost_ops->dev_set_started(hdev, started);
>         }
>         return 0;
>     }
>
>
thanks will fix this
> > diff --git a/include/hw/virtio/vhost.h b/include/hw/virtio/vhost.h
> > index 085450c6f8..59ea53f8c2 100644
> > --- a/include/hw/virtio/vhost.h
> > +++ b/include/hw/virtio/vhost.h
> > @@ -92,6 +92,7 @@ struct vhost_dev {
> >      const VhostDevConfigOps *config_ops;
> >  };
> >
> > +
> >  int vhost_dev_init(struct vhost_dev *hdev, void *opaque,
> >                     VhostBackendType backend_type,
> >                     uint32_t busyloop_timeout);
> > @@ -137,4 +138,5 @@ int vhost_dev_set_inflight(struct vhost_dev *dev,
> >                             struct vhost_inflight *inflight);
> >  int vhost_dev_get_inflight(struct vhost_dev *dev, uint16_t queue_size,
> >                             struct vhost_inflight *inflight);
> > +int vhost_set_start(struct vhost_dev *dev, bool started);
>
> There is no need to export it, so set it "static" in hw/virtio/vhost.c
> and move the definition before the use.
>
thanks will fix this
> Thanks,
> Laurent
>



^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v1 04/10] virtio-pci: implement queue_enabled method
  2020-06-24 13:24   ` Laurent Vivier
@ 2020-06-29  7:02     ` Cindy Lu
  0 siblings, 0 replies; 46+ messages in thread
From: Cindy Lu @ 2020-06-29  7:02 UTC (permalink / raw)
  To: Laurent Vivier
  Cc: rdunlap, Michael Tsirkin, mhabets, qemu-devel, Rob Miller,
	saugatm, Markus Armbruster, hch, Eugenio Perez Martin, jgg,
	Jason Wang, Shahaf Shuler, kevin.tian, parav, Vitaly Mireyno,
	Liang, Cunming, gdawar, jiri, xiao.w.wang, Stefan Hajnoczi, Wang,
	Zhihong, Maxime Coquelin, Ariel Adam, Cornelia Huck, hanand, Zhu,
	Lingshan

On Wed, Jun 24, 2020 at 9:25 PM Laurent Vivier <lvivier@redhat.com> wrote:
>
> On 22/06/2020 17:37, Cindy Lu wrote:
> > From: Jason Wang <jasowang@redhat.com>
> >
> > With version 1, we can detect whether a queue is enabled via
> > queue_enabled.
> >
> > Signed-off-by: Jason Wang <jasowang@redhat.com>
> > Signed-off-by: Cindy Lu <lulu@redhat.com>
> > ---
> >  hw/virtio/virtio-pci.c | 18 ++++++++++++++++++
> >  1 file changed, 18 insertions(+)
> >
> > diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
> > index 4cb784389c..3918aa9f6c 100644
> > --- a/hw/virtio/virtio-pci.c
> > +++ b/hw/virtio/virtio-pci.c
> > @@ -1107,6 +1107,23 @@ static AddressSpace *virtio_pci_get_dma_as(DeviceState *d)
> >      return pci_get_address_space(dev);
> >  }
> >
> > +static bool  virtio_queue_check_enabled(VirtIODevice *vdev, int n)
> > +{
> > +    return  virtio_queue_get_desc_addr(vdev, n) != 0;
> > +}
>
> This function is already defined under a different name in
> hw/virtio/virtio.c:
>
>
>    3287 bool virtio_queue_enabled(VirtIODevice *vdev, int n)
>    3288 {
>    3289     return virtio_queue_get_desc_addr(vdev, n) != 0;
>    3290 }
>
> As this file includes "hw/virtio/virtio.h" you can use it directly.
>
Thanks Laurent, Will fix this
> Thanks,
> Laurent
>



^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v1 05/10] vhost-backend: export the vhost backend helper
  2020-06-25 15:07   ` Laurent Vivier
@ 2020-06-30  6:27     ` Cindy Lu
  0 siblings, 0 replies; 46+ messages in thread
From: Cindy Lu @ 2020-06-30  6:27 UTC (permalink / raw)
  To: Laurent Vivier
  Cc: rdunlap, Michael Tsirkin, mhabets, qemu-devel, Rob Miller,
	saugatm, Markus Armbruster, hch, Eugenio Perez Martin, jgg,
	Jason Wang, Shahaf Shuler, kevin.tian, parav, Vitaly Mireyno,
	Liang, Cunming, gdawar, jiri, xiao.w.wang, Stefan Hajnoczi, Wang,
	Zhihong, Maxime Coquelin, Ariel Adam, Cornelia Huck, hanand, Zhu,
	Lingshan

On Thu, Jun 25, 2020 at 11:07 PM Laurent Vivier <lvivier@redhat.com> wrote:
>
> On 22/06/2020 17:37, Cindy Lu wrote:
> > export the helper then we can reuse them in other backend
> >
> > Signed-off-by: Cindy Lu <lulu@redhat.com>
> > ---
> >  hw/virtio/vhost-backend.c         | 18 +++++++++---------
> >  include/hw/virtio/vhost-backend.h | 28 ++++++++++++++++++++++++++++
> >  2 files changed, 37 insertions(+), 9 deletions(-)
> >
>
> This looks weird to export all these functions whereas they are all
> already exported by the vhost_ops structure.
>
> So if vhost-vdpa is not a subset of vhost-kernel and if these functions
> will diverge from vhost-backend.c definition in the future, perhaps it
> is wise to already copy their definitions right now in vhost-vdpa.c
> rather than exporting them now and to have to copy them in the future in
> vhost-vdpa.c to modify them.
>
> It will also simplify the definition of vhost_kernel_call().
>
> Thanks,
> Laurent
>
Thanks Laurent, will fix this
> > diff --git a/hw/virtio/vhost-backend.c b/hw/virtio/vhost-backend.c
> > index 48905383f8..660e9e8588 100644
> > --- a/hw/virtio/vhost-backend.c
> > +++ b/hw/virtio/vhost-backend.c
> > @@ -89,7 +89,7 @@ static int vhost_kernel_scsi_get_abi_version(struct vhost_dev *dev, int *version
> >      return vhost_kernel_call(dev, VHOST_SCSI_GET_ABI_VERSION, version);
> >  }
> >
> > -static int vhost_kernel_set_log_base(struct vhost_dev *dev, uint64_t base,
> > +int vhost_kernel_set_log_base(struct vhost_dev *dev, uint64_t base,
> >                                       struct vhost_log *log)
> >  {
> >      return vhost_kernel_call(dev, VHOST_SET_LOG_BASE, &base);
> > @@ -101,7 +101,7 @@ static int vhost_kernel_set_mem_table(struct vhost_dev *dev,
> >      return vhost_kernel_call(dev, VHOST_SET_MEM_TABLE, mem);
> >  }
> >
> > -static int vhost_kernel_set_vring_addr(struct vhost_dev *dev,
> > +int vhost_kernel_set_vring_addr(struct vhost_dev *dev,
> >                                         struct vhost_vring_addr *addr)
> >  {
> >      return vhost_kernel_call(dev, VHOST_SET_VRING_ADDR, addr);
> > @@ -113,31 +113,31 @@ static int vhost_kernel_set_vring_endian(struct vhost_dev *dev,
> >      return vhost_kernel_call(dev, VHOST_SET_VRING_ENDIAN, ring);
> >  }
> >
> > -static int vhost_kernel_set_vring_num(struct vhost_dev *dev,
> > +int vhost_kernel_set_vring_num(struct vhost_dev *dev,
> >                                        struct vhost_vring_state *ring)
> >  {
> >      return vhost_kernel_call(dev, VHOST_SET_VRING_NUM, ring);
> >  }
> >
> > -static int vhost_kernel_set_vring_base(struct vhost_dev *dev,
> > +int vhost_kernel_set_vring_base(struct vhost_dev *dev,
> >                                         struct vhost_vring_state *ring)
> >  {
> >      return vhost_kernel_call(dev, VHOST_SET_VRING_BASE, ring);
> >  }
> >
> > -static int vhost_kernel_get_vring_base(struct vhost_dev *dev,
> > +int vhost_kernel_get_vring_base(struct vhost_dev *dev,
> >                                         struct vhost_vring_state *ring)
> >  {
> >      return vhost_kernel_call(dev, VHOST_GET_VRING_BASE, ring);
> >  }
> >
> > -static int vhost_kernel_set_vring_kick(struct vhost_dev *dev,
> > +int vhost_kernel_set_vring_kick(struct vhost_dev *dev,
> >                                         struct vhost_vring_file *file)
> >  {
> >      return vhost_kernel_call(dev, VHOST_SET_VRING_KICK, file);
> >  }
> >
> > -static int vhost_kernel_set_vring_call(struct vhost_dev *dev,
> > +int vhost_kernel_set_vring_call(struct vhost_dev *dev,
> >                                         struct vhost_vring_file *file)
> >  {
> >      return vhost_kernel_call(dev, VHOST_SET_VRING_CALL, file);
> > @@ -155,13 +155,13 @@ static int vhost_kernel_set_features(struct vhost_dev *dev,
> >      return vhost_kernel_call(dev, VHOST_SET_FEATURES, &features);
> >  }
> >
> > -static int vhost_kernel_get_features(struct vhost_dev *dev,
> > +int vhost_kernel_get_features(struct vhost_dev *dev,
> >                                       uint64_t *features)
> >  {
> >      return vhost_kernel_call(dev, VHOST_GET_FEATURES, features);
> >  }
> >
> > -static int vhost_kernel_set_owner(struct vhost_dev *dev)
> > +int vhost_kernel_set_owner(struct vhost_dev *dev)
> >  {
> >      return vhost_kernel_call(dev, VHOST_SET_OWNER, NULL);
> >  }
> > diff --git a/include/hw/virtio/vhost-backend.h b/include/hw/virtio/vhost-backend.h
> > index 6f6670783f..300b59c172 100644
> > --- a/include/hw/virtio/vhost-backend.h
> > +++ b/include/hw/virtio/vhost-backend.h
> > @@ -172,4 +172,32 @@ int vhost_backend_handle_iotlb_msg(struct vhost_dev *dev,
> >
> >  int vhost_user_gpu_set_socket(struct vhost_dev *dev, int fd);
> >
> > +
> > +int vhost_kernel_set_log_base(struct vhost_dev *dev, uint64_t base,
> > +                                     struct vhost_log *log);
> > +
> > +int vhost_kernel_set_vring_addr(struct vhost_dev *dev,
> > +                                       struct vhost_vring_addr *addr);
> > +
> > +int vhost_kernel_set_vring_num(struct vhost_dev *dev,
> > +                                      struct vhost_vring_state *ring);
> > +
> > +int vhost_kernel_set_vring_base(struct vhost_dev *dev,
> > +                                       struct vhost_vring_state *ring);
> > +
> > +int vhost_kernel_get_vring_base(struct vhost_dev *dev,
> > +                                       struct vhost_vring_state *ring);
> > +
> > +int vhost_kernel_set_vring_kick(struct vhost_dev *dev,
> > +                                       struct vhost_vring_file *file);
> > +
> > +int vhost_kernel_set_vring_call(struct vhost_dev *dev,
> > +                                       struct vhost_vring_file *file);
> > +
> > +int vhost_kernel_set_owner(struct vhost_dev *dev);
> > +
> > +int vhost_kernel_get_features(struct vhost_dev *dev,
> > +                                     uint64_t *features);
> > +
> > +
> >  #endif /* VHOST_BACKEND_H */
> >
>



^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v1 09/10] vhost-vdpa: introduce vhost-vdpa backend
  2020-06-22 15:37 ` [PATCH v1 09/10] vhost-vdpa: introduce vhost-vdpa backend Cindy Lu
  2020-06-23  7:31   ` Jason Wang
  2020-06-25 12:36   ` Laurent Vivier
@ 2020-06-30  7:18   ` Maxime Coquelin
  2020-06-30  8:56     ` Cindy Lu
  2 siblings, 1 reply; 46+ messages in thread
From: Maxime Coquelin @ 2020-06-30  7:18 UTC (permalink / raw)
  To: Cindy Lu, mst, armbru, eblake, cohuck, jasowang
  Cc: mhabets, qemu-devel, rob.miller, saugatm, hch, eperezma, jgg,
	shahafs, kevin.tian, parav, vmireyno, cunming.liang, gdawar,
	jiri, xiao.w.wang, stefanha, zhihong.wang, Tiwei Bie, aadam,
	rdunlap, hanand, lingshan.zhu, Adrian Moreno



On 6/22/20 5:37 PM, Cindy Lu wrote:
> Currently we have 2 types of vhost backends in QEMU: vhost kernel and
> vhost-user. The above patch provides a generic device for vDPA purpose,
> this vDPA device exposes to user space a non-vendor-specific configuration
> interface for setting up a vhost HW accelerator, this patch set introduces
> a third vhost backend called vhost-vdpa based on the vDPA interface.
> 
> Vhost-vdpa usage:
> 
> qemu-system-x86_64 -cpu host -enable-kvm \
>     ......
>     -netdev type=vhost-vdpa,vhostdev=/dev/vhost-vdpa-id,id=vhost-vdpa0 \
>     -device virtio-net-pci,netdev=vhost-vdpa0,page-per-vq=on \
> 
> Signed-off-by: Lingshan zhu <lingshan.zhu@intel.com>
> Signed-off-by: Tiwei Bie <tiwei.bie@intel.com>
> Signed-off-by: Cindy Lu <lulu@redhat.com>
> ---
>  configure                         |  21 ++
>  hw/net/vhost_net.c                |  19 +-
>  hw/net/virtio-net.c               |  19 +-
>  hw/virtio/Makefile.objs           |   1 +
>  hw/virtio/vhost-backend.c         |  22 +-
>  hw/virtio/vhost-vdpa.c            | 406 ++++++++++++++++++++++++++++++
>  hw/virtio/vhost.c                 |  42 +++-
>  include/hw/virtio/vhost-backend.h |   6 +-
>  include/hw/virtio/vhost-vdpa.h    |  26 ++
>  include/hw/virtio/vhost.h         |   6 +
>  qemu-options.hx                   |  12 +
>  11 files changed, 555 insertions(+), 25 deletions(-)
>  create mode 100644 hw/virtio/vhost-vdpa.c
>  create mode 100644 include/hw/virtio/vhost-vdpa.h
> 
> diff --git a/configure b/configure
> index 23b5e93752..53679ee57f 100755
> --- a/configure
> +++ b/configure
> @@ -1557,6 +1557,10 @@ for opt do
>    ;;
>    --enable-vhost-user) vhost_user="yes"
>    ;;
> +  --disable-vhost-vdpa) vhost_vdpa="no"
> +  ;;
> +  --enable-vhost-vdpa) vhost_vdpa="yes"
> +  ;;
>    --disable-vhost-kernel) vhost_kernel="no"
>    ;;
>    --enable-vhost-kernel) vhost_kernel="yes"
> @@ -1846,6 +1850,7 @@ disabled with --disable-FEATURE, default is enabled if available:
>    vhost-crypto    vhost-user-crypto backend support
>    vhost-kernel    vhost kernel backend support
>    vhost-user      vhost-user backend support
> +  vhost-vdpa      vhost-vdpa kernel backend support
>    spice           spice
>    rbd             rados block device (rbd)
>    libiscsi        iscsi support
> @@ -2336,6 +2341,10 @@ test "$vhost_user" = "" && vhost_user=yes
>  if test "$vhost_user" = "yes" && test "$mingw32" = "yes"; then
>    error_exit "vhost-user isn't available on win32"
>  fi
> +test "$vhost_vdpa" = "" && vhost_vdpa=$linux
> +if test "$vhost_vdpa" = "yes" && test "$linux" != "yes"; then
> +  error_exit "vhost-vdpa is only available on Linux"
> +fi
>  test "$vhost_kernel" = "" && vhost_kernel=$linux
>  if test "$vhost_kernel" = "yes" && test "$linux" != "yes"; then
>    error_exit "vhost-kernel is only available on Linux"
> @@ -2364,6 +2373,11 @@ test "$vhost_user_fs" = "" && vhost_user_fs=$vhost_user
>  if test "$vhost_user_fs" = "yes" && test "$vhost_user" = "no"; then
>    error_exit "--enable-vhost-user-fs requires --enable-vhost-user"
>  fi
> +#vhost-vdpa backends
> +test "$vhost_net_vdpa" = "" && vhost_net_vdpa=$vhost_vdpa
> +if test "$vhost_net_vdpa" = "yes" && test "$vhost_vdpa" = "no"; then
> +  error_exit "--enable-vhost-net-vdpa requires --enable-vhost-vdpa"
> +fi
>  
>  # OR the vhost-kernel and vhost-user values for simplicity
>  if test "$vhost_net" = ""; then
> @@ -6673,6 +6687,7 @@ echo "vhost-scsi support $vhost_scsi"
>  echo "vhost-vsock support $vhost_vsock"
>  echo "vhost-user support $vhost_user"
>  echo "vhost-user-fs support $vhost_user_fs"
> +echo "vhost-vdpa support $vhost_vdpa"
>  echo "Trace backends    $trace_backends"
>  if have_backend "simple"; then
>  echo "Trace output file $trace_file-<pid>"
> @@ -7170,6 +7185,9 @@ fi
>  if test "$vhost_net_user" = "yes" ; then
>    echo "CONFIG_VHOST_NET_USER=y" >> $config_host_mak
>  fi
> +if test "$vhost_net_vdpa" = "yes" ; then
> +  echo "CONFIG_VHOST_NET_VDPA=y" >> $config_host_mak
> +fi
>  if test "$vhost_crypto" = "yes" ; then
>    echo "CONFIG_VHOST_CRYPTO=y" >> $config_host_mak
>  fi
> @@ -7182,6 +7200,9 @@ fi
>  if test "$vhost_user" = "yes" ; then
>    echo "CONFIG_VHOST_USER=y" >> $config_host_mak
>  fi
> +if test "$vhost_vdpa" = "yes" ; then
> +  echo "CONFIG_VHOST_VDPA=y" >> $config_host_mak
> +fi
>  if test "$vhost_user_fs" = "yes" ; then
>    echo "CONFIG_VHOST_USER_FS=y" >> $config_host_mak
>  fi
> diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c
> index 04cc3db264..cc259e571d 100644
> --- a/hw/net/vhost_net.c
> +++ b/hw/net/vhost_net.c
> @@ -17,8 +17,10 @@
>  #include "net/net.h"
>  #include "net/tap.h"
>  #include "net/vhost-user.h"
> +#include "net/vhost-vdpa.h"
>  
>  #include "standard-headers/linux/vhost_types.h"
> +#include "linux-headers/linux/vhost.h"
>  #include "hw/virtio/virtio-net.h"
>  #include "net/vhost_net.h"
>  #include "qemu/error-report.h"
> @@ -33,12 +35,6 @@
>  #include "hw/virtio/vhost.h"
>  #include "hw/virtio/virtio-bus.h"
>  
> -struct vhost_net {
> -    struct vhost_dev dev;
> -    struct vhost_virtqueue vqs[2];
> -    int backend;
> -    NetClientState *nc;
> -};
>  
>  /* Features supported by host kernel. */
>  static const int kernel_feature_bits[] = {
> @@ -84,7 +80,6 @@ static const int user_feature_bits[] = {
>  
>      VHOST_INVALID_FEATURE_BIT
>  };
> -
>  static const int *vhost_net_get_feature_bits(struct vhost_net *net)
>  {
>      const int *feature_bits = 0;
> @@ -96,6 +91,9 @@ static const int *vhost_net_get_feature_bits(struct vhost_net *net)
>      case NET_CLIENT_DRIVER_VHOST_USER:
>          feature_bits = user_feature_bits;
>          break;
> +    case NET_CLIENT_DRIVER_VHOST_VDPA:
> +        feature_bits = vdpa_feature_bits;
> +        break;
>      default:
>          error_report("Feature bits not defined for this type: %d",
>                  net->nc->info->type);
> @@ -348,6 +346,7 @@ int vhost_net_start(VirtIODevice *dev, NetClientState *ncs,
>      }
>  
>      for (i = 0; i < total_queues; i++) {
> +
>          peer = qemu_get_peer(ncs, i);
>          r = vhost_net_start_one(get_vhost_net(peer), dev);
>  
> @@ -444,6 +443,12 @@ VHostNetState *get_vhost_net(NetClientState *nc)
>          vhost_net = vhost_user_get_vhost_net(nc);
>          assert(vhost_net);
>          break;
> +#endif
> +#ifdef CONFIG_VHOST_NET_VDPA
> +    case NET_CLIENT_DRIVER_VHOST_VDPA:
> +        vhost_net = vhost_vdpa_get_vhost_net(nc);
> +        assert(vhost_net);
> +        break;
>  #endif
>      default:
>          break;
> diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
> index a46e3b37a7..8c85e2e1e1 100644
> --- a/hw/net/virtio-net.c
> +++ b/hw/net/virtio-net.c
> @@ -42,6 +42,7 @@
>  #include "trace.h"
>  #include "monitor/qdev.h"
>  #include "hw/pci/pci.h"
> +#include "hw/virtio/vhost.h"
>  
>  #define VIRTIO_NET_VM_VERSION    11
>  
> @@ -131,6 +132,8 @@ static void virtio_net_get_config(VirtIODevice *vdev, uint8_t *config)
>  {
>      VirtIONet *n = VIRTIO_NET(vdev);
>      struct virtio_net_config netcfg;
> +    int ret = 0;
> +    memset(&netcfg, 0 , sizeof(struct virtio_net_config));
>  
>      virtio_stw_p(vdev, &netcfg.status, n->status);
>      virtio_stw_p(vdev, &netcfg.max_virtqueue_pairs, n->max_queues);
> @@ -139,13 +142,21 @@ static void virtio_net_get_config(VirtIODevice *vdev, uint8_t *config)
>      virtio_stl_p(vdev, &netcfg.speed, n->net_conf.speed);
>      netcfg.duplex = n->net_conf.duplex;
>      memcpy(config, &netcfg, n->config_size);
> +    NetClientState *nc = qemu_get_queue(n->nic);
> +    if (nc->peer->info->type == NET_CLIENT_DRIVER_VHOST_VDPA) {
> +        ret = vhost_net_get_config(get_vhost_net(nc->peer), (uint8_t *)&netcfg,
> +                             n->config_size);
> +        if (ret != -1) {
> +            memcpy(config, &netcfg, n->config_size);
> +        }
> +    }
>  }
>  
>  static void virtio_net_set_config(VirtIODevice *vdev, const uint8_t *config)
>  {
>      VirtIONet *n = VIRTIO_NET(vdev);
> +    NetClientState *nc = qemu_get_queue(n->nic);
>      struct virtio_net_config netcfg = {};
> -
>      memcpy(&netcfg, config, n->config_size);
>  
>      if (!virtio_vdev_has_feature(vdev, VIRTIO_NET_F_CTRL_MAC_ADDR) &&
> @@ -154,6 +165,11 @@ static void virtio_net_set_config(VirtIODevice *vdev, const uint8_t *config)
>          memcpy(n->mac, netcfg.mac, ETH_ALEN);
>          qemu_format_nic_info_str(qemu_get_queue(n->nic), n->mac);
>      }
> +    if (nc->peer->info->type == NET_CLIENT_DRIVER_VHOST_VDPA) {
> +        vhost_net_set_config(get_vhost_net(nc->peer), (uint8_t *)&netcfg,
> +                               0, n->config_size,
> +                               VHOST_SET_CONFIG_TYPE_MASTER);
> +      }
>  }
>  
>  static bool virtio_net_started(VirtIONet *n, uint8_t status)
> @@ -2958,7 +2974,6 @@ static void virtio_net_device_realize(DeviceState *dev, Error **errp)
>      } else if (n->net_conf.speed >= 0) {
>          n->host_features |= (1ULL << VIRTIO_NET_F_SPEED_DUPLEX);
>      }
> -
>      if (n->failover) {
>          n->primary_listener.should_be_hidden =
>              virtio_net_primary_should_be_hidden;
> diff --git a/hw/virtio/Makefile.objs b/hw/virtio/Makefile.objs
> index 4e4d39a0a4..6b1b1a5fce 100644
> --- a/hw/virtio/Makefile.objs
> +++ b/hw/virtio/Makefile.objs
> @@ -5,6 +5,7 @@ obj-y += virtio.o
>  obj-$(CONFIG_VHOST) += vhost.o vhost-backend.o
>  common-obj-$(call lnot,$(CONFIG_VHOST)) += vhost-stub.o
>  obj-$(CONFIG_VHOST_USER) += vhost-user.o
> +obj-$(CONFIG_VHOST_VDPA) += vhost-vdpa.o
>  
>  common-obj-$(CONFIG_VIRTIO_RNG) += virtio-rng.o
>  common-obj-$(CONFIG_VIRTIO_PCI) += virtio-pci.o
> diff --git a/hw/virtio/vhost-backend.c b/hw/virtio/vhost-backend.c
> index 660e9e8588..84e5b1a833 100644
> --- a/hw/virtio/vhost-backend.c
> +++ b/hw/virtio/vhost-backend.c
> @@ -14,7 +14,7 @@
>  #include "qemu/error-report.h"
>  #include "qemu/main-loop.h"
>  #include "standard-headers/linux/vhost_types.h"
> -
> +#include "hw/virtio/vhost-vdpa.h"
>  #ifdef CONFIG_VHOST_KERNEL
>  #include <linux/vhost.h>
>  #include <sys/ioctl.h>
> @@ -22,10 +22,19 @@
>  static int vhost_kernel_call(struct vhost_dev *dev, unsigned long int request,
>                               void *arg)
>  {
> -    int fd = (uintptr_t) dev->opaque;
> -
> -    assert(dev->vhost_ops->backend_type == VHOST_BACKEND_TYPE_KERNEL);
> +    int fd = -1;
> +    switch (dev->vhost_ops->backend_type) {
> +    case VHOST_BACKEND_TYPE_KERNEL:
> +        fd  = (uintptr_t)dev->opaque;
> +        break;
> +    case VHOST_BACKEND_TYPE_VDPA:
> +        fd = ((struct vhost_vdpa *)dev->opaque)->device_fd;
> +        break;
> +    default:
> +        g_assert_not_reached();
> +    }
>  
> +    assert(fd != -1);
>      return ioctl(fd, request, arg);
>  }
>  
> @@ -285,6 +294,11 @@ int vhost_set_backend_type(struct vhost_dev *dev, VhostBackendType backend_type)
>      case VHOST_BACKEND_TYPE_USER:
>          dev->vhost_ops = &user_ops;
>          break;
> +#endif
> +#ifdef CONFIG_VHOST_VDPA
> +    case VHOST_BACKEND_TYPE_VDPA:
> +        dev->vhost_ops = &vdpa_ops;
> +        break;
>  #endif
>      default:
>          error_report("Unknown vhost backend type");
> diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c
> new file mode 100644
> index 0000000000..1724d404ce
> --- /dev/null
> +++ b/hw/virtio/vhost-vdpa.c
> @@ -0,0 +1,406 @@
> +/*
> + * vhost-vdpa
> + *
> + *  Copyright(c) 2017-2018 Intel Corporation.
> + *  Copyright(c) 2020 Red Hat, Inc.
> + *
> + * This work is licensed under the terms of the GNU GPL, version 2 or later.
> + * See the COPYING file in the top-level directory.
> + *
> + */
> +
> +#include "qemu/osdep.h"
> +#include <linux/vhost.h>
> +#include <linux/vfio.h>
> +#include <sys/eventfd.h>
> +#include <sys/ioctl.h>
> +#include "hw/virtio/vhost.h"
> +#include "hw/virtio/vhost-backend.h"
> +#include "hw/virtio/virtio-net.h"
> +#include "hw/virtio/vhost-vdpa.h"
> +#include "qemu/main-loop.h"
> +#include <linux/kvm.h>
> +#include "sysemu/kvm.h"
> +
> +
> +static bool vhost_vdpa_listener_skipped_section(MemoryRegionSection *section)
> +{
> +    return (!memory_region_is_ram(section->mr) &&
> +            !memory_region_is_iommu(section->mr)) ||
> +           /*
> +            * Sizing an enabled 64-bit BAR can cause spurious mappings to
> +            * addresses in the upper part of the 64-bit address space.  These
> +            * are never accessed by the CPU and beyond the address width of
> +            * some IOMMU hardware.  TODO: VDPA should tell us the IOMMU width.
> +            */
> +           section->offset_within_address_space & (1ULL << 63);
> +}
> +
> +static int vhost_vdpa_dma_map(struct vhost_vdpa *v, hwaddr iova, hwaddr size,
> +                              void *vaddr, bool readonly)
> +{
> +    struct vhost_msg_v2 msg;
> +    int fd = v->device_fd;
> +    int ret = 0;
> +
> +    msg.type =  v->msg_type;
> +    msg.iotlb.iova = iova;
> +    msg.iotlb.size = size;
> +    msg.iotlb.uaddr = (uint64_t)vaddr;
> +    msg.iotlb.perm = readonly ? VHOST_ACCESS_RO : VHOST_ACCESS_RW;
> +    msg.iotlb.type = VHOST_IOTLB_UPDATE;
> +
> +    if (write(fd, &msg, sizeof(msg)) != sizeof(msg)) {
> +        error_report("failed to write, fd=%d, errno=%d (%s)",
> +            fd, errno, strerror(errno));
> +        return -EIO ;
> +    }
> +
> +    return ret;
> +}
> +
> +static int vhost_vdpa_dma_unmap(struct vhost_vdpa *v, hwaddr iova,
> +                                hwaddr size)
> +{
> +    struct vhost_msg_v2 msg;
> +    int fd = v->device_fd;
> +    int ret = 0;
> +
> +    msg.type =  v->msg_type;
> +    msg.iotlb.iova = iova;
> +    msg.iotlb.size = size;
> +    msg.iotlb.type = VHOST_IOTLB_INVALIDATE;
> +
> +    if (write(fd, &msg, sizeof(msg)) != sizeof(msg)) {
> +        error_report("failed to write, fd=%d, errno=%d (%s)",
> +            fd, errno, strerror(errno));
> +        return -EIO ;
> +    }
> +
> +    return ret;
> +}
> +
> +static void vhost_vdpa_listener_region_add(MemoryListener *listener,
> +                                           MemoryRegionSection *section)
> +{
> +    struct vhost_vdpa *v = container_of(listener, struct vhost_vdpa, listener);
> +    hwaddr iova;
> +    Int128 llend, llsize;
> +    void *vaddr;
> +    int ret;
> +
> +    if (vhost_vdpa_listener_skipped_section(section)) {
> +        return;
> +    }
> +
> +    if (unlikely((section->offset_within_address_space & ~TARGET_PAGE_MASK) !=
> +                 (section->offset_within_region & ~TARGET_PAGE_MASK))) {
> +        error_report("%s received unaligned region", __func__);
> +        return;
> +    }
> +
> +    iova = TARGET_PAGE_ALIGN(section->offset_within_address_space);
> +    llend = int128_make64(section->offset_within_address_space);
> +    llend = int128_add(llend, section->size);
> +    llend = int128_and(llend, int128_exts64(TARGET_PAGE_MASK));
> +
> +    if (int128_ge(int128_make64(iova), llend)) {
> +        return;
> +    }
> +
> +    memory_region_ref(section->mr);
> +
> +    /* Here we assume that memory_region_is_ram(section->mr)==true */
> +
> +    vaddr = memory_region_get_ram_ptr(section->mr) +
> +            section->offset_within_region +
> +            (iova - section->offset_within_address_space);
> +
> +    llsize = int128_sub(llend, int128_make64(iova));
> +
> +    ret = vhost_vdpa_dma_map(v, iova, int128_get64(llsize),
> +                             vaddr, section->readonly);
> +    if (ret) {
> +        error_report("vhost vdpa map fail!");
> +        if (memory_region_is_ram_device(section->mr)) {
> +            /* Allow unexpected mappings not to be fatal for RAM devices */
> +            error_report("map ram fail!");
> +          return ;
> +        }
> +        goto fail;
> +    }
> +
> +    return;
> +
> +fail:
> +    if (memory_region_is_ram_device(section->mr)) {
> +        error_report("failed to vdpa_dma_map. pci p2p may not work");
> +        return;
> +
> +    }
> +    /*
> +     * On the initfn path, store the first error in the container so we
> +     * can gracefully fail.  Runtime, there's not much we can do other
> +     * than throw a hardware error.
> +     */
> +    error_report("vhost-vdpa: DMA mapping failed, unable to continue");
> +    return;
> +
> +}
> +
> +static void vhost_vdpa_listener_region_del(MemoryListener *listener,
> +                                           MemoryRegionSection *section)
> +{
> +    struct vhost_vdpa *v = container_of(listener, struct vhost_vdpa, listener);
> +    hwaddr iova;
> +    Int128 llend, llsize;
> +    int ret;
> +    bool try_unmap = true;
> +
> +    if (vhost_vdpa_listener_skipped_section(section)) {
> +        return;
> +    }
> +
> +    if (unlikely((section->offset_within_address_space & ~TARGET_PAGE_MASK) !=
> +                 (section->offset_within_region & ~TARGET_PAGE_MASK))) {
> +        error_report("%s received unaligned region", __func__);
> +        return;
> +    }
> +
> +    iova = TARGET_PAGE_ALIGN(section->offset_within_address_space);
> +    llend = int128_make64(section->offset_within_address_space);
> +    llend = int128_add(llend, section->size);
> +    llend = int128_and(llend, int128_exts64(TARGET_PAGE_MASK));
> +
> +    if (int128_ge(int128_make64(iova), llend)) {
> +        return;
> +    }
> +
> +    llsize = int128_sub(llend, int128_make64(iova));
> +
> +    if (try_unmap) {
> +        ret = vhost_vdpa_dma_unmap(v, iova, int128_get64(llsize));
> +        if (ret) {
> +            error_report("vhost_vdpa dma unmap error!");
> +        }
> +    }
> +
> +    memory_region_unref(section->mr);
> +}
> +/*
> + * IOTLB API is used by vhost-vpda which requires incremental updating
> + * of the mapping. So we can not use generic vhost memory listener which
> + * depends on the addnop().
> + */
> +static const MemoryListener vhost_vdpa_memory_listener = {
> +    .region_add = vhost_vdpa_listener_region_add,
> +    .region_del = vhost_vdpa_listener_region_del,
> +};
> +
> +static int vhost_vdpa_call(struct vhost_dev *dev, unsigned long int request,
> +                             void *arg)
> +{
> +    struct vhost_vdpa *v = dev->opaque;
> +    int fd = v->device_fd;
> +
> +    assert(dev->vhost_ops->backend_type == VHOST_BACKEND_TYPE_VDPA);
> +
> +    return ioctl(fd, request, arg);
> +}
> +
> +static void vhost_vdpa_add_status(struct vhost_dev *dev, uint8_t status)
> +{
> +    uint8_t s;
> +
> +    if (vhost_vdpa_call(dev, VHOST_VDPA_GET_STATUS, &s)) {
> +        return;
> +    }
> +
> +    s |= status;
> +
> +    vhost_vdpa_call(dev, VHOST_VDPA_SET_STATUS, &s);
> +}

I think it would be better to have backend ops for SET_STATUS and
GET_STATUS to avoid duplicating code in every backends that wish to
support it.

Also, I think that SET_STATUS should forward directly the Virtio device
status updates written by the Virtio driver.

> +static int vhost_vdpa_init(struct vhost_dev *dev, void *opaque)
> +{
> +    struct vhost_vdpa *v;
> +    uint64_t features;
> +    assert(dev->vhost_ops->backend_type == VHOST_BACKEND_TYPE_VDPA);
> +
> +    v = opaque;
> +    dev->opaque =  opaque ;
> +    vhost_vdpa_call(dev, VHOST_GET_FEATURES, &features);
> +    dev->backend_features = features;
> +    v->listener = vhost_vdpa_memory_listener;
> +    v->msg_type = VHOST_IOTLB_MSG_V2;
> +
> +    vhost_vdpa_add_status(dev, VIRTIO_CONFIG_S_ACKNOWLEDGE |
> +                               VIRTIO_CONFIG_S_DRIVER);
> +
> +    return 0;
> +}
> +
> +static int vhost_vdpa_cleanup(struct vhost_dev *dev)
> +{
> +    struct vhost_vdpa *v;
> +    assert(dev->vhost_ops->backend_type == VHOST_BACKEND_TYPE_VDPA);
> +    v = dev->opaque;
> +    memory_listener_unregister(&v->listener);
> +
> +    dev->opaque = NULL;
> +    return 0;
> +}
> +
> +static int vhost_vdpa_memslots_limit(struct vhost_dev *dev)
> +{
> +    return INT_MAX;
> +}
> +
> +static int vhost_vdpa_set_mem_table(struct vhost_dev *dev,
> +                                    struct vhost_memory *mem)
> +{
> +
> +    if (mem->padding) {
> +        return -1;
> +    }
> +
> +    return 0;
> +}
> +
> +static int vhost_vdpa_set_features(struct vhost_dev *dev,
> +                                   uint64_t features)
> +{
> +    int ret;
> +    ret = vhost_vdpa_call(dev, VHOST_SET_FEATURES, &features);
> +    uint8_t status = 0;
> +    if (ret) {
> +        return ret;
> +    }
> +    vhost_vdpa_add_status(dev, VIRTIO_CONFIG_S_FEATURES_OK);
> +    vhost_vdpa_call(dev, VHOST_VDPA_GET_STATUS, &status);
> +
> +    return !(status & VIRTIO_CONFIG_S_FEATURES_OK);
> +}
> +
> +int vhost_vdpa_get_device_id(struct vhost_dev *dev,
> +                                   uint32_t *device_id)
> +{
> +    return vhost_vdpa_call(dev, VHOST_VDPA_GET_DEVICE_ID, device_id);
> +}
> +
> +static int vhost_vdpa_reset_device(struct vhost_dev *dev)
> +{
> +    uint8_t status = 0;
> +
> +    return vhost_vdpa_call(dev, VHOST_VDPA_SET_STATUS, &status);
> +}
> +
> +static int vhost_vdpa_get_vq_index(struct vhost_dev *dev, int idx)
> +{
> +    assert(idx >= dev->vq_index && idx < dev->vq_index + dev->nvqs);
> +
> +    return idx - dev->vq_index;
> +}
> +
> +static int vhost_vdpa_set_vring_ready(struct vhost_dev *dev)
> +{
> +    int i;
> +    for (i = 0; i < dev->nvqs; ++i) {
> +        struct vhost_vring_state state = {
> +            .index = dev->vq_index + i,
> +            .num = 1,
> +        };
> +        vhost_vdpa_call(dev, VHOST_VDPA_SET_VRING_ENABLE, &state);
> +    }
> +    return 0;
> +}
> +
> +static int vhost_vdpa_set_config(struct vhost_dev *dev, const uint8_t *data,
> +                                   uint32_t offset, uint32_t size,
> +                                   uint32_t flags)
> +{
> +    struct vhost_vdpa_config *config;
> +    int ret;
> +    unsigned long config_size = offsetof(struct vhost_vdpa_config, buf);
> +    config = g_malloc(size + config_size);
> +    if (config == NULL) {
> +        return -1;
> +    }
> +    config->off = offset;
> +    config->len = size;
> +    memcpy(config->buf, data, size);
> +    ret = vhost_vdpa_call(dev, VHOST_VDPA_SET_CONFIG, config);
> +    g_free(config);
> +    return ret;
> +}
> +
> +static int vhost_vdpa_get_config(struct vhost_dev *dev, uint8_t *config,
> +                                   uint32_t config_len)
> +{
> +    struct vhost_vdpa_config *v_config;
> +    unsigned long config_size = offsetof(struct vhost_vdpa_config, buf);
> +    int ret;
> +
> +    v_config = g_malloc(config_len + config_size);
> +    if (v_config == NULL) {
> +        return -1;
> +    }
> +    v_config->len = config_len;
> +    v_config->off = 0;
> +    ret = vhost_vdpa_call(dev, VHOST_VDPA_GET_CONFIG, v_config);
> +    memcpy(config, v_config->buf, config_len);
> +    g_free(v_config);
> +    return ret;
> + }
> +
> +static int vhost_vdpa_dev_start(struct vhost_dev *dev, bool started)
> +{
> +    struct vhost_vdpa *v = dev->opaque;
> +    if (started) {
> +        uint8_t status = 0;
> +        memory_listener_register(&v->listener, &address_space_memory);
> +        vhost_vdpa_set_vring_ready(dev);
> +        vhost_vdpa_add_status(dev, VIRTIO_CONFIG_S_DRIVER_OK);
> +        vhost_vdpa_call(dev, VHOST_VDPA_GET_STATUS, &status);
> +
> +        return !(status & VIRTIO_CONFIG_S_DRIVER_OK);
> +    } else {
> +        vhost_vdpa_reset_device(dev);
> +        vhost_vdpa_add_status(dev, VIRTIO_CONFIG_S_ACKNOWLEDGE |
> +                                   VIRTIO_CONFIG_S_DRIVER);
> +        memory_listener_unregister(&v->listener);
> +
> +        return 0;
> +    }
> +}
> +
> +const VhostOps vdpa_ops = {
> +        .backend_type = VHOST_BACKEND_TYPE_VDPA,
> +        .vhost_backend_init = vhost_vdpa_init,
> +        .vhost_backend_cleanup = vhost_vdpa_cleanup,
> +        .vhost_set_log_base = vhost_kernel_set_log_base,
> +        .vhost_set_vring_addr = vhost_kernel_set_vring_addr,
> +        .vhost_set_vring_num = vhost_kernel_set_vring_num,
> +        .vhost_set_vring_base = vhost_kernel_set_vring_base,
> +        .vhost_get_vring_base = vhost_kernel_get_vring_base,
> +        .vhost_set_vring_kick = vhost_kernel_set_vring_kick,
> +        .vhost_set_vring_call = vhost_kernel_set_vring_call,
> +        .vhost_get_features = vhost_kernel_get_features,
> +        .vhost_set_owner = vhost_kernel_set_owner,
> +        .vhost_set_vring_endian = NULL,
> +        .vhost_backend_memslots_limit = vhost_vdpa_memslots_limit,
> +        .vhost_set_mem_table = vhost_vdpa_set_mem_table,
> +        .vhost_set_features = vhost_vdpa_set_features,
> +        .vhost_reset_device = vhost_vdpa_reset_device,
> +        .vhost_get_vq_index = vhost_vdpa_get_vq_index,
> +        .vhost_get_config  = vhost_vdpa_get_config,
> +        .vhost_set_config = vhost_vdpa_set_config,
> +        .vhost_requires_shm_log = NULL,
> +        .vhost_migration_done = NULL,
> +        .vhost_backend_can_merge = NULL,
> +        .vhost_net_set_mtu = NULL,
> +        .vhost_set_iotlb_callback = NULL,
> +        .vhost_send_device_iotlb_msg = NULL,
> +        .vhost_dev_start = vhost_vdpa_dev_start,
> +        .vhost_get_device_id = vhost_vdpa_get_device_id,
> +};
> diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
> index bfd7f9ce1f..a75be7216b 100644
> --- a/hw/virtio/vhost.c
> +++ b/hw/virtio/vhost.c
> @@ -744,19 +744,34 @@ static void vhost_iommu_region_del(MemoryListener *listener,
>      }
>  }
>  
> +static void vhost_virtqueue_get_addr(struct vhost_dev *dev,
> +                                    struct vhost_vring_addr *addr,
> +                                    struct vhost_virtqueue *vq)
> +{
> +    /*vDPA need to use the IOVA here to set to hardware*/
> +    if (dev->vhost_ops->backend_type == VHOST_BACKEND_TYPE_VDPA) {
> +        addr->desc_user_addr = (uint64_t)(unsigned long)vq->desc_phys;
> +        addr->avail_user_addr = (uint64_t)(unsigned long)vq->avail_phys;
> +        addr->used_user_addr = (uint64_t)(unsigned long)vq->used_phys;
> +    } else {
> +        addr->desc_user_addr = (uint64_t)(unsigned long)vq->desc;
> +        addr->avail_user_addr = (uint64_t)(unsigned long)vq->avail;
> +        addr->used_user_addr = (uint64_t)(unsigned long)vq->used;
> +    }
> +}
>  
>  static int vhost_virtqueue_set_addr(struct vhost_dev *dev,
>                                      struct vhost_virtqueue *vq,
>                                      unsigned idx, bool enable_log)
>  {
> -    struct vhost_vring_addr addr = {
> -        .index = idx,
> -        .desc_user_addr = (uint64_t)(unsigned long)vq->desc,
> -        .avail_user_addr = (uint64_t)(unsigned long)vq->avail,
> -        .used_user_addr = (uint64_t)(unsigned long)vq->used,
> -        .log_guest_addr = vq->used_phys,
> -        .flags = enable_log ? (1 << VHOST_VRING_F_LOG) : 0,
> -    };
> +    struct vhost_vring_addr addr;
> +    memset(&addr, 0, sizeof(struct vhost_vring_addr));
> +
> +    vhost_virtqueue_get_addr(dev, &addr, vq);
> +    addr.index = idx;
> +    addr .log_guest_addr = vq->used_phys;
> +    addr .flags = enable_log ? (1 << VHOST_VRING_F_LOG) : 0;
> +
>      int r = dev->vhost_ops->vhost_set_vring_addr(dev, &addr);
>      if (r < 0) {
>          VHOST_OPS_DEBUG("vhost_set_vring_addr failed");
> @@ -774,7 +789,9 @@ static int vhost_dev_set_features(struct vhost_dev *dev,
>          features |= 0x1ULL << VHOST_F_LOG_ALL;
>      }
>      if (!vhost_dev_has_iommu(dev)) {
> -        features &= ~(0x1ULL << VIRTIO_F_IOMMU_PLATFORM);
> +        if (dev->vhost_ops->backend_type != VHOST_BACKEND_TYPE_VDPA) {
> +            features &= ~(0x1ULL << VIRTIO_F_IOMMU_PLATFORM);
> +        }
>      }
>      r = dev->vhost_ops->vhost_set_features(dev, features);
>      if (r < 0) {
> @@ -1667,7 +1684,8 @@ int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev)
>          goto fail_log;
>      }
>  
> -    if (vhost_dev_has_iommu(hdev)) {
> +    if (vhost_dev_has_iommu(hdev) &&
> +        hdev->vhost_ops->vhost_set_iotlb_callback) {
>          hdev->vhost_ops->vhost_set_iotlb_callback(hdev, true);
>  
>          /* Update used ring information for IOTLB to work correctly,
> @@ -1713,7 +1731,9 @@ void vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev)
>      }
>  
>      if (vhost_dev_has_iommu(hdev)) {
> -        hdev->vhost_ops->vhost_set_iotlb_callback(hdev, false);
> +        if (hdev->vhost_ops->vhost_set_iotlb_callback) {
> +            hdev->vhost_ops->vhost_set_iotlb_callback(hdev, false);
> +        }
>          memory_listener_unregister(&hdev->iommu_listener);
>      }
>      vhost_log_put(hdev, true);
> diff --git a/include/hw/virtio/vhost-backend.h b/include/hw/virtio/vhost-backend.h
> index c1384bd2c7..c418c2fa0e 100644
> --- a/include/hw/virtio/vhost-backend.h
> +++ b/include/hw/virtio/vhost-backend.h
> @@ -17,7 +17,8 @@ typedef enum VhostBackendType {
>      VHOST_BACKEND_TYPE_NONE = 0,
>      VHOST_BACKEND_TYPE_KERNEL = 1,
>      VHOST_BACKEND_TYPE_USER = 2,
> -    VHOST_BACKEND_TYPE_MAX = 3,
> +    VHOST_BACKEND_TYPE_VDPA = 3,
> +    VHOST_BACKEND_TYPE_MAX = 4,
>  } VhostBackendType;
>  
>  typedef enum VhostSetConfigType {
> @@ -113,6 +114,7 @@ typedef int (*vhost_set_inflight_fd_op)(struct vhost_dev *dev,
>                                          struct vhost_inflight *inflight);
>  
>  typedef int (*vhost_dev_start_op)(struct vhost_dev *dev, bool started);
> +typedef int (*vhost_get_device_id_op)(struct vhost_dev *dev, uint32_t *dev_id);
>  typedef struct VhostOps {
>      VhostBackendType backend_type;
>      vhost_backend_init vhost_backend_init;
> @@ -154,9 +156,11 @@ typedef struct VhostOps {
>      vhost_get_inflight_fd_op vhost_get_inflight_fd;
>      vhost_set_inflight_fd_op vhost_set_inflight_fd;
>      vhost_dev_start_op vhost_dev_start;
> +    vhost_get_device_id_op vhost_get_device_id;
>  } VhostOps;
>  
>  extern const VhostOps user_ops;
> +extern const VhostOps vdpa_ops;
>  
>  int vhost_set_backend_type(struct vhost_dev *dev,
>                             VhostBackendType backend_type);
> diff --git a/include/hw/virtio/vhost-vdpa.h b/include/hw/virtio/vhost-vdpa.h
> new file mode 100644
> index 0000000000..6455663388
> --- /dev/null
> +++ b/include/hw/virtio/vhost-vdpa.h
> @@ -0,0 +1,26 @@
> +/*
> + * vhost-vdpa.h
> + *
> + * Copyright(c) 2017-2018 Intel Corporation.
> + * Copyright(c) 2020 Red Hat, Inc.
> + *
> + * This work is licensed under the terms of the GNU GPL, version 2 or later.
> + * See the COPYING file in the top-level directory.
> + *
> + */
> +
> +#ifndef HW_VIRTIO_VHOST_VDPA_H
> +#define HW_VIRTIO_VHOST_VDPA_H
> +
> +#include "hw/virtio/virtio.h"
> +
> +typedef struct vhost_vdpa {
> +    int device_fd;
> +    uint32_t msg_type;
> +    MemoryListener listener;
> +} VhostVDPA;
> +
> +extern AddressSpace address_space_memory;
> +extern int vhost_vdpa_get_device_id(struct vhost_dev *dev,
> +                                   uint32_t *device_id);
> +#endif
> diff --git a/include/hw/virtio/vhost.h b/include/hw/virtio/vhost.h
> index 59ea53f8c2..f69b5e4a02 100644
> --- a/include/hw/virtio/vhost.h
> +++ b/include/hw/virtio/vhost.h
> @@ -92,6 +92,12 @@ struct vhost_dev {
>      const VhostDevConfigOps *config_ops;
>  };
>  
> +struct vhost_net {
> +    struct vhost_dev dev;
> +    struct vhost_virtqueue vqs[2];
> +    int backend;
> +    NetClientState *nc;
> +};
>  
>  int vhost_dev_init(struct vhost_dev *hdev, void *opaque,
>                     VhostBackendType backend_type,
> diff --git a/qemu-options.hx b/qemu-options.hx
> index 292d4e7c0c..d7d0daaa0e 100644
> --- a/qemu-options.hx
> +++ b/qemu-options.hx
> @@ -2409,6 +2409,10 @@ DEF("netdev", HAS_ARG, QEMU_OPTION_netdev,
>  #ifdef CONFIG_POSIX
>      "-netdev vhost-user,id=str,chardev=dev[,vhostforce=on|off]\n"
>      "                configure a vhost-user network, backed by a chardev 'dev'\n"
> +#endif
> +#ifdef __linux__
> +    "-netdev vhost-vdpa,id=str,vhostdev=/path/to/dev\n"
> +    "                configure a vhost-vdpa network,Establish a vhost-vdpa netdev\n"
>  #endif
>      "-netdev hubport,id=str,hubid=n[,netdev=nd]\n"
>      "                configure a hub port on the hub with ID 'n'\n", QEMU_ARCH_ALL)
> @@ -2888,6 +2892,14 @@ SRST
>               -netdev type=vhost-user,id=net0,chardev=chr0 \
>               -device virtio-net-pci,netdev=net0
>  
> +``-netdev vhost-vdpa,vhostdev=/path/to/dev``
> +    Establish a vhost-vdpa netdev.
> +
> +    vDPA device is a device that uses a datapath which complies with
> +    the virtio specifications with a vendor specific control path.
> +    vDPA devices can be both physically located on the hardware or
> +    emulated by software.
> +
>  ``-netdev hubport,id=id,hubid=hubid[,netdev=nd]``
>      Create a hub port on the emulated hub with ID hubid.
>  
> 



^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v1 09/10] vhost-vdpa: introduce vhost-vdpa backend
  2020-06-30  7:18   ` Maxime Coquelin
@ 2020-06-30  8:56     ` Cindy Lu
  0 siblings, 0 replies; 46+ messages in thread
From: Cindy Lu @ 2020-06-30  8:56 UTC (permalink / raw)
  To: Maxime Coquelin
  Cc: Cornelia Huck, Michael Tsirkin, Jason Wang, qemu-devel,
	Rob Miller, saugatm, Markus Armbruster, hch,
	Eugenio Perez Martin, jgg, mhabets, Shahaf Shuler, kevin.tian,
	parav, Vitaly Mireyno, Liang, Cunming, gdawar, jiri, xiao.w.wang,
	Stefan Hajnoczi, Wang, Zhihong, Tiwei Bie, Ariel Adam, rdunlap,
	hanand, Zhu, Lingshan, Adrian Moreno

On Tue, Jun 30, 2020 at 3:19 PM Maxime Coquelin
<maxime.coquelin@redhat.com> wrote:
>
>
>
> On 6/22/20 5:37 PM, Cindy Lu wrote:
> > Currently we have 2 types of vhost backends in QEMU: vhost kernel and
> > vhost-user. The above patch provides a generic device for vDPA purpose,
> > this vDPA device exposes to user space a non-vendor-specific configuration
> > interface for setting up a vhost HW accelerator, this patch set introduces
> > a third vhost backend called vhost-vdpa based on the vDPA interface.
> >
> > Vhost-vdpa usage:
> >
> > qemu-system-x86_64 -cpu host -enable-kvm \
> >     ......
> >     -netdev type=vhost-vdpa,vhostdev=/dev/vhost-vdpa-id,id=vhost-vdpa0 \
> >     -device virtio-net-pci,netdev=vhost-vdpa0,page-per-vq=on \
> >
> > Signed-off-by: Lingshan zhu <lingshan.zhu@intel.com>
> > Signed-off-by: Tiwei Bie <tiwei.bie@intel.com>
> > Signed-off-by: Cindy Lu <lulu@redhat.com>
> > ---
> >  configure                         |  21 ++
> >  hw/net/vhost_net.c                |  19 +-
> >  hw/net/virtio-net.c               |  19 +-
> >  hw/virtio/Makefile.objs           |   1 +
> >  hw/virtio/vhost-backend.c         |  22 +-
> >  hw/virtio/vhost-vdpa.c            | 406 ++++++++++++++++++++++++++++++
> >  hw/virtio/vhost.c                 |  42 +++-
> >  include/hw/virtio/vhost-backend.h |   6 +-
> >  include/hw/virtio/vhost-vdpa.h    |  26 ++
> >  include/hw/virtio/vhost.h         |   6 +
> >  qemu-options.hx                   |  12 +
> >  11 files changed, 555 insertions(+), 25 deletions(-)
> >  create mode 100644 hw/virtio/vhost-vdpa.c
> >  create mode 100644 include/hw/virtio/vhost-vdpa.h
> >
> > diff --git a/configure b/configure
> > index 23b5e93752..53679ee57f 100755
> > --- a/configure
> > +++ b/configure
> > @@ -1557,6 +1557,10 @@ for opt do
> >    ;;
> >    --enable-vhost-user) vhost_user="yes"
> >    ;;
> > +  --disable-vhost-vdpa) vhost_vdpa="no"
> > +  ;;
> > +  --enable-vhost-vdpa) vhost_vdpa="yes"
> > +  ;;
> >    --disable-vhost-kernel) vhost_kernel="no"
> >    ;;
> >    --enable-vhost-kernel) vhost_kernel="yes"
> > @@ -1846,6 +1850,7 @@ disabled with --disable-FEATURE, default is enabled if available:
> >    vhost-crypto    vhost-user-crypto backend support
> >    vhost-kernel    vhost kernel backend support
> >    vhost-user      vhost-user backend support
> > +  vhost-vdpa      vhost-vdpa kernel backend support
> >    spice           spice
> >    rbd             rados block device (rbd)
> >    libiscsi        iscsi support
> > @@ -2336,6 +2341,10 @@ test "$vhost_user" = "" && vhost_user=yes
> >  if test "$vhost_user" = "yes" && test "$mingw32" = "yes"; then
> >    error_exit "vhost-user isn't available on win32"
> >  fi
> > +test "$vhost_vdpa" = "" && vhost_vdpa=$linux
> > +if test "$vhost_vdpa" = "yes" && test "$linux" != "yes"; then
> > +  error_exit "vhost-vdpa is only available on Linux"
> > +fi
> >  test "$vhost_kernel" = "" && vhost_kernel=$linux
> >  if test "$vhost_kernel" = "yes" && test "$linux" != "yes"; then
> >    error_exit "vhost-kernel is only available on Linux"
> > @@ -2364,6 +2373,11 @@ test "$vhost_user_fs" = "" && vhost_user_fs=$vhost_user
> >  if test "$vhost_user_fs" = "yes" && test "$vhost_user" = "no"; then
> >    error_exit "--enable-vhost-user-fs requires --enable-vhost-user"
> >  fi
> > +#vhost-vdpa backends
> > +test "$vhost_net_vdpa" = "" && vhost_net_vdpa=$vhost_vdpa
> > +if test "$vhost_net_vdpa" = "yes" && test "$vhost_vdpa" = "no"; then
> > +  error_exit "--enable-vhost-net-vdpa requires --enable-vhost-vdpa"
> > +fi
> >
> >  # OR the vhost-kernel and vhost-user values for simplicity
> >  if test "$vhost_net" = ""; then
> > @@ -6673,6 +6687,7 @@ echo "vhost-scsi support $vhost_scsi"
> >  echo "vhost-vsock support $vhost_vsock"
> >  echo "vhost-user support $vhost_user"
> >  echo "vhost-user-fs support $vhost_user_fs"
> > +echo "vhost-vdpa support $vhost_vdpa"
> >  echo "Trace backends    $trace_backends"
> >  if have_backend "simple"; then
> >  echo "Trace output file $trace_file-<pid>"
> > @@ -7170,6 +7185,9 @@ fi
> >  if test "$vhost_net_user" = "yes" ; then
> >    echo "CONFIG_VHOST_NET_USER=y" >> $config_host_mak
> >  fi
> > +if test "$vhost_net_vdpa" = "yes" ; then
> > +  echo "CONFIG_VHOST_NET_VDPA=y" >> $config_host_mak
> > +fi
> >  if test "$vhost_crypto" = "yes" ; then
> >    echo "CONFIG_VHOST_CRYPTO=y" >> $config_host_mak
> >  fi
> > @@ -7182,6 +7200,9 @@ fi
> >  if test "$vhost_user" = "yes" ; then
> >    echo "CONFIG_VHOST_USER=y" >> $config_host_mak
> >  fi
> > +if test "$vhost_vdpa" = "yes" ; then
> > +  echo "CONFIG_VHOST_VDPA=y" >> $config_host_mak
> > +fi
> >  if test "$vhost_user_fs" = "yes" ; then
> >    echo "CONFIG_VHOST_USER_FS=y" >> $config_host_mak
> >  fi
> > diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c
> > index 04cc3db264..cc259e571d 100644
> > --- a/hw/net/vhost_net.c
> > +++ b/hw/net/vhost_net.c
> > @@ -17,8 +17,10 @@
> >  #include "net/net.h"
> >  #include "net/tap.h"
> >  #include "net/vhost-user.h"
> > +#include "net/vhost-vdpa.h"
> >
> >  #include "standard-headers/linux/vhost_types.h"
> > +#include "linux-headers/linux/vhost.h"
> >  #include "hw/virtio/virtio-net.h"
> >  #include "net/vhost_net.h"
> >  #include "qemu/error-report.h"
> > @@ -33,12 +35,6 @@
> >  #include "hw/virtio/vhost.h"
> >  #include "hw/virtio/virtio-bus.h"
> >
> > -struct vhost_net {
> > -    struct vhost_dev dev;
> > -    struct vhost_virtqueue vqs[2];
> > -    int backend;
> > -    NetClientState *nc;
> > -};
> >
> >  /* Features supported by host kernel. */
> >  static const int kernel_feature_bits[] = {
> > @@ -84,7 +80,6 @@ static const int user_feature_bits[] = {
> >
> >      VHOST_INVALID_FEATURE_BIT
> >  };
> > -
> >  static const int *vhost_net_get_feature_bits(struct vhost_net *net)
> >  {
> >      const int *feature_bits = 0;
> > @@ -96,6 +91,9 @@ static const int *vhost_net_get_feature_bits(struct vhost_net *net)
> >      case NET_CLIENT_DRIVER_VHOST_USER:
> >          feature_bits = user_feature_bits;
> >          break;
> > +    case NET_CLIENT_DRIVER_VHOST_VDPA:
> > +        feature_bits = vdpa_feature_bits;
> > +        break;
> >      default:
> >          error_report("Feature bits not defined for this type: %d",
> >                  net->nc->info->type);
> > @@ -348,6 +346,7 @@ int vhost_net_start(VirtIODevice *dev, NetClientState *ncs,
> >      }
> >
> >      for (i = 0; i < total_queues; i++) {
> > +
> >          peer = qemu_get_peer(ncs, i);
> >          r = vhost_net_start_one(get_vhost_net(peer), dev);
> >
> > @@ -444,6 +443,12 @@ VHostNetState *get_vhost_net(NetClientState *nc)
> >          vhost_net = vhost_user_get_vhost_net(nc);
> >          assert(vhost_net);
> >          break;
> > +#endif
> > +#ifdef CONFIG_VHOST_NET_VDPA
> > +    case NET_CLIENT_DRIVER_VHOST_VDPA:
> > +        vhost_net = vhost_vdpa_get_vhost_net(nc);
> > +        assert(vhost_net);
> > +        break;
> >  #endif
> >      default:
> >          break;
> > diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
> > index a46e3b37a7..8c85e2e1e1 100644
> > --- a/hw/net/virtio-net.c
> > +++ b/hw/net/virtio-net.c
> > @@ -42,6 +42,7 @@
> >  #include "trace.h"
> >  #include "monitor/qdev.h"
> >  #include "hw/pci/pci.h"
> > +#include "hw/virtio/vhost.h"
> >
> >  #define VIRTIO_NET_VM_VERSION    11
> >
> > @@ -131,6 +132,8 @@ static void virtio_net_get_config(VirtIODevice *vdev, uint8_t *config)
> >  {
> >      VirtIONet *n = VIRTIO_NET(vdev);
> >      struct virtio_net_config netcfg;
> > +    int ret = 0;
> > +    memset(&netcfg, 0 , sizeof(struct virtio_net_config));
> >
> >      virtio_stw_p(vdev, &netcfg.status, n->status);
> >      virtio_stw_p(vdev, &netcfg.max_virtqueue_pairs, n->max_queues);
> > @@ -139,13 +142,21 @@ static void virtio_net_get_config(VirtIODevice *vdev, uint8_t *config)
> >      virtio_stl_p(vdev, &netcfg.speed, n->net_conf.speed);
> >      netcfg.duplex = n->net_conf.duplex;
> >      memcpy(config, &netcfg, n->config_size);
> > +    NetClientState *nc = qemu_get_queue(n->nic);
> > +    if (nc->peer->info->type == NET_CLIENT_DRIVER_VHOST_VDPA) {
> > +        ret = vhost_net_get_config(get_vhost_net(nc->peer), (uint8_t *)&netcfg,
> > +                             n->config_size);
> > +        if (ret != -1) {
> > +            memcpy(config, &netcfg, n->config_size);
> > +        }
> > +    }
> >  }
> >
> >  static void virtio_net_set_config(VirtIODevice *vdev, const uint8_t *config)
> >  {
> >      VirtIONet *n = VIRTIO_NET(vdev);
> > +    NetClientState *nc = qemu_get_queue(n->nic);
> >      struct virtio_net_config netcfg = {};
> > -
> >      memcpy(&netcfg, config, n->config_size);
> >
> >      if (!virtio_vdev_has_feature(vdev, VIRTIO_NET_F_CTRL_MAC_ADDR) &&
> > @@ -154,6 +165,11 @@ static void virtio_net_set_config(VirtIODevice *vdev, const uint8_t *config)
> >          memcpy(n->mac, netcfg.mac, ETH_ALEN);
> >          qemu_format_nic_info_str(qemu_get_queue(n->nic), n->mac);
> >      }
> > +    if (nc->peer->info->type == NET_CLIENT_DRIVER_VHOST_VDPA) {
> > +        vhost_net_set_config(get_vhost_net(nc->peer), (uint8_t *)&netcfg,
> > +                               0, n->config_size,
> > +                               VHOST_SET_CONFIG_TYPE_MASTER);
> > +      }
> >  }
> >
> >  static bool virtio_net_started(VirtIONet *n, uint8_t status)
> > @@ -2958,7 +2974,6 @@ static void virtio_net_device_realize(DeviceState *dev, Error **errp)
> >      } else if (n->net_conf.speed >= 0) {
> >          n->host_features |= (1ULL << VIRTIO_NET_F_SPEED_DUPLEX);
> >      }
> > -
> >      if (n->failover) {
> >          n->primary_listener.should_be_hidden =
> >              virtio_net_primary_should_be_hidden;
> > diff --git a/hw/virtio/Makefile.objs b/hw/virtio/Makefile.objs
> > index 4e4d39a0a4..6b1b1a5fce 100644
> > --- a/hw/virtio/Makefile.objs
> > +++ b/hw/virtio/Makefile.objs
> > @@ -5,6 +5,7 @@ obj-y += virtio.o
> >  obj-$(CONFIG_VHOST) += vhost.o vhost-backend.o
> >  common-obj-$(call lnot,$(CONFIG_VHOST)) += vhost-stub.o
> >  obj-$(CONFIG_VHOST_USER) += vhost-user.o
> > +obj-$(CONFIG_VHOST_VDPA) += vhost-vdpa.o
> >
> >  common-obj-$(CONFIG_VIRTIO_RNG) += virtio-rng.o
> >  common-obj-$(CONFIG_VIRTIO_PCI) += virtio-pci.o
> > diff --git a/hw/virtio/vhost-backend.c b/hw/virtio/vhost-backend.c
> > index 660e9e8588..84e5b1a833 100644
> > --- a/hw/virtio/vhost-backend.c
> > +++ b/hw/virtio/vhost-backend.c
> > @@ -14,7 +14,7 @@
> >  #include "qemu/error-report.h"
> >  #include "qemu/main-loop.h"
> >  #include "standard-headers/linux/vhost_types.h"
> > -
> > +#include "hw/virtio/vhost-vdpa.h"
> >  #ifdef CONFIG_VHOST_KERNEL
> >  #include <linux/vhost.h>
> >  #include <sys/ioctl.h>
> > @@ -22,10 +22,19 @@
> >  static int vhost_kernel_call(struct vhost_dev *dev, unsigned long int request,
> >                               void *arg)
> >  {
> > -    int fd = (uintptr_t) dev->opaque;
> > -
> > -    assert(dev->vhost_ops->backend_type == VHOST_BACKEND_TYPE_KERNEL);
> > +    int fd = -1;
> > +    switch (dev->vhost_ops->backend_type) {
> > +    case VHOST_BACKEND_TYPE_KERNEL:
> > +        fd  = (uintptr_t)dev->opaque;
> > +        break;
> > +    case VHOST_BACKEND_TYPE_VDPA:
> > +        fd = ((struct vhost_vdpa *)dev->opaque)->device_fd;
> > +        break;
> > +    default:
> > +        g_assert_not_reached();
> > +    }
> >
> > +    assert(fd != -1);
> >      return ioctl(fd, request, arg);
> >  }
> >
> > @@ -285,6 +294,11 @@ int vhost_set_backend_type(struct vhost_dev *dev, VhostBackendType backend_type)
> >      case VHOST_BACKEND_TYPE_USER:
> >          dev->vhost_ops = &user_ops;
> >          break;
> > +#endif
> > +#ifdef CONFIG_VHOST_VDPA
> > +    case VHOST_BACKEND_TYPE_VDPA:
> > +        dev->vhost_ops = &vdpa_ops;
> > +        break;
> >  #endif
> >      default:
> >          error_report("Unknown vhost backend type");
> > diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c
> > new file mode 100644
> > index 0000000000..1724d404ce
> > --- /dev/null
> > +++ b/hw/virtio/vhost-vdpa.c
> > @@ -0,0 +1,406 @@
> > +/*
> > + * vhost-vdpa
> > + *
> > + *  Copyright(c) 2017-2018 Intel Corporation.
> > + *  Copyright(c) 2020 Red Hat, Inc.
> > + *
> > + * This work is licensed under the terms of the GNU GPL, version 2 or later.
> > + * See the COPYING file in the top-level directory.
> > + *
> > + */
> > +
> > +#include "qemu/osdep.h"
> > +#include <linux/vhost.h>
> > +#include <linux/vfio.h>
> > +#include <sys/eventfd.h>
> > +#include <sys/ioctl.h>
> > +#include "hw/virtio/vhost.h"
> > +#include "hw/virtio/vhost-backend.h"
> > +#include "hw/virtio/virtio-net.h"
> > +#include "hw/virtio/vhost-vdpa.h"
> > +#include "qemu/main-loop.h"
> > +#include <linux/kvm.h>
> > +#include "sysemu/kvm.h"
> > +
> > +
> > +static bool vhost_vdpa_listener_skipped_section(MemoryRegionSection *section)
> > +{
> > +    return (!memory_region_is_ram(section->mr) &&
> > +            !memory_region_is_iommu(section->mr)) ||
> > +           /*
> > +            * Sizing an enabled 64-bit BAR can cause spurious mappings to
> > +            * addresses in the upper part of the 64-bit address space.  These
> > +            * are never accessed by the CPU and beyond the address width of
> > +            * some IOMMU hardware.  TODO: VDPA should tell us the IOMMU width.
> > +            */
> > +           section->offset_within_address_space & (1ULL << 63);
> > +}
> > +
> > +static int vhost_vdpa_dma_map(struct vhost_vdpa *v, hwaddr iova, hwaddr size,
> > +                              void *vaddr, bool readonly)
> > +{
> > +    struct vhost_msg_v2 msg;
> > +    int fd = v->device_fd;
> > +    int ret = 0;
> > +
> > +    msg.type =  v->msg_type;
> > +    msg.iotlb.iova = iova;
> > +    msg.iotlb.size = size;
> > +    msg.iotlb.uaddr = (uint64_t)vaddr;
> > +    msg.iotlb.perm = readonly ? VHOST_ACCESS_RO : VHOST_ACCESS_RW;
> > +    msg.iotlb.type = VHOST_IOTLB_UPDATE;
> > +
> > +    if (write(fd, &msg, sizeof(msg)) != sizeof(msg)) {
> > +        error_report("failed to write, fd=%d, errno=%d (%s)",
> > +            fd, errno, strerror(errno));
> > +        return -EIO ;
> > +    }
> > +
> > +    return ret;
> > +}
> > +
> > +static int vhost_vdpa_dma_unmap(struct vhost_vdpa *v, hwaddr iova,
> > +                                hwaddr size)
> > +{
> > +    struct vhost_msg_v2 msg;
> > +    int fd = v->device_fd;
> > +    int ret = 0;
> > +
> > +    msg.type =  v->msg_type;
> > +    msg.iotlb.iova = iova;
> > +    msg.iotlb.size = size;
> > +    msg.iotlb.type = VHOST_IOTLB_INVALIDATE;
> > +
> > +    if (write(fd, &msg, sizeof(msg)) != sizeof(msg)) {
> > +        error_report("failed to write, fd=%d, errno=%d (%s)",
> > +            fd, errno, strerror(errno));
> > +        return -EIO ;
> > +    }
> > +
> > +    return ret;
> > +}
> > +
> > +static void vhost_vdpa_listener_region_add(MemoryListener *listener,
> > +                                           MemoryRegionSection *section)
> > +{
> > +    struct vhost_vdpa *v = container_of(listener, struct vhost_vdpa, listener);
> > +    hwaddr iova;
> > +    Int128 llend, llsize;
> > +    void *vaddr;
> > +    int ret;
> > +
> > +    if (vhost_vdpa_listener_skipped_section(section)) {
> > +        return;
> > +    }
> > +
> > +    if (unlikely((section->offset_within_address_space & ~TARGET_PAGE_MASK) !=
> > +                 (section->offset_within_region & ~TARGET_PAGE_MASK))) {
> > +        error_report("%s received unaligned region", __func__);
> > +        return;
> > +    }
> > +
> > +    iova = TARGET_PAGE_ALIGN(section->offset_within_address_space);
> > +    llend = int128_make64(section->offset_within_address_space);
> > +    llend = int128_add(llend, section->size);
> > +    llend = int128_and(llend, int128_exts64(TARGET_PAGE_MASK));
> > +
> > +    if (int128_ge(int128_make64(iova), llend)) {
> > +        return;
> > +    }
> > +
> > +    memory_region_ref(section->mr);
> > +
> > +    /* Here we assume that memory_region_is_ram(section->mr)==true */
> > +
> > +    vaddr = memory_region_get_ram_ptr(section->mr) +
> > +            section->offset_within_region +
> > +            (iova - section->offset_within_address_space);
> > +
> > +    llsize = int128_sub(llend, int128_make64(iova));
> > +
> > +    ret = vhost_vdpa_dma_map(v, iova, int128_get64(llsize),
> > +                             vaddr, section->readonly);
> > +    if (ret) {
> > +        error_report("vhost vdpa map fail!");
> > +        if (memory_region_is_ram_device(section->mr)) {
> > +            /* Allow unexpected mappings not to be fatal for RAM devices */
> > +            error_report("map ram fail!");
> > +          return ;
> > +        }
> > +        goto fail;
> > +    }
> > +
> > +    return;
> > +
> > +fail:
> > +    if (memory_region_is_ram_device(section->mr)) {
> > +        error_report("failed to vdpa_dma_map. pci p2p may not work");
> > +        return;
> > +
> > +    }
> > +    /*
> > +     * On the initfn path, store the first error in the container so we
> > +     * can gracefully fail.  Runtime, there's not much we can do other
> > +     * than throw a hardware error.
> > +     */
> > +    error_report("vhost-vdpa: DMA mapping failed, unable to continue");
> > +    return;
> > +
> > +}
> > +
> > +static void vhost_vdpa_listener_region_del(MemoryListener *listener,
> > +                                           MemoryRegionSection *section)
> > +{
> > +    struct vhost_vdpa *v = container_of(listener, struct vhost_vdpa, listener);
> > +    hwaddr iova;
> > +    Int128 llend, llsize;
> > +    int ret;
> > +    bool try_unmap = true;
> > +
> > +    if (vhost_vdpa_listener_skipped_section(section)) {
> > +        return;
> > +    }
> > +
> > +    if (unlikely((section->offset_within_address_space & ~TARGET_PAGE_MASK) !=
> > +                 (section->offset_within_region & ~TARGET_PAGE_MASK))) {
> > +        error_report("%s received unaligned region", __func__);
> > +        return;
> > +    }
> > +
> > +    iova = TARGET_PAGE_ALIGN(section->offset_within_address_space);
> > +    llend = int128_make64(section->offset_within_address_space);
> > +    llend = int128_add(llend, section->size);
> > +    llend = int128_and(llend, int128_exts64(TARGET_PAGE_MASK));
> > +
> > +    if (int128_ge(int128_make64(iova), llend)) {
> > +        return;
> > +    }
> > +
> > +    llsize = int128_sub(llend, int128_make64(iova));
> > +
> > +    if (try_unmap) {
> > +        ret = vhost_vdpa_dma_unmap(v, iova, int128_get64(llsize));
> > +        if (ret) {
> > +            error_report("vhost_vdpa dma unmap error!");
> > +        }
> > +    }
> > +
> > +    memory_region_unref(section->mr);
> > +}
> > +/*
> > + * IOTLB API is used by vhost-vpda which requires incremental updating
> > + * of the mapping. So we can not use generic vhost memory listener which
> > + * depends on the addnop().
> > + */
> > +static const MemoryListener vhost_vdpa_memory_listener = {
> > +    .region_add = vhost_vdpa_listener_region_add,
> > +    .region_del = vhost_vdpa_listener_region_del,
> > +};
> > +
> > +static int vhost_vdpa_call(struct vhost_dev *dev, unsigned long int request,
> > +                             void *arg)
> > +{
> > +    struct vhost_vdpa *v = dev->opaque;
> > +    int fd = v->device_fd;
> > +
> > +    assert(dev->vhost_ops->backend_type == VHOST_BACKEND_TYPE_VDPA);
> > +
> > +    return ioctl(fd, request, arg);
> > +}
> > +
> > +static void vhost_vdpa_add_status(struct vhost_dev *dev, uint8_t status)
> > +{
> > +    uint8_t s;
> > +
> > +    if (vhost_vdpa_call(dev, VHOST_VDPA_GET_STATUS, &s)) {
> > +        return;
> > +    }
> > +
> > +    s |= status;
> > +
> > +    vhost_vdpa_call(dev, VHOST_VDPA_SET_STATUS, &s);
> > +}
>
> I think it would be better to have backend ops for SET_STATUS and
> GET_STATUS to avoid duplicating code in every backends that wish to
> support it.
>
> Also, I think that SET_STATUS should forward directly the Virtio device
> status updates written by the Virtio driver.
>
Hi Maxime,
I think maybe we can keep what is now, now we only export the vhostops
vhost_dev_start.
That  will make the code in vhost.c clear and easy to understand.
Also if there are different processes in different kinds of backends,
we can implement them in
their own file,  hiden the difference to the uplayer.

Thanks
Cindy
> > +static int vhost_vdpa_init(struct vhost_dev *dev, void *opaque)
> > +{
> > +    struct vhost_vdpa *v;
> > +    uint64_t features;
> > +    assert(dev->vhost_ops->backend_type == VHOST_BACKEND_TYPE_VDPA);
> > +
> > +    v = opaque;
> > +    dev->opaque =  opaque ;
> > +    vhost_vdpa_call(dev, VHOST_GET_FEATURES, &features);
> > +    dev->backend_features = features;
> > +    v->listener = vhost_vdpa_memory_listener;
> > +    v->msg_type = VHOST_IOTLB_MSG_V2;
> > +
> > +    vhost_vdpa_add_status(dev, VIRTIO_CONFIG_S_ACKNOWLEDGE |
> > +                               VIRTIO_CONFIG_S_DRIVER);
> > +
> > +    return 0;
> > +}
> > +
> > +static int vhost_vdpa_cleanup(struct vhost_dev *dev)
> > +{
> > +    struct vhost_vdpa *v;
> > +    assert(dev->vhost_ops->backend_type == VHOST_BACKEND_TYPE_VDPA);
> > +    v = dev->opaque;
> > +    memory_listener_unregister(&v->listener);
> > +
> > +    dev->opaque = NULL;
> > +    return 0;
> > +}
> > +
> > +static int vhost_vdpa_memslots_limit(struct vhost_dev *dev)
> > +{
> > +    return INT_MAX;
> > +}
> > +
> > +static int vhost_vdpa_set_mem_table(struct vhost_dev *dev,
> > +                                    struct vhost_memory *mem)
> > +{
> > +
> > +    if (mem->padding) {
> > +        return -1;
> > +    }
> > +
> > +    return 0;
> > +}
> > +
> > +static int vhost_vdpa_set_features(struct vhost_dev *dev,
> > +                                   uint64_t features)
> > +{
> > +    int ret;
> > +    ret = vhost_vdpa_call(dev, VHOST_SET_FEATURES, &features);
> > +    uint8_t status = 0;
> > +    if (ret) {
> > +        return ret;
> > +    }
> > +    vhost_vdpa_add_status(dev, VIRTIO_CONFIG_S_FEATURES_OK);
> > +    vhost_vdpa_call(dev, VHOST_VDPA_GET_STATUS, &status);
> > +
> > +    return !(status & VIRTIO_CONFIG_S_FEATURES_OK);
> > +}
> > +
> > +int vhost_vdpa_get_device_id(struct vhost_dev *dev,
> > +                                   uint32_t *device_id)
> > +{
> > +    return vhost_vdpa_call(dev, VHOST_VDPA_GET_DEVICE_ID, device_id);
> > +}
> > +
> > +static int vhost_vdpa_reset_device(struct vhost_dev *dev)
> > +{
> > +    uint8_t status = 0;
> > +
> > +    return vhost_vdpa_call(dev, VHOST_VDPA_SET_STATUS, &status);
> > +}
> > +
> > +static int vhost_vdpa_get_vq_index(struct vhost_dev *dev, int idx)
> > +{
> > +    assert(idx >= dev->vq_index && idx < dev->vq_index + dev->nvqs);
> > +
> > +    return idx - dev->vq_index;
> > +}
> > +
> > +static int vhost_vdpa_set_vring_ready(struct vhost_dev *dev)
> > +{
> > +    int i;
> > +    for (i = 0; i < dev->nvqs; ++i) {
> > +        struct vhost_vring_state state = {
> > +            .index = dev->vq_index + i,
> > +            .num = 1,
> > +        };
> > +        vhost_vdpa_call(dev, VHOST_VDPA_SET_VRING_ENABLE, &state);
> > +    }
> > +    return 0;
> > +}
> > +
> > +static int vhost_vdpa_set_config(struct vhost_dev *dev, const uint8_t *data,
> > +                                   uint32_t offset, uint32_t size,
> > +                                   uint32_t flags)
> > +{
> > +    struct vhost_vdpa_config *config;
> > +    int ret;
> > +    unsigned long config_size = offsetof(struct vhost_vdpa_config, buf);
> > +    config = g_malloc(size + config_size);
> > +    if (config == NULL) {
> > +        return -1;
> > +    }
> > +    config->off = offset;
> > +    config->len = size;
> > +    memcpy(config->buf, data, size);
> > +    ret = vhost_vdpa_call(dev, VHOST_VDPA_SET_CONFIG, config);
> > +    g_free(config);
> > +    return ret;
> > +}
> > +
> > +static int vhost_vdpa_get_config(struct vhost_dev *dev, uint8_t *config,
> > +                                   uint32_t config_len)
> > +{
> > +    struct vhost_vdpa_config *v_config;
> > +    unsigned long config_size = offsetof(struct vhost_vdpa_config, buf);
> > +    int ret;
> > +
> > +    v_config = g_malloc(config_len + config_size);
> > +    if (v_config == NULL) {
> > +        return -1;
> > +    }
> > +    v_config->len = config_len;
> > +    v_config->off = 0;
> > +    ret = vhost_vdpa_call(dev, VHOST_VDPA_GET_CONFIG, v_config);
> > +    memcpy(config, v_config->buf, config_len);
> > +    g_free(v_config);
> > +    return ret;
> > + }
> > +
> > +static int vhost_vdpa_dev_start(struct vhost_dev *dev, bool started)
> > +{
> > +    struct vhost_vdpa *v = dev->opaque;
> > +    if (started) {
> > +        uint8_t status = 0;
> > +        memory_listener_register(&v->listener, &address_space_memory);
> > +        vhost_vdpa_set_vring_ready(dev);
> > +        vhost_vdpa_add_status(dev, VIRTIO_CONFIG_S_DRIVER_OK);
> > +        vhost_vdpa_call(dev, VHOST_VDPA_GET_STATUS, &status);
> > +
> > +        return !(status & VIRTIO_CONFIG_S_DRIVER_OK);
> > +    } else {
> > +        vhost_vdpa_reset_device(dev);
> > +        vhost_vdpa_add_status(dev, VIRTIO_CONFIG_S_ACKNOWLEDGE |
> > +                                   VIRTIO_CONFIG_S_DRIVER);
> > +        memory_listener_unregister(&v->listener);
> > +
> > +        return 0;
> > +    }
> > +}
> > +
> > +const VhostOps vdpa_ops = {
> > +        .backend_type = VHOST_BACKEND_TYPE_VDPA,
> > +        .vhost_backend_init = vhost_vdpa_init,
> > +        .vhost_backend_cleanup = vhost_vdpa_cleanup,
> > +        .vhost_set_log_base = vhost_kernel_set_log_base,
> > +        .vhost_set_vring_addr = vhost_kernel_set_vring_addr,
> > +        .vhost_set_vring_num = vhost_kernel_set_vring_num,
> > +        .vhost_set_vring_base = vhost_kernel_set_vring_base,
> > +        .vhost_get_vring_base = vhost_kernel_get_vring_base,
> > +        .vhost_set_vring_kick = vhost_kernel_set_vring_kick,
> > +        .vhost_set_vring_call = vhost_kernel_set_vring_call,
> > +        .vhost_get_features = vhost_kernel_get_features,
> > +        .vhost_set_owner = vhost_kernel_set_owner,
> > +        .vhost_set_vring_endian = NULL,
> > +        .vhost_backend_memslots_limit = vhost_vdpa_memslots_limit,
> > +        .vhost_set_mem_table = vhost_vdpa_set_mem_table,
> > +        .vhost_set_features = vhost_vdpa_set_features,
> > +        .vhost_reset_device = vhost_vdpa_reset_device,
> > +        .vhost_get_vq_index = vhost_vdpa_get_vq_index,
> > +        .vhost_get_config  = vhost_vdpa_get_config,
> > +        .vhost_set_config = vhost_vdpa_set_config,
> > +        .vhost_requires_shm_log = NULL,
> > +        .vhost_migration_done = NULL,
> > +        .vhost_backend_can_merge = NULL,
> > +        .vhost_net_set_mtu = NULL,
> > +        .vhost_set_iotlb_callback = NULL,
> > +        .vhost_send_device_iotlb_msg = NULL,
> > +        .vhost_dev_start = vhost_vdpa_dev_start,
> > +        .vhost_get_device_id = vhost_vdpa_get_device_id,
> > +};
> > diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
> > index bfd7f9ce1f..a75be7216b 100644
> > --- a/hw/virtio/vhost.c
> > +++ b/hw/virtio/vhost.c
> > @@ -744,19 +744,34 @@ static void vhost_iommu_region_del(MemoryListener *listener,
> >      }
> >  }
> >
> > +static void vhost_virtqueue_get_addr(struct vhost_dev *dev,
> > +                                    struct vhost_vring_addr *addr,
> > +                                    struct vhost_virtqueue *vq)
> > +{
> > +    /*vDPA need to use the IOVA here to set to hardware*/
> > +    if (dev->vhost_ops->backend_type == VHOST_BACKEND_TYPE_VDPA) {
> > +        addr->desc_user_addr = (uint64_t)(unsigned long)vq->desc_phys;
> > +        addr->avail_user_addr = (uint64_t)(unsigned long)vq->avail_phys;
> > +        addr->used_user_addr = (uint64_t)(unsigned long)vq->used_phys;
> > +    } else {
> > +        addr->desc_user_addr = (uint64_t)(unsigned long)vq->desc;
> > +        addr->avail_user_addr = (uint64_t)(unsigned long)vq->avail;
> > +        addr->used_user_addr = (uint64_t)(unsigned long)vq->used;
> > +    }
> > +}
> >
> >  static int vhost_virtqueue_set_addr(struct vhost_dev *dev,
> >                                      struct vhost_virtqueue *vq,
> >                                      unsigned idx, bool enable_log)
> >  {
> > -    struct vhost_vring_addr addr = {
> > -        .index = idx,
> > -        .desc_user_addr = (uint64_t)(unsigned long)vq->desc,
> > -        .avail_user_addr = (uint64_t)(unsigned long)vq->avail,
> > -        .used_user_addr = (uint64_t)(unsigned long)vq->used,
> > -        .log_guest_addr = vq->used_phys,
> > -        .flags = enable_log ? (1 << VHOST_VRING_F_LOG) : 0,
> > -    };
> > +    struct vhost_vring_addr addr;
> > +    memset(&addr, 0, sizeof(struct vhost_vring_addr));
> > +
> > +    vhost_virtqueue_get_addr(dev, &addr, vq);
> > +    addr.index = idx;
> > +    addr .log_guest_addr = vq->used_phys;
> > +    addr .flags = enable_log ? (1 << VHOST_VRING_F_LOG) : 0;
> > +
> >      int r = dev->vhost_ops->vhost_set_vring_addr(dev, &addr);
> >      if (r < 0) {
> >          VHOST_OPS_DEBUG("vhost_set_vring_addr failed");
> > @@ -774,7 +789,9 @@ static int vhost_dev_set_features(struct vhost_dev *dev,
> >          features |= 0x1ULL << VHOST_F_LOG_ALL;
> >      }
> >      if (!vhost_dev_has_iommu(dev)) {
> > -        features &= ~(0x1ULL << VIRTIO_F_IOMMU_PLATFORM);
> > +        if (dev->vhost_ops->backend_type != VHOST_BACKEND_TYPE_VDPA) {
> > +            features &= ~(0x1ULL << VIRTIO_F_IOMMU_PLATFORM);
> > +        }
> >      }
> >      r = dev->vhost_ops->vhost_set_features(dev, features);
> >      if (r < 0) {
> > @@ -1667,7 +1684,8 @@ int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev)
> >          goto fail_log;
> >      }
> >
> > -    if (vhost_dev_has_iommu(hdev)) {
> > +    if (vhost_dev_has_iommu(hdev) &&
> > +        hdev->vhost_ops->vhost_set_iotlb_callback) {
> >          hdev->vhost_ops->vhost_set_iotlb_callback(hdev, true);
> >
> >          /* Update used ring information for IOTLB to work correctly,
> > @@ -1713,7 +1731,9 @@ void vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev)
> >      }
> >
> >      if (vhost_dev_has_iommu(hdev)) {
> > -        hdev->vhost_ops->vhost_set_iotlb_callback(hdev, false);
> > +        if (hdev->vhost_ops->vhost_set_iotlb_callback) {
> > +            hdev->vhost_ops->vhost_set_iotlb_callback(hdev, false);
> > +        }
> >          memory_listener_unregister(&hdev->iommu_listener);
> >      }
> >      vhost_log_put(hdev, true);
> > diff --git a/include/hw/virtio/vhost-backend.h b/include/hw/virtio/vhost-backend.h
> > index c1384bd2c7..c418c2fa0e 100644
> > --- a/include/hw/virtio/vhost-backend.h
> > +++ b/include/hw/virtio/vhost-backend.h
> > @@ -17,7 +17,8 @@ typedef enum VhostBackendType {
> >      VHOST_BACKEND_TYPE_NONE = 0,
> >      VHOST_BACKEND_TYPE_KERNEL = 1,
> >      VHOST_BACKEND_TYPE_USER = 2,
> > -    VHOST_BACKEND_TYPE_MAX = 3,
> > +    VHOST_BACKEND_TYPE_VDPA = 3,
> > +    VHOST_BACKEND_TYPE_MAX = 4,
> >  } VhostBackendType;
> >
> >  typedef enum VhostSetConfigType {
> > @@ -113,6 +114,7 @@ typedef int (*vhost_set_inflight_fd_op)(struct vhost_dev *dev,
> >                                          struct vhost_inflight *inflight);
> >
> >  typedef int (*vhost_dev_start_op)(struct vhost_dev *dev, bool started);
> > +typedef int (*vhost_get_device_id_op)(struct vhost_dev *dev, uint32_t *dev_id);
> >  typedef struct VhostOps {
> >      VhostBackendType backend_type;
> >      vhost_backend_init vhost_backend_init;
> > @@ -154,9 +156,11 @@ typedef struct VhostOps {
> >      vhost_get_inflight_fd_op vhost_get_inflight_fd;
> >      vhost_set_inflight_fd_op vhost_set_inflight_fd;
> >      vhost_dev_start_op vhost_dev_start;
> > +    vhost_get_device_id_op vhost_get_device_id;
> >  } VhostOps;
> >
> >  extern const VhostOps user_ops;
> > +extern const VhostOps vdpa_ops;
> >
> >  int vhost_set_backend_type(struct vhost_dev *dev,
> >                             VhostBackendType backend_type);
> > diff --git a/include/hw/virtio/vhost-vdpa.h b/include/hw/virtio/vhost-vdpa.h
> > new file mode 100644
> > index 0000000000..6455663388
> > --- /dev/null
> > +++ b/include/hw/virtio/vhost-vdpa.h
> > @@ -0,0 +1,26 @@
> > +/*
> > + * vhost-vdpa.h
> > + *
> > + * Copyright(c) 2017-2018 Intel Corporation.
> > + * Copyright(c) 2020 Red Hat, Inc.
> > + *
> > + * This work is licensed under the terms of the GNU GPL, version 2 or later.
> > + * See the COPYING file in the top-level directory.
> > + *
> > + */
> > +
> > +#ifndef HW_VIRTIO_VHOST_VDPA_H
> > +#define HW_VIRTIO_VHOST_VDPA_H
> > +
> > +#include "hw/virtio/virtio.h"
> > +
> > +typedef struct vhost_vdpa {
> > +    int device_fd;
> > +    uint32_t msg_type;
> > +    MemoryListener listener;
> > +} VhostVDPA;
> > +
> > +extern AddressSpace address_space_memory;
> > +extern int vhost_vdpa_get_device_id(struct vhost_dev *dev,
> > +                                   uint32_t *device_id);
> > +#endif
> > diff --git a/include/hw/virtio/vhost.h b/include/hw/virtio/vhost.h
> > index 59ea53f8c2..f69b5e4a02 100644
> > --- a/include/hw/virtio/vhost.h
> > +++ b/include/hw/virtio/vhost.h
> > @@ -92,6 +92,12 @@ struct vhost_dev {
> >      const VhostDevConfigOps *config_ops;
> >  };
> >
> > +struct vhost_net {
> > +    struct vhost_dev dev;
> > +    struct vhost_virtqueue vqs[2];
> > +    int backend;
> > +    NetClientState *nc;
> > +};
> >
> >  int vhost_dev_init(struct vhost_dev *hdev, void *opaque,
> >                     VhostBackendType backend_type,
> > diff --git a/qemu-options.hx b/qemu-options.hx
> > index 292d4e7c0c..d7d0daaa0e 100644
> > --- a/qemu-options.hx
> > +++ b/qemu-options.hx
> > @@ -2409,6 +2409,10 @@ DEF("netdev", HAS_ARG, QEMU_OPTION_netdev,
> >  #ifdef CONFIG_POSIX
> >      "-netdev vhost-user,id=str,chardev=dev[,vhostforce=on|off]\n"
> >      "                configure a vhost-user network, backed by a chardev 'dev'\n"
> > +#endif
> > +#ifdef __linux__
> > +    "-netdev vhost-vdpa,id=str,vhostdev=/path/to/dev\n"
> > +    "                configure a vhost-vdpa network,Establish a vhost-vdpa netdev\n"
> >  #endif
> >      "-netdev hubport,id=str,hubid=n[,netdev=nd]\n"
> >      "                configure a hub port on the hub with ID 'n'\n", QEMU_ARCH_ALL)
> > @@ -2888,6 +2892,14 @@ SRST
> >               -netdev type=vhost-user,id=net0,chardev=chr0 \
> >               -device virtio-net-pci,netdev=net0
> >
> > +``-netdev vhost-vdpa,vhostdev=/path/to/dev``
> > +    Establish a vhost-vdpa netdev.
> > +
> > +    vDPA device is a device that uses a datapath which complies with
> > +    the virtio specifications with a vendor specific control path.
> > +    vDPA devices can be both physically located on the hardware or
> > +    emulated by software.
> > +
> >  ``-netdev hubport,id=id,hubid=hubid[,netdev=nd]``
> >      Create a hub port on the emulated hub with ID hubid.
> >
> >
>



^ permalink raw reply	[flat|nested] 46+ messages in thread

end of thread, other threads:[~2020-06-30  8:58 UTC | newest]

Thread overview: 46+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-06-22 15:37 [PATCH v1 00/10] vDPA support in qemu Cindy Lu
2020-06-22 15:37 ` [PATCH v1 01/10] net: introduce qemu_get_peer Cindy Lu
2020-06-23  7:10   ` Jason Wang
2020-06-23  9:17     ` Cindy Lu
2020-06-22 15:37 ` [PATCH v1 02/10] vhost_net: use the function qemu_get_peer Cindy Lu
2020-06-24 13:20   ` Laurent Vivier
2020-06-22 15:37 ` [PATCH v1 03/10] virtio-bus: introduce queue_enabled method Cindy Lu
2020-06-22 15:37 ` [PATCH v1 04/10] virtio-pci: implement " Cindy Lu
2020-06-23  7:13   ` Jason Wang
2020-06-23  9:18     ` Cindy Lu
2020-06-24 13:24   ` Laurent Vivier
2020-06-29  7:02     ` Cindy Lu
2020-06-22 15:37 ` [PATCH v1 05/10] vhost-backend: export the vhost backend helper Cindy Lu
2020-06-25 15:07   ` Laurent Vivier
2020-06-30  6:27     ` Cindy Lu
2020-06-22 15:37 ` [PATCH v1 06/10] vhsot_net: introduce set_config & get_config function Cindy Lu
2020-06-23  7:18   ` Jason Wang
2020-06-23  9:22     ` Cindy Lu
2020-06-22 15:37 ` [PATCH v1 07/10] vhost: introduce new VhostOps vhost_dev_start Cindy Lu
2020-06-22 15:37 ` [PATCH v1 08/10] vhost: implement vhost_dev_start method Cindy Lu
2020-06-23  7:21   ` Jason Wang
2020-06-23  9:34     ` Cindy Lu
2020-06-23  9:37       ` Jason Wang
2020-06-23  9:39         ` Cindy Lu
2020-06-25 14:35   ` Laurent Vivier
2020-06-29  7:01     ` Cindy Lu
2020-06-22 15:37 ` [PATCH v1 09/10] vhost-vdpa: introduce vhost-vdpa backend Cindy Lu
2020-06-23  7:31   ` Jason Wang
2020-06-23  9:38     ` Cindy Lu
2020-06-25 12:36   ` Laurent Vivier
2020-06-28  1:35     ` Cindy Lu
2020-06-30  7:18   ` Maxime Coquelin
2020-06-30  8:56     ` Cindy Lu
2020-06-22 15:37 ` [PATCH v1 10/10] vhost-vdpa: introduce vhost-vdpa net client Cindy Lu
2020-06-23  7:12   ` Markus Armbruster
2020-06-23  9:19     ` Cindy Lu
2020-06-23  8:56   ` Jason Wang
2020-06-23  9:57     ` Cindy Lu
2020-06-23  7:07 ` [PATCH v1 00/10] vDPA support in qemu Markus Armbruster
2020-06-23  9:16   ` Cindy Lu
2020-06-23  9:43     ` Jason Wang
2020-06-24  9:42       ` Cindy Lu
2020-06-25  4:48         ` Markus Armbruster
2020-06-28  1:37           ` Cindy Lu
2020-06-28  7:06 ` Jason Wang
2020-06-28  8:19   ` Cindy Lu

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.