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> --- 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