[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [RFC PATCH 4/4] vhost-user: extend the vhost-user Master (c
From: |
Wei Wang |
Subject: |
[Qemu-devel] [RFC PATCH 4/4] vhost-user: extend the vhost-user Master (client) part to support vhost-pci |
Date: |
Wed, 9 Nov 2016 21:47:49 -0500 |
Signed-off-by: Wei Wang <address@hidden>
---
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 --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
--
2.7.4