----- Original Message ----- > On Sat, Sep 19, 2015 at 12:12:00PM +0200, marcandre.lur...@redhat.com wrote: > > From: Marc-André Lureau <marcandre.lur...@redhat.com> > > > > Replace the generic vhost_call() by specific functions for each > > function call to help with type safety and changing arguments. > > > > Signed-off-by: Marc-André Lureau <marcandre.lur...@redhat.com> > > OK but I would rather not make logging feature depend on the > refactoring.
The refactoring is straightforward, but I can split this patch. > How about moving each call over from vhost_call by a separate patch? > Start with vhost_set_log_base as the 1st one, this way I can apply > logging support while we still review the larger refactorings. > ok > > --- > > hw/net/vhost_net.c | 12 +- > > hw/scsi/vhost-scsi.c | 7 +- > > hw/virtio/vhost-backend.c | 140 +++++++++++-- > > hw/virtio/vhost-user.c | 402 > > ++++++++++++++++++++++++++------------ > > hw/virtio/vhost.c | 34 ++-- > > include/hw/virtio/vhost-backend.h | 59 +++++- > > 6 files changed, 484 insertions(+), 170 deletions(-) > > > > diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c > > index 9d32d76..d116fb3 100644 > > --- a/hw/net/vhost_net.c > > +++ b/hw/net/vhost_net.c > > @@ -243,8 +243,7 @@ static int vhost_net_start_one(struct vhost_net *net, > > file.fd = net->backend; > > for (file.index = 0; file.index < net->dev.nvqs; ++file.index) { > > const VhostOps *vhost_ops = net->dev.vhost_ops; > > - r = vhost_ops->vhost_call(&net->dev, VHOST_NET_SET_BACKEND, > > - &file); > > + r = vhost_ops->vhost_net_set_backend(&net->dev, &file); > > if (r < 0) { > > r = -errno; > > goto fail; > > @@ -257,8 +256,7 @@ fail: > > if (net->nc->info->type == NET_CLIENT_OPTIONS_KIND_TAP) { > > while (file.index-- > 0) { > > const VhostOps *vhost_ops = net->dev.vhost_ops; > > - int r = vhost_ops->vhost_call(&net->dev, > > VHOST_NET_SET_BACKEND, > > - &file); > > + int r = vhost_ops->vhost_net_set_backend(&net->dev, &file); > > assert(r >= 0); > > } > > } > > @@ -280,15 +278,13 @@ static void vhost_net_stop_one(struct vhost_net *net, > > if (net->nc->info->type == NET_CLIENT_OPTIONS_KIND_TAP) { > > for (file.index = 0; file.index < net->dev.nvqs; ++file.index) { > > const VhostOps *vhost_ops = net->dev.vhost_ops; > > - int r = vhost_ops->vhost_call(&net->dev, > > VHOST_NET_SET_BACKEND, > > - &file); > > + int r = vhost_ops->vhost_net_set_backend(&net->dev, &file); > > assert(r >= 0); > > } > > } else if (net->nc->info->type == NET_CLIENT_OPTIONS_KIND_VHOST_USER) > > { > > for (file.index = 0; file.index < net->dev.nvqs; ++file.index) { > > const VhostOps *vhost_ops = net->dev.vhost_ops; > > - int r = vhost_ops->vhost_call(&net->dev, VHOST_RESET_OWNER, > > - NULL); > > + int r = vhost_ops->vhost_reset_owner(&net->dev); > > assert(r >= 0); > > } > > } > > diff --git a/hw/scsi/vhost-scsi.c b/hw/scsi/vhost-scsi.c > > index bac9ddb..a0034ab 100644 > > --- a/hw/scsi/vhost-scsi.c > > +++ b/hw/scsi/vhost-scsi.c > > @@ -45,7 +45,7 @@ static int vhost_scsi_set_endpoint(VHostSCSI *s) > > > > memset(&backend, 0, sizeof(backend)); > > pstrcpy(backend.vhost_wwpn, sizeof(backend.vhost_wwpn), > > vs->conf.wwpn); > > - ret = vhost_ops->vhost_call(&s->dev, VHOST_SCSI_SET_ENDPOINT, > > &backend); > > + ret = vhost_ops->vhost_scsi_set_endpoint(&s->dev, &backend); > > if (ret < 0) { > > return -errno; > > } > > @@ -60,7 +60,7 @@ static void vhost_scsi_clear_endpoint(VHostSCSI *s) > > > > memset(&backend, 0, sizeof(backend)); > > pstrcpy(backend.vhost_wwpn, sizeof(backend.vhost_wwpn), > > vs->conf.wwpn); > > - vhost_ops->vhost_call(&s->dev, VHOST_SCSI_CLEAR_ENDPOINT, &backend); > > + vhost_ops->vhost_scsi_clear_endpoint(&s->dev, &backend); > > } > > > > static int vhost_scsi_start(VHostSCSI *s) > > @@ -76,8 +76,7 @@ static int vhost_scsi_start(VHostSCSI *s) > > return -ENOSYS; > > } > > > > - ret = vhost_ops->vhost_call(&s->dev, > > - VHOST_SCSI_GET_ABI_VERSION, &abi_version); > > + ret = vhost_ops->vhost_scsi_get_abi_version(&s->dev, &abi_version); > > if (ret < 0) { > > return -errno; > > } > > diff --git a/hw/virtio/vhost-backend.c b/hw/virtio/vhost-backend.c > > index 4d68a27..bf2d1d4 100644 > > --- a/hw/virtio/vhost-backend.c > > +++ b/hw/virtio/vhost-backend.c > > @@ -11,19 +11,10 @@ > > #include "hw/virtio/vhost.h" > > #include "hw/virtio/vhost-backend.h" > > #include "qemu/error-report.h" > > +#include "linux/vhost.h" > > > > #include <sys/ioctl.h> > > > > -static int vhost_kernel_call(struct vhost_dev *dev, unsigned long int > > request, > > - void *arg) > > -{ > > - int fd = (uintptr_t) dev->opaque; > > - > > - assert(dev->vhost_ops->backend_type == VHOST_BACKEND_TYPE_KERNEL); > > - > > - return ioctl(fd, request, arg); > > -} > > - > > static int vhost_kernel_init(struct vhost_dev *dev, void *opaque) > > { > > assert(dev->vhost_ops->backend_type == VHOST_BACKEND_TYPE_KERNEL); > > @@ -42,11 +33,136 @@ static int vhost_kernel_cleanup(struct vhost_dev *dev) > > return close(fd); > > } > > > > +static int vhost_kernel_call(struct vhost_dev *dev, > > + unsigned long int request, void *arg) > > +{ > > + int fd = (uintptr_t) dev->opaque; > > + > > + assert(dev->vhost_ops->backend_type == VHOST_BACKEND_TYPE_KERNEL); > > + > > + return ioctl(fd, request, arg); > > +} > > + > > +static int vhost_net_set_backend(struct vhost_dev *dev, > > + struct vhost_vring_file *file) > > +{ > > + return vhost_kernel_call(dev, VHOST_NET_SET_BACKEND, file); > > +} > > + > > +static int vhost_scsi_set_endpoint(struct vhost_dev *dev, > > + struct vhost_scsi_target *target) > > +{ > > + return vhost_kernel_call(dev, VHOST_SCSI_SET_ENDPOINT, target); > > +} > > + > > +static int vhost_scsi_clear_endpoint(struct vhost_dev *dev, > > + struct vhost_scsi_target *target) > > +{ > > + return vhost_kernel_call(dev, VHOST_SCSI_CLEAR_ENDPOINT, target); > > +} > > + > > +static int vhost_scsi_get_abi_version(struct vhost_dev *dev, int *version) > > +{ > > + return vhost_kernel_call(dev, VHOST_SCSI_GET_ABI_VERSION, version); > > +} > > + > > +static int vhost_set_log_base(struct vhost_dev *dev, uint64_t base) > > +{ > > + return vhost_kernel_call(dev, VHOST_SET_LOG_BASE, &base); > > +} > > + > > +static int vhost_set_mem_table(struct vhost_dev *dev, > > + struct vhost_memory *mem) > > +{ > > + return vhost_kernel_call(dev, VHOST_SET_MEM_TABLE, mem); > > +} > > + > > +static int vhost_set_vring_addr(struct vhost_dev *dev, > > + struct vhost_vring_addr *addr) > > +{ > > + return vhost_kernel_call(dev, VHOST_SET_VRING_ADDR, addr); > > +} > > + > > +static int vhost_set_vring_endian(struct vhost_dev *dev, > > + struct vhost_vring_state *ring) > > +{ > > + return vhost_kernel_call(dev, VHOST_SET_VRING_ENDIAN, ring); > > +} > > + > > +static int vhost_set_vring_num(struct vhost_dev *dev, > > + struct vhost_vring_state *ring) > > +{ > > + return vhost_kernel_call(dev, VHOST_SET_VRING_NUM, ring); > > +} > > + > > +static int vhost_set_vring_base(struct vhost_dev *dev, > > + struct vhost_vring_state *ring) > > +{ > > + return vhost_kernel_call(dev, VHOST_SET_VRING_BASE, ring); > > +} > > + > > +static int vhost_get_vring_base(struct vhost_dev *dev, > > + struct vhost_vring_state *ring) > > +{ > > + return vhost_kernel_call(dev, VHOST_GET_VRING_BASE, ring); > > +} > > + > > +static int vhost_set_vring_kick(struct vhost_dev *dev, > > + struct vhost_vring_file *file) > > +{ > > + return vhost_kernel_call(dev, VHOST_SET_VRING_KICK, file); > > +} > > + > > +static int vhost_set_vring_call(struct vhost_dev *dev, > > + struct vhost_vring_file *file) > > +{ > > + return vhost_kernel_call(dev, VHOST_SET_VRING_CALL, file); > > +} > > + > > +static int vhost_set_features(struct vhost_dev *dev, > > + uint64_t features) > > +{ > > + return vhost_kernel_call(dev, VHOST_SET_FEATURES, &features); > > +} > > + > > +static int vhost_kernel_get_features(struct vhost_dev *dev, > > + uint64_t *features) > > +{ > > + return vhost_kernel_call(dev, VHOST_GET_FEATURES, features); > > +} > > + > > +static int vhost_set_owner(struct vhost_dev *dev) > > +{ > > + return vhost_kernel_call(dev, VHOST_SET_OWNER, NULL); > > +} > > + > > +static int vhost_reset_owner(struct vhost_dev *dev) > > +{ > > + return vhost_kernel_call(dev, VHOST_RESET_OWNER, NULL); > > +} > > + > > static const VhostOps kernel_ops = { > > .backend_type = VHOST_BACKEND_TYPE_KERNEL, > > - .vhost_call = vhost_kernel_call, > > .vhost_backend_init = vhost_kernel_init, > > - .vhost_backend_cleanup = vhost_kernel_cleanup > > + .vhost_backend_cleanup = vhost_kernel_cleanup, > > + > > + .vhost_net_set_backend = vhost_net_set_backend, > > + .vhost_scsi_set_endpoint = vhost_scsi_set_endpoint, > > + .vhost_scsi_clear_endpoint = vhost_scsi_clear_endpoint, > > + .vhost_scsi_get_abi_version = vhost_scsi_get_abi_version, > > + .vhost_set_log_base = vhost_set_log_base, > > + .vhost_set_mem_table = vhost_set_mem_table, > > + .vhost_set_vring_addr = vhost_set_vring_addr, > > + .vhost_set_vring_endian = vhost_set_vring_endian, > > + .vhost_set_vring_num = vhost_set_vring_num, > > + .vhost_set_vring_base = vhost_set_vring_base, > > + .vhost_get_vring_base = vhost_get_vring_base, > > + .vhost_set_vring_kick = vhost_set_vring_kick, > > + .vhost_set_vring_call = vhost_set_vring_call, > > + .vhost_set_features = vhost_set_features, > > + .vhost_get_features = vhost_kernel_get_features, > > + .vhost_set_owner = vhost_set_owner, > > + .vhost_reset_owner = vhost_reset_owner, > > }; > > > > int vhost_set_backend_type(struct vhost_dev *dev, VhostBackendType > > backend_type) > > diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c > > index de87562..d5b7951 100644 > > --- a/hw/virtio/vhost-user.c > > +++ b/hw/virtio/vhost-user.c > > @@ -176,6 +176,7 @@ fail: > > return -1; > > } > > > > +/* most non-init callers ignore the error */ > > static int vhost_user_write(struct vhost_dev *dev, VhostUserMsg *msg, > > int *fds, int fd_num) > > { > > @@ -190,148 +191,280 @@ static int vhost_user_write(struct vhost_dev *dev, > > VhostUserMsg *msg, > > 0 : -1; > > } > > > > -static int vhost_user_call(struct vhost_dev *dev, unsigned long int > > request, > > - void *arg) > > +static int vhost_net_set_backend(struct vhost_dev *dev, > > + struct vhost_vring_file *file) > > +{ > > + error_report("vhost-user trying to send unhandled ioctl"); > > + return -1; > > +} > > + > > +static int vhost_scsi_set_endpoint(struct vhost_dev *dev, > > + struct vhost_scsi_target *target) > > +{ > > + error_report("vhost-user trying to send unhandled ioctl"); > > + return -1; > > +} > > + > > +static int vhost_scsi_clear_endpoint(struct vhost_dev *dev, > > + struct vhost_scsi_target *target) > > +{ > > + error_report("vhost-user trying to send unhandled ioctl"); > > + return -1; > > +} > > + > > +static int vhost_scsi_get_abi_version(struct vhost_dev *dev, int *version) > > +{ > > + error_report("vhost-user trying to send unhandled ioctl"); > > + return -1; > > +} > > + > > +static int vhost_set_log_base(struct vhost_dev *dev, uint64_t base) > > +{ > > + VhostUserMsg msg = { > > + .request = VHOST_USER_SET_LOG_BASE, > > + .flags = VHOST_USER_VERSION, > > + .u64 = base, > > + .size = sizeof(m.u64), > > + }; > > + > > + vhost_user_write(dev, &msg, NULL, 0); > > + > > + return 0; > > +} > > + > > +static int vhost_set_mem_table(struct vhost_dev *dev, > > + struct vhost_memory *mem) > > { > > - VhostUserMsg msg; > > - VhostUserRequest msg_request; > > - struct vhost_vring_file *file = 0; > > - int need_reply = 0; > > int fds[VHOST_MEMORY_MAX_NREGIONS]; > > int i, fd; > > size_t fd_num = 0; > > + VhostUserMsg msg = { > > + .request = VHOST_USER_SET_MEM_TABLE, > > + .flags = VHOST_USER_VERSION, > > + }; > > > > - assert(dev->vhost_ops->backend_type == VHOST_BACKEND_TYPE_USER); > > + for (i = 0; i < dev->mem->nregions; ++i) { > > + struct vhost_memory_region *reg = dev->mem->regions + i; > > + ram_addr_t ram_addr; > > + > > + assert((uintptr_t)reg->userspace_addr == reg->userspace_addr); > > + qemu_ram_addr_from_host((void *)(uintptr_t)reg->userspace_addr, > > + &ram_addr); > > + fd = qemu_get_ram_fd(ram_addr); > > + if (fd > 0) { > > + msg.memory.regions[fd_num].userspace_addr = > > reg->userspace_addr; > > + msg.memory.regions[fd_num].memory_size = reg->memory_size; > > + msg.memory.regions[fd_num].guest_phys_addr = > > reg->guest_phys_addr; > > + msg.memory.regions[fd_num].mmap_offset = reg->userspace_addr - > > + (uintptr_t) qemu_get_ram_block_host_ptr(ram_addr); > > + assert(fd_num < VHOST_MEMORY_MAX_NREGIONS); > > + fds[fd_num++] = fd; > > + } > > + } > > > > - msg_request = vhost_user_request_translate(request); > > - msg.request = msg_request; > > - msg.flags = VHOST_USER_VERSION; > > - msg.size = 0; > > + msg.memory.nregions = fd_num; > > > > - switch (msg_request) { > > - case VHOST_USER_GET_FEATURES: > > - need_reply = 1; > > - break; > > - > > - case VHOST_USER_SET_FEATURES: > > - case VHOST_USER_SET_LOG_BASE: > > - msg.u64 = *((__u64 *) arg); > > - msg.size = sizeof(m.u64); > > - break; > > - > > - case VHOST_USER_SET_OWNER: > > - case VHOST_USER_RESET_OWNER: > > - break; > > - > > - case VHOST_USER_SET_MEM_TABLE: > > - for (i = 0; i < dev->mem->nregions; ++i) { > > - struct vhost_memory_region *reg = dev->mem->regions + i; > > - ram_addr_t ram_addr; > > - > > - assert((uintptr_t)reg->userspace_addr == reg->userspace_addr); > > - qemu_ram_addr_from_host((void > > *)(uintptr_t)reg->userspace_addr, &ram_addr); > > - fd = qemu_get_ram_fd(ram_addr); > > - if (fd > 0) { > > - msg.memory.regions[fd_num].userspace_addr = > > reg->userspace_addr; > > - msg.memory.regions[fd_num].memory_size = > > reg->memory_size; > > - msg.memory.regions[fd_num].guest_phys_addr = > > reg->guest_phys_addr; > > - msg.memory.regions[fd_num].mmap_offset = > > reg->userspace_addr - > > - (uintptr_t) qemu_get_ram_block_host_ptr(ram_addr); > > - assert(fd_num < VHOST_MEMORY_MAX_NREGIONS); > > - fds[fd_num++] = fd; > > - } > > - } > > + if (!fd_num) { > > + error_report("Failed initializing vhost-user memory map, " > > + "consider using -object memory-backend-file > > share=on"); > > + return -1; > > + } > > > > - msg.memory.nregions = fd_num; > > + msg.size = sizeof(m.memory.nregions); > > + msg.size += sizeof(m.memory.padding); > > + msg.size += fd_num * sizeof(VhostUserMemoryRegion); > > > > - if (!fd_num) { > > - error_report("Failed initializing vhost-user memory map, " > > - "consider using -object memory-backend-file > > share=on"); > > - return -1; > > - } > > + vhost_user_write(dev, &msg, fds, fd_num); > > > > - msg.size = sizeof(m.memory.nregions); > > - msg.size += sizeof(m.memory.padding); > > - msg.size += fd_num * sizeof(VhostUserMemoryRegion); > > - > > - break; > > - > > - case VHOST_USER_SET_LOG_FD: > > - fds[fd_num++] = *((int *) arg); > > - break; > > - > > - case VHOST_USER_SET_VRING_NUM: > > - case VHOST_USER_SET_VRING_BASE: > > - memcpy(&msg.state, arg, sizeof(struct vhost_vring_state)); > > - msg.size = sizeof(m.state); > > - break; > > - > > - case VHOST_USER_GET_VRING_BASE: > > - memcpy(&msg.state, arg, sizeof(struct vhost_vring_state)); > > - msg.size = sizeof(m.state); > > - need_reply = 1; > > - break; > > - > > - case VHOST_USER_SET_VRING_ADDR: > > - memcpy(&msg.addr, arg, sizeof(struct vhost_vring_addr)); > > - msg.size = sizeof(m.addr); > > - break; > > - > > - case VHOST_USER_SET_VRING_KICK: > > - case VHOST_USER_SET_VRING_CALL: > > - case VHOST_USER_SET_VRING_ERR: > > - file = arg; > > - msg.u64 = file->index & VHOST_USER_VRING_IDX_MASK; > > - msg.size = sizeof(m.u64); > > - if (ioeventfd_enabled() && file->fd > 0) { > > - fds[fd_num++] = file->fd; > > - } else { > > - msg.u64 |= VHOST_USER_VRING_NOFD_MASK; > > - } > > - break; > > - default: > > - error_report("vhost-user trying to send unhandled ioctl"); > > + return 0; > > +} > > + > > +static int vhost_set_vring_addr(struct vhost_dev *dev, > > + struct vhost_vring_addr *addr) > > +{ > > + VhostUserMsg msg = { > > + .request = VHOST_USER_SET_VRING_ADDR, > > + .flags = VHOST_USER_VERSION, > > + .addr = *addr, > > + .size = sizeof(*addr), > > + }; > > + > > + vhost_user_write(dev, &msg, NULL, 0); > > + > > + return 0; > > +} > > + > > +static int vhost_set_vring_endian(struct vhost_dev *dev, > > + struct vhost_vring_state *ring) > > +{ > > + error_report("vhost-user trying to send unhandled ioctl"); > > + return -1; > > +} > > + > > +static int vhost_set_vring_num(struct vhost_dev *dev, > > + struct vhost_vring_state *ring) > > +{ > > + VhostUserMsg msg = { > > + .request = VHOST_USER_SET_VRING_NUM, > > + .flags = VHOST_USER_VERSION, > > + .state = *ring, > > + .size = sizeof(*ring), > > + }; > > + > > + vhost_user_write(dev, &msg, NULL, 0); > > + > > + return 0; > > +} > > + > > +static int vhost_set_vring_base(struct vhost_dev *dev, > > + struct vhost_vring_state *ring) > > +{ > > + VhostUserMsg msg = { > > + .request = VHOST_USER_SET_VRING_BASE, > > + .flags = VHOST_USER_VERSION, > > + .state = *ring, > > + .size = sizeof(*ring), > > + }; > > + > > + vhost_user_write(dev, &msg, NULL, 0); > > + > > + return 0; > > +} > > + > > +static int vhost_get_vring_base(struct vhost_dev *dev, > > + struct vhost_vring_state *ring) > > +{ > > + VhostUserMsg msg = { > > + .request = VHOST_USER_GET_VRING_BASE, > > + .flags = VHOST_USER_VERSION, > > + .state = *ring, > > + .size = sizeof(*ring), > > + }; > > + > > + vhost_user_write(dev, &msg, NULL, 0); > > + > > + if (vhost_user_read(dev, &msg) < 0) { > > + return 0; > > + } > > + > > + if (msg.request != VHOST_USER_GET_VRING_BASE) { > > + error_report("Received unexpected msg type. Expected %d received > > %d", > > + VHOST_USER_GET_FEATURES, msg.request); > > return -1; > > - break; > > } > > > > - if (vhost_user_write(dev, &msg, fds, fd_num) < 0) { > > - return 0; > > + if (msg.size != sizeof(m.state)) { > > + error_report("Received bad msg size."); > > + return -1; > > } > > > > - if (need_reply) { > > - if (vhost_user_read(dev, &msg) < 0) { > > - return 0; > > - } > > + *ring = msg.state; > > > > - if (msg_request != msg.request) { > > - error_report("Received unexpected msg type." > > - " Expected %d received %d", msg_request, msg.request); > > - return -1; > > - } > > + return 0; > > +} > > > > - switch (msg_request) { > > - case VHOST_USER_GET_FEATURES: > > - if (msg.size != sizeof(m.u64)) { > > - error_report("Received bad msg size."); > > - return -1; > > - } > > - *((__u64 *) arg) = msg.u64; > > - break; > > - case VHOST_USER_GET_VRING_BASE: > > - if (msg.size != sizeof(m.state)) { > > - error_report("Received bad msg size."); > > - return -1; > > - } > > - memcpy(arg, &msg.state, sizeof(struct vhost_vring_state)); > > - break; > > - default: > > - error_report("Received unexpected msg type."); > > - return -1; > > - break; > > - } > > +static int vhost_set_vring_file(struct vhost_dev *dev, > > + VhostUserRequest request, > > + struct vhost_vring_file *file) > > +{ > > + int fds[VHOST_MEMORY_MAX_NREGIONS]; > > + size_t fd_num = 0; > > + VhostUserMsg msg = { > > + .request = request, > > + .flags = VHOST_USER_VERSION, > > + .u64 = file->index & VHOST_USER_VRING_IDX_MASK, > > + .size = sizeof(m.u64), > > + }; > > + > > + if (ioeventfd_enabled() && file->fd > 0) { > > + fds[fd_num++] = file->fd; > > + } else { > > + msg.u64 |= VHOST_USER_VRING_NOFD_MASK; > > } > > > > + vhost_user_write(dev, &msg, fds, fd_num); > > + > > + return 0; > > +} > > + > > +static int vhost_set_vring_kick(struct vhost_dev *dev, > > + struct vhost_vring_file *file) > > +{ > > + return vhost_set_vring_file(dev, VHOST_USER_SET_VRING_KICK, file); > > +} > > + > > +static int vhost_set_vring_call(struct vhost_dev *dev, > > + struct vhost_vring_file *file) > > +{ > > + return vhost_set_vring_file(dev, VHOST_USER_SET_VRING_CALL, file); > > +} > > + > > +static int vhost_set_features(struct vhost_dev *dev, > > + uint64_t features) > > +{ > > + VhostUserMsg msg = { > > + .request = VHOST_USER_SET_FEATURES, > > + .flags = VHOST_USER_VERSION, > > + .u64 = features, > > + .size = sizeof(m.u64), > > + }; > > + > > + vhost_user_write(dev, &msg, NULL, 0); > > + > > + return 0; > > +} > > + > > +static int vhost_user_get_features(struct vhost_dev *dev, > > + uint64_t *features) > > +{ > > + VhostUserMsg msg = { > > + .request = VHOST_USER_GET_FEATURES, > > + .flags = VHOST_USER_VERSION, > > + }; > > + > > + vhost_user_write(dev, &msg, NULL, 0); > > + > > + if (vhost_user_read(dev, &msg) < 0) { > > + return 0; > > + } > > + > > + if (msg.request != VHOST_USER_GET_FEATURES) { > > + error_report("Received unexpected msg type. Expected %d received > > %d", > > + VHOST_USER_GET_FEATURES, msg.request); > > + return -1; > > + } > > + > > + if (msg.size != sizeof(m.u64)) { > > + error_report("Received bad msg size."); > > + return -1; > > + } > > + > > + *features = msg.u64; > > + > > + return 0; > > +} > > + > > +static int vhost_set_owner(struct vhost_dev *dev) > > +{ > > + VhostUserMsg msg = { > > + .request = VHOST_USER_SET_OWNER, > > + .flags = VHOST_USER_VERSION, > > + }; > > + > > + vhost_user_write(dev, &msg, NULL, 0); > > + > > + return 0; > > +} > > + > > +static int vhost_reset_owner(struct vhost_dev *dev) > > +{ > > + VhostUserMsg msg = { > > + .request = VHOST_USER_RESET_OWNER, > > + .flags = VHOST_USER_VERSION, > > + }; > > + > > + vhost_user_write(dev, &msg, NULL, 0); > > + > > return 0; > > } > > > > @@ -402,7 +535,24 @@ static int vhost_user_cleanup(struct vhost_dev *dev) > > > > const VhostOps user_ops = { > > .backend_type = VHOST_BACKEND_TYPE_USER, > > - .vhost_call = vhost_user_call, > > .vhost_backend_init = vhost_user_init, > > - .vhost_backend_cleanup = vhost_user_cleanup > > - }; > > + .vhost_backend_cleanup = vhost_user_cleanup, > > + > > + .vhost_net_set_backend = vhost_net_set_backend, > > + .vhost_scsi_set_endpoint = vhost_scsi_set_endpoint, > > + .vhost_scsi_clear_endpoint = vhost_scsi_clear_endpoint, > > + .vhost_scsi_get_abi_version = vhost_scsi_get_abi_version, > > + .vhost_set_log_base = vhost_set_log_base, > > + .vhost_set_mem_table = vhost_set_mem_table, > > + .vhost_set_vring_addr = vhost_set_vring_addr, > > + .vhost_set_vring_endian = vhost_set_vring_endian, > > + .vhost_set_vring_num = vhost_set_vring_num, > > + .vhost_set_vring_base = vhost_set_vring_base, > > + .vhost_get_vring_base = vhost_get_vring_base, > > + .vhost_set_vring_kick = vhost_set_vring_kick, > > + .vhost_set_vring_call = vhost_set_vring_call, > > + .vhost_set_features = vhost_set_features, > > + .vhost_get_features = vhost_user_get_features, > > + .vhost_set_owner = vhost_set_owner, > > + .vhost_reset_owner = vhost_reset_owner, > > +}; > > diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c > > index 81209ba..83ef164 100644 > > --- a/hw/virtio/vhost.c > > +++ b/hw/virtio/vhost.c > > @@ -359,7 +359,7 @@ static inline void vhost_dev_log_resize(struct > > vhost_dev* dev, uint64_t size) > > > > /* inform backend of log switching, this must be done before > > releasing the current log, to ensure no logging is lost */ > > - r = dev->vhost_ops->vhost_call(dev, VHOST_SET_LOG_BASE, &log_base); > > + r = dev->vhost_ops->vhost_set_log_base(dev, log_base); > > assert(r >= 0); > > vhost_log_put(dev, true); > > dev->log = log; > > @@ -525,7 +525,7 @@ static void vhost_commit(MemoryListener *listener) > > } > > > > if (!dev->log_enabled) { > > - r = dev->vhost_ops->vhost_call(dev, VHOST_SET_MEM_TABLE, > > dev->mem); > > + r = dev->vhost_ops->vhost_set_mem_table(dev, dev->mem); > > assert(r >= 0); > > dev->memory_changed = false; > > return; > > @@ -538,7 +538,7 @@ static void vhost_commit(MemoryListener *listener) > > if (dev->log_size < log_size) { > > vhost_dev_log_resize(dev, log_size + VHOST_LOG_BUFFER); > > } > > - r = dev->vhost_ops->vhost_call(dev, VHOST_SET_MEM_TABLE, dev->mem); > > + r = dev->vhost_ops->vhost_set_mem_table(dev, dev->mem); > > assert(r >= 0); > > /* To log less, can only decrease log size after table update. */ > > if (dev->log_size > log_size + VHOST_LOG_BUFFER) { > > @@ -606,7 +606,7 @@ static int vhost_virtqueue_set_addr(struct vhost_dev > > *dev, > > .log_guest_addr = vq->used_phys, > > .flags = enable_log ? (1 << VHOST_VRING_F_LOG) : 0, > > }; > > - int r = dev->vhost_ops->vhost_call(dev, VHOST_SET_VRING_ADDR, &addr); > > + int r = dev->vhost_ops->vhost_set_vring_addr(dev, &addr); > > if (r < 0) { > > return -errno; > > } > > @@ -620,7 +620,7 @@ static int vhost_dev_set_features(struct vhost_dev > > *dev, bool enable_log) > > if (enable_log) { > > features |= 0x1ULL << VHOST_F_LOG_ALL; > > } > > - r = dev->vhost_ops->vhost_call(dev, VHOST_SET_FEATURES, &features); > > + r = dev->vhost_ops->vhost_set_features(dev, features); > > return r < 0 ? -errno : 0; > > } > > > > @@ -725,7 +725,7 @@ static int > > vhost_virtqueue_set_vring_endian_legacy(struct vhost_dev *dev, > > .num = is_big_endian > > }; > > > > - if (!dev->vhost_ops->vhost_call(dev, VHOST_SET_VRING_ENDIAN, &s)) { > > + if (!dev->vhost_ops->vhost_set_vring_endian(dev, &s)) { > > return 0; > > } > > > > @@ -756,13 +756,13 @@ static int vhost_virtqueue_start(struct vhost_dev > > *dev, > > assert(idx >= dev->vq_index && idx < dev->vq_index + dev->nvqs); > > > > vq->num = state.num = virtio_queue_get_num(vdev, idx); > > - r = dev->vhost_ops->vhost_call(dev, VHOST_SET_VRING_NUM, &state); > > + r = dev->vhost_ops->vhost_set_vring_num(dev, &state); > > if (r) { > > return -errno; > > } > > > > state.num = virtio_queue_get_last_avail_idx(vdev, idx); > > - r = dev->vhost_ops->vhost_call(dev, VHOST_SET_VRING_BASE, &state); > > + r = dev->vhost_ops->vhost_set_vring_base(dev, &state); > > if (r) { > > return -errno; > > } > > @@ -814,7 +814,7 @@ static int vhost_virtqueue_start(struct vhost_dev *dev, > > } > > > > file.fd = event_notifier_get_fd(virtio_queue_get_host_notifier(vvq)); > > - r = dev->vhost_ops->vhost_call(dev, VHOST_SET_VRING_KICK, &file); > > + r = dev->vhost_ops->vhost_set_vring_kick(dev, &file); > > if (r) { > > r = -errno; > > goto fail_kick; > > @@ -853,7 +853,7 @@ static void vhost_virtqueue_stop(struct vhost_dev *dev, > > }; > > int r; > > assert(idx >= dev->vq_index && idx < dev->vq_index + dev->nvqs); > > - r = dev->vhost_ops->vhost_call(dev, VHOST_GET_VRING_BASE, &state); > > + r = dev->vhost_ops->vhost_get_vring_base(dev, &state); > > if (r < 0) { > > fprintf(stderr, "vhost VQ %d ring restore failed: %d\n", idx, r); > > fflush(stderr); > > @@ -909,7 +909,7 @@ static int vhost_virtqueue_init(struct vhost_dev *dev, > > } > > > > file.fd = event_notifier_get_fd(&vq->masked_notifier); > > - r = dev->vhost_ops->vhost_call(dev, VHOST_SET_VRING_CALL, &file); > > + r = dev->vhost_ops->vhost_set_vring_call(dev, &file); > > if (r) { > > r = -errno; > > goto fail_call; > > @@ -941,12 +941,12 @@ int vhost_dev_init(struct vhost_dev *hdev, void > > *opaque, > > return -errno; > > } > > > > - r = hdev->vhost_ops->vhost_call(hdev, VHOST_SET_OWNER, NULL); > > + r = hdev->vhost_ops->vhost_set_owner(hdev); > > if (r < 0) { > > goto fail; > > } > > > > - r = hdev->vhost_ops->vhost_call(hdev, VHOST_GET_FEATURES, &features); > > + r = hdev->vhost_ops->vhost_get_features(hdev, &features); > > if (r < 0) { > > goto fail; > > } > > @@ -1102,7 +1102,7 @@ void vhost_virtqueue_mask(struct vhost_dev *hdev, > > VirtIODevice *vdev, int n, > > } else { > > file.fd = > > event_notifier_get_fd(virtio_queue_get_guest_notifier(vvq)); > > } > > - r = hdev->vhost_ops->vhost_call(hdev, VHOST_SET_VRING_CALL, &file); > > + r = hdev->vhost_ops->vhost_set_vring_call(hdev, &file); > > assert(r >= 0); > > } > > > > @@ -1144,7 +1144,7 @@ int vhost_dev_start(struct vhost_dev *hdev, > > VirtIODevice *vdev) > > if (r < 0) { > > goto fail_features; > > } > > - r = hdev->vhost_ops->vhost_call(hdev, VHOST_SET_MEM_TABLE, hdev->mem); > > + r = hdev->vhost_ops->vhost_set_mem_table(hdev, hdev->mem); > > if (r < 0) { > > r = -errno; > > goto fail_mem; > > @@ -1166,8 +1166,8 @@ int vhost_dev_start(struct vhost_dev *hdev, > > VirtIODevice *vdev) > > hdev->log_size = vhost_get_log_size(hdev); > > hdev->log = vhost_log_get(hdev->log_size, share); > > log_base = (uintptr_t)hdev->log->log; > > - r = hdev->vhost_ops->vhost_call(hdev, VHOST_SET_LOG_BASE, > > - hdev->log_size ? &log_base : > > NULL); > > + r = hdev->vhost_ops->vhost_set_log_base(hdev, > > + hdev->log_size ? log_base > > : 0); > > if (r < 0) { > > r = -errno; > > goto fail_log; > > diff --git a/include/hw/virtio/vhost-backend.h > > b/include/hw/virtio/vhost-backend.h > > index e472f29..42cfb87 100644 > > --- a/include/hw/virtio/vhost-backend.h > > +++ b/include/hw/virtio/vhost-backend.h > > @@ -19,17 +19,70 @@ typedef enum VhostBackendType { > > } VhostBackendType; > > > > struct vhost_dev; > > +struct vhost_memory; > > +struct vhost_vring_file; > > +struct vhost_vring_state; > > +struct vhost_vring_addr; > > +struct vhost_scsi_target; > > > > -typedef int (*vhost_call)(struct vhost_dev *dev, unsigned long int > > request, > > - void *arg); > > typedef int (*vhost_backend_init)(struct vhost_dev *dev, void *opaque); > > typedef int (*vhost_backend_cleanup)(struct vhost_dev *dev); > > > > +typedef int (*vhost_net_set_backend_op)(struct vhost_dev *dev, > > + struct vhost_vring_file *file); > > +typedef int (*vhost_scsi_set_endpoint_op)(struct vhost_dev *dev, > > + struct vhost_scsi_target > > *target); > > +typedef int (*vhost_scsi_clear_endpoint_op)(struct vhost_dev *dev, > > + struct vhost_scsi_target > > *target); > > +typedef int (*vhost_scsi_get_abi_version_op)(struct vhost_dev *dev, > > + int *version); > > +typedef int (*vhost_set_log_base_op)(struct vhost_dev *dev, uint64_t > > base); > > +typedef int (*vhost_set_mem_table_op)(struct vhost_dev *dev, > > + struct vhost_memory *mem); > > +typedef int (*vhost_set_vring_addr_op)(struct vhost_dev *dev, > > + struct vhost_vring_addr *addr); > > +typedef int (*vhost_set_vring_endian_op)(struct vhost_dev *dev, > > + struct vhost_vring_state *ring); > > +typedef int (*vhost_set_vring_num_op)(struct vhost_dev *dev, > > + struct vhost_vring_state *ring); > > +typedef int (*vhost_set_vring_base_op)(struct vhost_dev *dev, > > + struct vhost_vring_state *ring); > > +typedef int (*vhost_get_vring_base_op)(struct vhost_dev *dev, > > + struct vhost_vring_state *ring); > > +typedef int (*vhost_set_vring_kick_op)(struct vhost_dev *dev, > > + struct vhost_vring_file *file); > > +typedef int (*vhost_set_vring_call_op)(struct vhost_dev *dev, > > + struct vhost_vring_file *file); > > +typedef int (*vhost_set_features_op)(struct vhost_dev *dev, > > + uint64_t features); > > +typedef int (*vhost_get_features_op)(struct vhost_dev *dev, > > + uint64_t *features); > > +typedef int (*vhost_set_owner_op)(struct vhost_dev *dev); > > +typedef int (*vhost_reset_owner_op)(struct vhost_dev *dev); > > + > > typedef struct VhostOps { > > VhostBackendType backend_type; > > - vhost_call vhost_call; > > + > > vhost_backend_init vhost_backend_init; > > vhost_backend_cleanup vhost_backend_cleanup; > > + > > + vhost_net_set_backend_op vhost_net_set_backend; > > + vhost_scsi_set_endpoint_op vhost_scsi_set_endpoint; > > + vhost_scsi_clear_endpoint_op vhost_scsi_clear_endpoint; > > + vhost_scsi_get_abi_version_op vhost_scsi_get_abi_version; > > + vhost_set_log_base_op vhost_set_log_base; > > + vhost_set_mem_table_op vhost_set_mem_table; > > + vhost_set_vring_addr_op vhost_set_vring_addr; > > + vhost_set_vring_endian_op vhost_set_vring_endian; > > + vhost_set_vring_num_op vhost_set_vring_num; > > + vhost_set_vring_base_op vhost_set_vring_base; > > + vhost_get_vring_base_op vhost_get_vring_base; > > + vhost_set_vring_kick_op vhost_set_vring_kick; > > + vhost_set_vring_call_op vhost_set_vring_call; > > + vhost_set_features_op vhost_set_features; > > + vhost_get_features_op vhost_get_features; > > + vhost_set_owner_op vhost_set_owner; > > + vhost_reset_owner_op vhost_reset_owner; > > } VhostOps; > > > > extern const VhostOps user_ops; > > -- > > 2.4.3 >