aboutsummaryrefslogtreecommitdiff
path: root/hw/virtio
diff options
context:
space:
mode:
authorDr. David Alan Gilbert <dgilbert@redhat.com>2018-03-12 17:21:07 +0000
committerMichael S. Tsirkin <mst@redhat.com>2018-03-20 05:03:28 +0200
commit55d754b307f6e10503dcf2e2136e6e0aef8c80f5 (patch)
treee5cf51b84a2fdc9c1ae8f1d465f1da7a2ae99d36 /hw/virtio
parent6864a7b5aced6d8d9b287b92db8d7a996ea2e8a3 (diff)
postcopy+vhost-user: Split set_mem_table for postcopy
Split the set_mem_table routines in both qemu and libvhost-user because the postcopy versions are going to be quite different once changes in the later patches are added. However, this patch doesn't produce any functional change, just the split. Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com> Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Diffstat (limited to 'hw/virtio')
-rw-r--r--hw/virtio/vhost-user.c77
1 files changed, 75 insertions, 2 deletions
diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c
index c3ab2994fb..b6757ebae3 100644
--- a/hw/virtio/vhost-user.c
+++ b/hw/virtio/vhost-user.c
@@ -340,15 +340,86 @@ static int vhost_user_set_log_base(struct vhost_dev *dev, uint64_t base,
return 0;
}
+static int vhost_user_set_mem_table_postcopy(struct vhost_dev *dev,
+ struct vhost_memory *mem)
+{
+ int fds[VHOST_MEMORY_MAX_NREGIONS];
+ int i, fd;
+ size_t fd_num = 0;
+ bool reply_supported = virtio_has_feature(dev->protocol_features,
+ VHOST_USER_PROTOCOL_F_REPLY_ACK);
+ /* TODO: Add actual postcopy differences */
+ VhostUserMsg msg = {
+ .hdr.request = VHOST_USER_SET_MEM_TABLE,
+ .hdr.flags = VHOST_USER_VERSION,
+ };
+
+ if (reply_supported) {
+ msg.hdr.flags |= VHOST_USER_NEED_REPLY_MASK;
+ }
+
+ for (i = 0; i < dev->mem->nregions; ++i) {
+ struct vhost_memory_region *reg = dev->mem->regions + i;
+ ram_addr_t offset;
+ MemoryRegion *mr;
+
+ assert((uintptr_t)reg->userspace_addr == reg->userspace_addr);
+ mr = memory_region_from_host((void *)(uintptr_t)reg->userspace_addr,
+ &offset);
+ fd = memory_region_get_fd(mr);
+ if (fd > 0) {
+ msg.payload.memory.regions[fd_num].userspace_addr =
+ reg->userspace_addr;
+ msg.payload.memory.regions[fd_num].memory_size = reg->memory_size;
+ msg.payload.memory.regions[fd_num].guest_phys_addr =
+ reg->guest_phys_addr;
+ msg.payload.memory.regions[fd_num].mmap_offset = offset;
+ assert(fd_num < VHOST_MEMORY_MAX_NREGIONS);
+ fds[fd_num++] = fd;
+ }
+ }
+
+ msg.payload.memory.nregions = fd_num;
+
+ if (!fd_num) {
+ error_report("Failed initializing vhost-user memory map, "
+ "consider using -object memory-backend-file share=on");
+ return -1;
+ }
+
+ msg.hdr.size = sizeof(msg.payload.memory.nregions);
+ msg.hdr.size += sizeof(msg.payload.memory.padding);
+ msg.hdr.size += fd_num * sizeof(VhostUserMemoryRegion);
+
+ if (vhost_user_write(dev, &msg, fds, fd_num) < 0) {
+ return -1;
+ }
+
+ if (reply_supported) {
+ return process_message_reply(dev, &msg);
+ }
+
+ return 0;
+}
+
static int vhost_user_set_mem_table(struct vhost_dev *dev,
struct vhost_memory *mem)
{
+ struct vhost_user *u = dev->opaque;
int fds[VHOST_MEMORY_MAX_NREGIONS];
int i, fd;
size_t fd_num = 0;
+ bool do_postcopy = u->postcopy_listen && u->postcopy_fd.handler;
bool reply_supported = virtio_has_feature(dev->protocol_features,
VHOST_USER_PROTOCOL_F_REPLY_ACK);
+ if (do_postcopy) {
+ /* Postcopy has enough differences that it's best done in it's own
+ * version
+ */
+ return vhost_user_set_mem_table_postcopy(dev, mem);
+ }
+
VhostUserMsg msg = {
.hdr.request = VHOST_USER_SET_MEM_TABLE,
.hdr.flags = VHOST_USER_VERSION,
@@ -372,9 +443,11 @@ static int vhost_user_set_mem_table(struct vhost_dev *dev,
error_report("Failed preparing vhost-user memory table msg");
return -1;
}
- msg.payload.memory.regions[fd_num].userspace_addr = reg->userspace_addr;
+ msg.payload.memory.regions[fd_num].userspace_addr =
+ reg->userspace_addr;
msg.payload.memory.regions[fd_num].memory_size = reg->memory_size;
- msg.payload.memory.regions[fd_num].guest_phys_addr = reg->guest_phys_addr;
+ msg.payload.memory.regions[fd_num].guest_phys_addr =
+ reg->guest_phys_addr;
msg.payload.memory.regions[fd_num].mmap_offset = offset;
fds[fd_num++] = fd;
}