vhost-user: don't merge regions with different fds

vhost currently merges regions with contiguious virtual and physical
addresses.  This breaks for vhost-user since that also needs fds to
match.

Add a vhost_ops entry to compare the fds for vhost-user only.

Cc: qemu-stable@nongnu.org
Cc: Victor Kaplansky <victork@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
stable-2.6
Michael S. Tsirkin 2016-02-21 17:01:47 +02:00
parent b54ca0c3df
commit ffe42cc14c
3 changed files with 31 additions and 0 deletions

View File

@ -611,6 +611,25 @@ static int vhost_user_migration_done(struct vhost_dev *dev, char* mac_addr)
return -1;
}
static bool vhost_user_can_merge(struct vhost_dev *dev,
uint64_t start1, uint64_t size1,
uint64_t start2, uint64_t size2)
{
ram_addr_t ram_addr;
int mfd, rfd;
MemoryRegion *mr;
mr = qemu_ram_addr_from_host((void *)(uintptr_t)start1, &ram_addr);
assert(mr);
mfd = qemu_get_ram_fd(ram_addr);
mr = qemu_ram_addr_from_host((void *)(uintptr_t)start2, &ram_addr);
assert(mr);
rfd = qemu_get_ram_fd(ram_addr);
return mfd == rfd;
}
const VhostOps user_ops = {
.backend_type = VHOST_BACKEND_TYPE_USER,
.vhost_backend_init = vhost_user_init,
@ -633,4 +652,5 @@ const VhostOps user_ops = {
.vhost_set_vring_enable = vhost_user_set_vring_enable,
.vhost_requires_shm_log = vhost_user_requires_shm_log,
.vhost_migration_done = vhost_user_migration_done,
.vhost_backend_can_merge = vhost_user_can_merge,
};

View File

@ -260,6 +260,13 @@ static void vhost_dev_assign_memory(struct vhost_dev *dev,
continue;
}
if (dev->vhost_ops->vhost_backend_can_merge &&
!dev->vhost_ops->vhost_backend_can_merge(dev, uaddr, size,
reg->userspace_addr,
reg->memory_size)) {
continue;
}
if (merged) {
--to;
assert(to >= 0);

View File

@ -70,6 +70,9 @@ typedef int (*vhost_set_vring_enable_op)(struct vhost_dev *dev,
typedef bool (*vhost_requires_shm_log_op)(struct vhost_dev *dev);
typedef int (*vhost_migration_done_op)(struct vhost_dev *dev,
char *mac_addr);
typedef bool (*vhost_backend_can_merge_op)(struct vhost_dev *dev,
uint64_t start1, uint64_t size1,
uint64_t start2, uint64_t size2);
typedef struct VhostOps {
VhostBackendType backend_type;
@ -97,6 +100,7 @@ typedef struct VhostOps {
vhost_set_vring_enable_op vhost_set_vring_enable;
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;
} VhostOps;
extern const VhostOps user_ops;