diff mbox

[RFC,4/4] vhost-user: extend the vhost-user Master (client) part to support vhost-pci

Message ID 1478746069-79574-5-git-send-email-wei.w.wang@intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

Wang, Wei W Nov. 10, 2016, 2:47 a.m. UTC
Signed-off-by: Wei Wang <wei.w.wang@intel.com>
---
 hw/net/vhost_net.c                | 20 ++++++++++++
 hw/virtio/vhost-user.c            | 66 +++++++++++++++++++++++++++++++++++++++
 include/hw/virtio/vhost-backend.h |  3 ++
 include/net/vhost_net.h           |  5 +++
 4 files changed, 94 insertions(+)
diff mbox

Patch

diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c
index f2d49ad..100349b 100644
--- a/hw/net/vhost_net.c
+++ b/hw/net/vhost_net.c
@@ -337,6 +337,9 @@  int vhost_net_start(VirtIODevice *dev, NetClientState *ncs,
         }
     }
 
+    vhost_set_peer_connection(ncs[i-1].peer,
+                              VHOST_USER_SET_PEER_CONNECTION_INIT);
+
     return 0;
 
 err_start:
@@ -435,6 +438,18 @@  int vhost_set_vring_enable(NetClientState *nc, int enable)
     return 0;
 }
 
+int vhost_set_peer_connection(NetClientState *nc, uint64_t cmd)
+{
+    VHostNetState *net = get_vhost_net(nc);
+    const VhostOps *vhost_ops = net->dev.vhost_ops;
+
+    if (vhost_ops && vhost_ops->vhost_set_peer_connection) {
+        return vhost_ops->vhost_set_peer_connection(&net->dev, cmd);
+    }
+
+    return 0;
+}
+
 #else
 uint64_t vhost_net_get_max_queues(VHostNetState *net)
 {
@@ -501,4 +516,9 @@  int vhost_set_vring_enable(NetClientState *nc, int enable)
 {
     return 0;
 }
+
+int vhost_set_peer_connection(NetClientState *nc, uint64_t cmd)
+{
+    return 0;
+}
 #endif
diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c
index bce5181..6edf7f2 100644
--- a/hw/virtio/vhost-user.c
+++ b/hw/virtio/vhost-user.c
@@ -124,6 +124,8 @@  static int vhost_user_write(struct vhost_dev *dev, VhostUserMsg *msg,
         return 0;
     }
 
+    msg->conn_id = chr->conn_id;
+
     if (qemu_chr_fe_set_msgfds(chr, fds, fd_num) < 0) {
         error_report("Failed to set msg fds.");
         return -1;
@@ -313,6 +315,22 @@  static int vhost_user_set_vring_enable(struct vhost_dev *dev, int enable)
     return 0;
 }
 
+static int vhost_user_set_peer_connection(struct vhost_dev *dev, uint64_t cmd)
+{
+    VhostUserMsg msg = {
+        .request = VHOST_USER_SET_PEER_CONNECTION,
+        .flags = VHOST_USER_VERSION,
+        .payload.u64 = cmd,
+        .size = sizeof(msg.payload.u64),
+    };
+
+    if (vhost_user_write(dev, &msg, NULL, 0) < 0) {
+        return -1;
+    }
+
+    return 0;
+}
+
 static int vhost_user_get_vring_base(struct vhost_dev *dev,
                                      struct vhost_vring_state *ring)
 {
@@ -448,6 +466,28 @@  static int vhost_user_get_u64(struct vhost_dev *dev, int request, uint64_t *u64)
     return 0;
 }
 
+static bool vhost_user_need_conn_id(struct vhost_dev *dev)
+{
+    CharDriverState *chr = dev->opaque;
+
+    if(chr->conn_id == ANONYMOUS_CLIENT)
+        return 1;
+    else
+        return 0;
+}
+
+static int vhost_user_get_conn_id(struct vhost_dev *dev)
+{
+    int ret;
+    uint64_t conn_id;
+    CharDriverState *chr = dev->opaque;
+
+    ret = vhost_user_get_u64(dev, VHOST_USER_GET_CONN_ID, &conn_id);
+    if (!ret)
+        chr->conn_id = conn_id;
+    return ret;
+}
+
 static int vhost_user_get_features(struct vhost_dev *dev, uint64_t *features)
 {
     return vhost_user_get_u64(dev, VHOST_USER_GET_FEATURES, features);
@@ -481,6 +521,18 @@  static int vhost_user_reset_device(struct vhost_dev *dev)
     return 0;
 }
 
+static int vhost_user_set_dev_info(struct vhost_dev *dev, uint16_t virtio_id)
+{
+    VhostUserMsg msg = {
+        .request = VHOST_USER_SET_DEV_INFO,
+        .flags = VHOST_USER_VERSION,
+        .payload.dev_info.virtio_id = virtio_id,
+        .size = sizeof(msg.payload.dev_info),
+    };
+
+    return vhost_user_write(dev, &msg, NULL, 0);
+}
+
 static int vhost_user_init(struct vhost_dev *dev, void *opaque)
 {
     uint64_t features;
@@ -489,6 +541,12 @@  static int vhost_user_init(struct vhost_dev *dev, void *opaque)
     assert(dev->vhost_ops->backend_type == VHOST_BACKEND_TYPE_USER);
 
     dev->opaque = opaque;
+    if (vhost_user_need_conn_id(dev)) {
+        err = vhost_user_get_conn_id(dev);
+        if (err < 0) {
+            return err;
+        }
+    }
 
     err = vhost_user_get_features(dev, &features);
     if (err < 0) {
@@ -510,6 +568,13 @@  static int vhost_user_init(struct vhost_dev *dev, void *opaque)
             return err;
         }
 
+        if (dev->protocol_features & (1ULL << VHOST_USER_PROTOCOL_F_VHOST_PCI)) {
+            err = vhost_user_set_dev_info(dev, VIRTIO_ID_NET);
+            if (err < 0) {
+                return err;
+            }
+        }
+
         /* query the max queues we support if backend supports Multiple Queue */
         if (dev->protocol_features & (1ULL << VHOST_USER_PROTOCOL_F_MQ)) {
             err = vhost_user_get_u64(dev, VHOST_USER_GET_QUEUE_NUM,
@@ -621,6 +686,7 @@  const VhostOps user_ops = {
         .vhost_reset_device = vhost_user_reset_device,
         .vhost_get_vq_index = vhost_user_get_vq_index,
         .vhost_set_vring_enable = vhost_user_set_vring_enable,
+        .vhost_set_peer_connection = vhost_user_set_peer_connection,
         .vhost_requires_shm_log = vhost_user_requires_shm_log,
         .vhost_migration_done = vhost_user_migration_done,
         .vhost_backend_can_merge = vhost_user_can_merge,
diff --git a/include/hw/virtio/vhost-backend.h b/include/hw/virtio/vhost-backend.h
index cf7f0b5..955dea6 100644
--- a/include/hw/virtio/vhost-backend.h
+++ b/include/hw/virtio/vhost-backend.h
@@ -67,6 +67,8 @@  typedef int (*vhost_reset_device_op)(struct vhost_dev *dev);
 typedef int (*vhost_get_vq_index_op)(struct vhost_dev *dev, int idx);
 typedef int (*vhost_set_vring_enable_op)(struct vhost_dev *dev,
                                          int enable);
+typedef int (*vhost_set_peer_connection_op)(struct vhost_dev *dev,
+                                            uint64_t cmd);
 typedef bool (*vhost_requires_shm_log_op)(struct vhost_dev *dev);
 typedef int (*vhost_migration_done_op)(struct vhost_dev *dev,
                                        char *mac_addr);
@@ -99,6 +101,7 @@  typedef struct VhostOps {
     vhost_reset_device_op vhost_reset_device;
     vhost_get_vq_index_op vhost_get_vq_index;
     vhost_set_vring_enable_op vhost_set_vring_enable;
+    vhost_set_peer_connection_op vhost_set_peer_connection;
     vhost_requires_shm_log_op vhost_requires_shm_log;
     vhost_migration_done_op vhost_migration_done;
     vhost_backend_can_merge_op vhost_backend_can_merge;
diff --git a/include/net/vhost_net.h b/include/net/vhost_net.h
index 5a08eff..baa5a34 100644
--- a/include/net/vhost_net.h
+++ b/include/net/vhost_net.h
@@ -33,6 +33,11 @@  VHostNetState *get_vhost_net(NetClientState *nc);
 
 int vhost_set_vring_enable(NetClientState * nc, int enable);
 
+#define VHOST_USER_SET_PEER_CONNECTION_OFF  0
+#define VHOST_USER_SET_PEER_CONNECTION_ON   1
+#define VHOST_USER_SET_PEER_CONNECTION_INIT 2
+int vhost_set_peer_connection(NetClientState *nc, uint64_t cmd);
+
 uint64_t vhost_net_get_acked_features(VHostNetState *net);
 
 #endif