|
|
ae23c9 |
From 672f445642c474d54500ca8d080d64d8a8d4dbd9 Mon Sep 17 00:00:00 2001
|
|
|
ae23c9 |
From: "plai@redhat.com" <plai@redhat.com>
|
|
|
ae23c9 |
Date: Thu, 21 Jun 2018 18:54:45 +0200
|
|
|
ae23c9 |
Subject: [PATCH 166/268] libvhost-user: support host notifier
|
|
|
ae23c9 |
|
|
|
ae23c9 |
RH-Author: plai@redhat.com
|
|
|
ae23c9 |
Message-id: <1529607285-9942-11-git-send-email-plai@redhat.com>
|
|
|
ae23c9 |
Patchwork-id: 80939
|
|
|
ae23c9 |
O-Subject: [RHEL7.6 PATCH BZ 1526645 10/10] libvhost-user: support host notifier
|
|
|
ae23c9 |
Bugzilla: 1526645
|
|
|
ae23c9 |
RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
|
|
|
ae23c9 |
RH-Acked-by: Maxime Coquelin <maxime.coquelin@redhat.com>
|
|
|
ae23c9 |
RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
|
|
|
ae23c9 |
|
|
|
ae23c9 |
From: Tiwei Bie <tiwei.bie@intel.com>
|
|
|
ae23c9 |
|
|
|
ae23c9 |
This patch introduces the host notifier support in
|
|
|
ae23c9 |
libvhost-user. A new API is added to support setting
|
|
|
ae23c9 |
host notifier for each queue.
|
|
|
ae23c9 |
|
|
|
ae23c9 |
Signed-off-by: Tiwei Bie <tiwei.bie@intel.com>
|
|
|
ae23c9 |
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
|
|
|
ae23c9 |
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
|
|
|
ae23c9 |
(cherry picked from commit d84599f56c820d8c1ac9928a76500dcdfbbf194d)
|
|
|
ae23c9 |
Signed-off-by: Paul Lai <plai@redhat.com>
|
|
|
ae23c9 |
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
|
ae23c9 |
---
|
|
|
ae23c9 |
contrib/libvhost-user/libvhost-user.c | 81 +++++++++++++++++++++++++++++++----
|
|
|
ae23c9 |
contrib/libvhost-user/libvhost-user.h | 32 ++++++++++++++
|
|
|
ae23c9 |
2 files changed, 105 insertions(+), 8 deletions(-)
|
|
|
ae23c9 |
|
|
|
ae23c9 |
diff --git a/contrib/libvhost-user/libvhost-user.c b/contrib/libvhost-user/libvhost-user.c
|
|
|
ae23c9 |
index beeed0c..fa06eee 100644
|
|
|
ae23c9 |
--- a/contrib/libvhost-user/libvhost-user.c
|
|
|
ae23c9 |
+++ b/contrib/libvhost-user/libvhost-user.c
|
|
|
ae23c9 |
@@ -314,11 +314,6 @@ vu_message_write(VuDev *dev, int conn_fd, VhostUserMsg *vmsg)
|
|
|
ae23c9 |
msg.msg_controllen = 0;
|
|
|
ae23c9 |
}
|
|
|
ae23c9 |
|
|
|
ae23c9 |
- /* Set the version in the flags when sending the reply */
|
|
|
ae23c9 |
- vmsg->flags &= ~VHOST_USER_VERSION_MASK;
|
|
|
ae23c9 |
- vmsg->flags |= VHOST_USER_VERSION;
|
|
|
ae23c9 |
- vmsg->flags |= VHOST_USER_REPLY_MASK;
|
|
|
ae23c9 |
-
|
|
|
ae23c9 |
do {
|
|
|
ae23c9 |
rc = sendmsg(conn_fd, &msg, 0);
|
|
|
ae23c9 |
} while (rc < 0 && (errno == EINTR || errno == EAGAIN));
|
|
|
ae23c9 |
@@ -339,6 +334,39 @@ vu_message_write(VuDev *dev, int conn_fd, VhostUserMsg *vmsg)
|
|
|
ae23c9 |
return true;
|
|
|
ae23c9 |
}
|
|
|
ae23c9 |
|
|
|
ae23c9 |
+static bool
|
|
|
ae23c9 |
+vu_send_reply(VuDev *dev, int conn_fd, VhostUserMsg *vmsg)
|
|
|
ae23c9 |
+{
|
|
|
ae23c9 |
+ /* Set the version in the flags when sending the reply */
|
|
|
ae23c9 |
+ vmsg->flags &= ~VHOST_USER_VERSION_MASK;
|
|
|
ae23c9 |
+ vmsg->flags |= VHOST_USER_VERSION;
|
|
|
ae23c9 |
+ vmsg->flags |= VHOST_USER_REPLY_MASK;
|
|
|
ae23c9 |
+
|
|
|
ae23c9 |
+ return vu_message_write(dev, conn_fd, vmsg);
|
|
|
ae23c9 |
+}
|
|
|
ae23c9 |
+
|
|
|
ae23c9 |
+static bool
|
|
|
ae23c9 |
+vu_process_message_reply(VuDev *dev, const VhostUserMsg *vmsg)
|
|
|
ae23c9 |
+{
|
|
|
ae23c9 |
+ VhostUserMsg msg_reply;
|
|
|
ae23c9 |
+
|
|
|
ae23c9 |
+ if ((vmsg->flags & VHOST_USER_NEED_REPLY_MASK) == 0) {
|
|
|
ae23c9 |
+ return true;
|
|
|
ae23c9 |
+ }
|
|
|
ae23c9 |
+
|
|
|
ae23c9 |
+ if (!vu_message_read(dev, dev->slave_fd, &msg_reply)) {
|
|
|
ae23c9 |
+ return false;
|
|
|
ae23c9 |
+ }
|
|
|
ae23c9 |
+
|
|
|
ae23c9 |
+ if (msg_reply.request != vmsg->request) {
|
|
|
ae23c9 |
+ DPRINT("Received unexpected msg type. Expected %d received %d",
|
|
|
ae23c9 |
+ vmsg->request, msg_reply.request);
|
|
|
ae23c9 |
+ return false;
|
|
|
ae23c9 |
+ }
|
|
|
ae23c9 |
+
|
|
|
ae23c9 |
+ return msg_reply.payload.u64 == 0;
|
|
|
ae23c9 |
+}
|
|
|
ae23c9 |
+
|
|
|
ae23c9 |
/* Kick the log_call_fd if required. */
|
|
|
ae23c9 |
static void
|
|
|
ae23c9 |
vu_log_kick(VuDev *dev)
|
|
|
ae23c9 |
@@ -534,7 +562,7 @@ vu_set_mem_table_exec_postcopy(VuDev *dev, VhostUserMsg *vmsg)
|
|
|
ae23c9 |
|
|
|
ae23c9 |
/* Send the message back to qemu with the addresses filled in */
|
|
|
ae23c9 |
vmsg->fd_num = 0;
|
|
|
ae23c9 |
- if (!vu_message_write(dev, dev->sock, vmsg)) {
|
|
|
ae23c9 |
+ if (!vu_send_reply(dev, dev->sock, vmsg)) {
|
|
|
ae23c9 |
vu_panic(dev, "failed to respond to set-mem-table for postcopy");
|
|
|
ae23c9 |
return false;
|
|
|
ae23c9 |
}
|
|
|
ae23c9 |
@@ -914,6 +942,41 @@ void vu_set_queue_handler(VuDev *dev, VuVirtq *vq,
|
|
|
ae23c9 |
}
|
|
|
ae23c9 |
}
|
|
|
ae23c9 |
|
|
|
ae23c9 |
+bool vu_set_queue_host_notifier(VuDev *dev, VuVirtq *vq, int fd,
|
|
|
ae23c9 |
+ int size, int offset)
|
|
|
ae23c9 |
+{
|
|
|
ae23c9 |
+ int qidx = vq - dev->vq;
|
|
|
ae23c9 |
+ int fd_num = 0;
|
|
|
ae23c9 |
+ VhostUserMsg vmsg = {
|
|
|
ae23c9 |
+ .request = VHOST_USER_SLAVE_VRING_HOST_NOTIFIER_MSG,
|
|
|
ae23c9 |
+ .flags = VHOST_USER_VERSION | VHOST_USER_NEED_REPLY_MASK,
|
|
|
ae23c9 |
+ .size = sizeof(vmsg.payload.area),
|
|
|
ae23c9 |
+ .payload.area = {
|
|
|
ae23c9 |
+ .u64 = qidx & VHOST_USER_VRING_IDX_MASK,
|
|
|
ae23c9 |
+ .size = size,
|
|
|
ae23c9 |
+ .offset = offset,
|
|
|
ae23c9 |
+ },
|
|
|
ae23c9 |
+ };
|
|
|
ae23c9 |
+
|
|
|
ae23c9 |
+ if (fd == -1) {
|
|
|
ae23c9 |
+ vmsg.payload.area.u64 |= VHOST_USER_VRING_NOFD_MASK;
|
|
|
ae23c9 |
+ } else {
|
|
|
ae23c9 |
+ vmsg.fds[fd_num++] = fd;
|
|
|
ae23c9 |
+ }
|
|
|
ae23c9 |
+
|
|
|
ae23c9 |
+ vmsg.fd_num = fd_num;
|
|
|
ae23c9 |
+
|
|
|
ae23c9 |
+ if ((dev->protocol_features & VHOST_USER_PROTOCOL_F_SLAVE_SEND_FD) == 0) {
|
|
|
ae23c9 |
+ return false;
|
|
|
ae23c9 |
+ }
|
|
|
ae23c9 |
+
|
|
|
ae23c9 |
+ if (!vu_message_write(dev, dev->slave_fd, &vmsg)) {
|
|
|
ae23c9 |
+ return false;
|
|
|
ae23c9 |
+ }
|
|
|
ae23c9 |
+
|
|
|
ae23c9 |
+ return vu_process_message_reply(dev, &vmsg);
|
|
|
ae23c9 |
+}
|
|
|
ae23c9 |
+
|
|
|
ae23c9 |
static bool
|
|
|
ae23c9 |
vu_set_vring_call_exec(VuDev *dev, VhostUserMsg *vmsg)
|
|
|
ae23c9 |
{
|
|
|
ae23c9 |
@@ -966,7 +1029,9 @@ static bool
|
|
|
ae23c9 |
vu_get_protocol_features_exec(VuDev *dev, VhostUserMsg *vmsg)
|
|
|
ae23c9 |
{
|
|
|
ae23c9 |
uint64_t features = 1ULL << VHOST_USER_PROTOCOL_F_LOG_SHMFD |
|
|
|
ae23c9 |
- 1ULL << VHOST_USER_PROTOCOL_F_SLAVE_REQ;
|
|
|
ae23c9 |
+ 1ULL << VHOST_USER_PROTOCOL_F_SLAVE_REQ |
|
|
|
ae23c9 |
+ 1ULL << VHOST_USER_PROTOCOL_F_HOST_NOTIFIER |
|
|
|
ae23c9 |
+ 1ULL << VHOST_USER_PROTOCOL_F_SLAVE_SEND_FD;
|
|
|
ae23c9 |
|
|
|
ae23c9 |
if (have_userfault()) {
|
|
|
ae23c9 |
features |= 1ULL << VHOST_USER_PROTOCOL_F_PAGEFAULT;
|
|
|
ae23c9 |
@@ -1250,7 +1315,7 @@ vu_dispatch(VuDev *dev)
|
|
|
ae23c9 |
goto end;
|
|
|
ae23c9 |
}
|
|
|
ae23c9 |
|
|
|
ae23c9 |
- if (!vu_message_write(dev, dev->sock, &vmsg)) {
|
|
|
ae23c9 |
+ if (!vu_send_reply(dev, dev->sock, &vmsg)) {
|
|
|
ae23c9 |
goto end;
|
|
|
ae23c9 |
}
|
|
|
ae23c9 |
|
|
|
ae23c9 |
diff --git a/contrib/libvhost-user/libvhost-user.h b/contrib/libvhost-user/libvhost-user.h
|
|
|
ae23c9 |
index b27075e..4aa55b4 100644
|
|
|
ae23c9 |
--- a/contrib/libvhost-user/libvhost-user.h
|
|
|
ae23c9 |
+++ b/contrib/libvhost-user/libvhost-user.h
|
|
|
ae23c9 |
@@ -51,6 +51,8 @@ enum VhostUserProtocolFeature {
|
|
|
ae23c9 |
VHOST_USER_PROTOCOL_F_CRYPTO_SESSION = 7,
|
|
|
ae23c9 |
VHOST_USER_PROTOCOL_F_PAGEFAULT = 8,
|
|
|
ae23c9 |
VHOST_USER_PROTOCOL_F_CONFIG = 9,
|
|
|
ae23c9 |
+ VHOST_USER_PROTOCOL_F_SLAVE_SEND_FD = 10,
|
|
|
ae23c9 |
+ VHOST_USER_PROTOCOL_F_HOST_NOTIFIER = 11,
|
|
|
ae23c9 |
|
|
|
ae23c9 |
VHOST_USER_PROTOCOL_F_MAX
|
|
|
ae23c9 |
};
|
|
|
ae23c9 |
@@ -92,6 +94,14 @@ typedef enum VhostUserRequest {
|
|
|
ae23c9 |
VHOST_USER_MAX
|
|
|
ae23c9 |
} VhostUserRequest;
|
|
|
ae23c9 |
|
|
|
ae23c9 |
+typedef enum VhostUserSlaveRequest {
|
|
|
ae23c9 |
+ VHOST_USER_SLAVE_NONE = 0,
|
|
|
ae23c9 |
+ VHOST_USER_SLAVE_IOTLB_MSG = 1,
|
|
|
ae23c9 |
+ VHOST_USER_SLAVE_CONFIG_CHANGE_MSG = 2,
|
|
|
ae23c9 |
+ VHOST_USER_SLAVE_VRING_HOST_NOTIFIER_MSG = 3,
|
|
|
ae23c9 |
+ VHOST_USER_SLAVE_MAX
|
|
|
ae23c9 |
+} VhostUserSlaveRequest;
|
|
|
ae23c9 |
+
|
|
|
ae23c9 |
typedef struct VhostUserMemoryRegion {
|
|
|
ae23c9 |
uint64_t guest_phys_addr;
|
|
|
ae23c9 |
uint64_t memory_size;
|
|
|
ae23c9 |
@@ -122,6 +132,12 @@ static VhostUserConfig c __attribute__ ((unused));
|
|
|
ae23c9 |
+ sizeof(c.size) \
|
|
|
ae23c9 |
+ sizeof(c.flags))
|
|
|
ae23c9 |
|
|
|
ae23c9 |
+typedef struct VhostUserVringArea {
|
|
|
ae23c9 |
+ uint64_t u64;
|
|
|
ae23c9 |
+ uint64_t size;
|
|
|
ae23c9 |
+ uint64_t offset;
|
|
|
ae23c9 |
+} VhostUserVringArea;
|
|
|
ae23c9 |
+
|
|
|
ae23c9 |
#if defined(_WIN32)
|
|
|
ae23c9 |
# define VU_PACKED __attribute__((gcc_struct, packed))
|
|
|
ae23c9 |
#else
|
|
|
ae23c9 |
@@ -133,6 +149,7 @@ typedef struct VhostUserMsg {
|
|
|
ae23c9 |
|
|
|
ae23c9 |
#define VHOST_USER_VERSION_MASK (0x3)
|
|
|
ae23c9 |
#define VHOST_USER_REPLY_MASK (0x1 << 2)
|
|
|
ae23c9 |
+#define VHOST_USER_NEED_REPLY_MASK (0x1 << 3)
|
|
|
ae23c9 |
uint32_t flags;
|
|
|
ae23c9 |
uint32_t size; /* the following payload size */
|
|
|
ae23c9 |
|
|
|
ae23c9 |
@@ -145,6 +162,7 @@ typedef struct VhostUserMsg {
|
|
|
ae23c9 |
VhostUserMemory memory;
|
|
|
ae23c9 |
VhostUserLog log;
|
|
|
ae23c9 |
VhostUserConfig config;
|
|
|
ae23c9 |
+ VhostUserVringArea area;
|
|
|
ae23c9 |
} payload;
|
|
|
ae23c9 |
|
|
|
ae23c9 |
int fds[VHOST_MEMORY_MAX_NREGIONS];
|
|
|
ae23c9 |
@@ -368,6 +386,20 @@ VuVirtq *vu_get_queue(VuDev *dev, int qidx);
|
|
|
ae23c9 |
void vu_set_queue_handler(VuDev *dev, VuVirtq *vq,
|
|
|
ae23c9 |
vu_queue_handler_cb handler);
|
|
|
ae23c9 |
|
|
|
ae23c9 |
+/**
|
|
|
ae23c9 |
+ * vu_set_queue_host_notifier:
|
|
|
ae23c9 |
+ * @dev: a VuDev context
|
|
|
ae23c9 |
+ * @vq: a VuVirtq queue
|
|
|
ae23c9 |
+ * @fd: a file descriptor
|
|
|
ae23c9 |
+ * @size: host page size
|
|
|
ae23c9 |
+ * @offset: notifier offset in @fd file
|
|
|
ae23c9 |
+ *
|
|
|
ae23c9 |
+ * Set queue's host notifier. This function may be called several
|
|
|
ae23c9 |
+ * times for the same queue. If called with -1 @fd, the notifier
|
|
|
ae23c9 |
+ * is removed.
|
|
|
ae23c9 |
+ */
|
|
|
ae23c9 |
+bool vu_set_queue_host_notifier(VuDev *dev, VuVirtq *vq, int fd,
|
|
|
ae23c9 |
+ int size, int offset);
|
|
|
ae23c9 |
|
|
|
ae23c9 |
/**
|
|
|
ae23c9 |
* vu_queue_set_notification:
|
|
|
ae23c9 |
--
|
|
|
ae23c9 |
1.8.3.1
|
|
|
ae23c9 |
|