On Fri, Nov 29, 2013 at 08:52:26PM +0100, Antonios Motakis wrote: > Each ioctl request of vhost-kernel has a vhost-user message equivalent, > which is sent it over the control socket. > > The general approach is to copy the data from the supplied argument > pointer to a designated field in the message. If a file descriptor is > to be passed it should be placed also in the fds array for inclusion in > the sendmsd control header.
What does this code talk to? What's on the other side of the domain socket? > VHOST_SET_MEM_TABLE ignores the supplied vhost_memory structure and scans > the global ram_list for ram blocks wiht a valid fd field set. This would > be set when -mem-path and -mem-prealloc command line options are used. I don't get this. AFAIK -mem-path is used for huge tlb fs. So vhost-user requires huge tlb fs then? > Signed-off-by: Antonios Motakis <a.mota...@virtualopensystems.com> > Signed-off-by: Nikolay Nikolaev <n.nikol...@virtualopensystems.com> > --- > hw/virtio/vhost-backend.c | 105 > +++++++++++++++++++++++++++++++++++++++++++--- > 1 file changed, 100 insertions(+), 5 deletions(-) > > diff --git a/hw/virtio/vhost-backend.c b/hw/virtio/vhost-backend.c > index 264a0a1..1bc2928 100644 > --- a/hw/virtio/vhost-backend.c > +++ b/hw/virtio/vhost-backend.c > @@ -67,6 +67,38 @@ typedef struct VhostUserMsg { > }; > } VhostUserMsg; > > +static unsigned long int ioctl_to_vhost_user_request[VHOST_USER_MAX] = { > + -1, /* VHOST_USER_NONE */ > + VHOST_GET_FEATURES, /* VHOST_USER_GET_FEATURES */ > + VHOST_SET_FEATURES, /* VHOST_USER_SET_FEATURES */ > + VHOST_SET_OWNER, /* VHOST_USER_SET_OWNER */ > + VHOST_RESET_OWNER, /* VHOST_USER_RESET_OWNER */ > + VHOST_SET_MEM_TABLE, /* VHOST_USER_SET_MEM_TABLE */ > + VHOST_SET_LOG_BASE, /* VHOST_USER_SET_LOG_BASE */ > + VHOST_SET_LOG_FD, /* VHOST_USER_SET_LOG_FD */ > + VHOST_SET_VRING_NUM, /* VHOST_USER_SET_VRING_NUM */ > + VHOST_SET_VRING_ADDR, /* VHOST_USER_SET_VRING_ADDR */ > + VHOST_SET_VRING_BASE, /* VHOST_USER_SET_VRING_BASE */ > + VHOST_GET_VRING_BASE, /* VHOST_USER_GET_VRING_BASE */ > + VHOST_SET_VRING_KICK, /* VHOST_USER_SET_VRING_KICK */ > + VHOST_SET_VRING_CALL, /* VHOST_USER_SET_VRING_CALL */ > + VHOST_SET_VRING_ERR, /* VHOST_USER_SET_VRING_ERR */ > + VHOST_NET_SET_BACKEND /* VHOST_USER_NET_SET_BACKEND */ > +}; > + > +static VhostUserRequest vhost_user_request_translate(unsigned long int > request) > +{ > + VhostUserRequest idx; > + > + for (idx = 0; idx < VHOST_USER_MAX; idx++) { > + if (ioctl_to_vhost_user_request[idx] == request) { > + break; > + } > + } > + > + return (idx == VHOST_USER_MAX) ? VHOST_USER_NONE : idx; > +} > + > static int vhost_user_recv(int fd, VhostUserMsg *msg) > { > ssize_t r = read(fd, msg, sizeof(VhostUserMsg)); > @@ -137,13 +169,72 @@ static int vhost_user_call(struct vhost_dev *dev, > unsigned long int request, > { > int fd = dev->control; > VhostUserMsg msg; > - int result = 0; > + RAMBlock *block = 0; > + int result = 0, need_reply = 0; > int fds[VHOST_MEMORY_MAX_NREGIONS]; > size_t fd_num = 0; > > - memset(&msg, 0, sizeof(VhostUserMsg)); > + msg.request = vhost_user_request_translate(request); > + msg.flags = 0; > > switch (request) { > + case VHOST_GET_FEATURES: > + case VHOST_GET_VRING_BASE: > + need_reply = 1; > + break; > + > + case VHOST_SET_FEATURES: > + case VHOST_SET_LOG_BASE: > + msg.u64 = *((uint64_t *) arg); > + break; > + > + case VHOST_SET_OWNER: > + case VHOST_RESET_OWNER: > + break; > + > + case VHOST_SET_MEM_TABLE: > + QTAILQ_FOREACH(block, &ram_list.blocks, next) > + { > + if (block->fd > 0) { > + msg.memory.regions[fd_num].userspace_addr = (__u64) > block->host; > + msg.memory.regions[fd_num].memory_size = block->length; > + msg.memory.regions[fd_num].guest_phys_addr = block->offset; > + fds[fd_num++] = block->fd; > + } > + } > + > + msg.memory.nregions = fd_num; > + > + if (!fd_num) { > + fprintf(stderr, "Failed initializing vhost-user memory map\n" > + "consider -mem-path and -mem-prealloc options\n"); > + return -1; > + } > + break; > + > + case VHOST_SET_LOG_FD: > + msg.fd = *((int *) arg); > + break; > + > + case VHOST_SET_VRING_NUM: > + case VHOST_SET_VRING_BASE: > + memcpy(&msg.state, arg, sizeof(struct vhost_vring_state)); > + break; > + > + case VHOST_SET_VRING_ADDR: > + memcpy(&msg.addr, arg, sizeof(struct vhost_vring_addr)); > + break; > + > + case VHOST_SET_VRING_KICK: > + case VHOST_SET_VRING_CALL: > + case VHOST_SET_VRING_ERR: > + case VHOST_NET_SET_BACKEND: > + memcpy(&msg.file, arg, sizeof(struct vhost_vring_file)); > + if (msg.file.fd > 0) { > + fds[0] = msg.file.fd; > + fd_num = 1; > + } > + break; > default: > fprintf(stderr, "vhost-user trying to send unhandled ioctl\n"); > return -1; > @@ -152,12 +243,16 @@ static int vhost_user_call(struct vhost_dev *dev, > unsigned long int request, > > result = vhost_user_send_fds(fd, &msg, fds, fd_num); > > - if (!result) { > + if (!result && need_reply) { > result = vhost_user_recv(fd, &msg); > if (!result) { > switch (request) { > - default: > - fprintf(stderr, "vhost-user received unhandled message\n"); > + case VHOST_GET_FEATURES: > + *((uint64_t *) arg) = msg.u64; > + break; > + case VHOST_GET_VRING_BASE: > + memcpy(arg, &msg.state, sizeof(struct vhost_vring_state)); > + break; > } > } > } > -- > 1.8.3.2 >