diff options
Diffstat (limited to 'tools/vhost-user-scmi/main.c')
-rw-r--r-- | tools/vhost-user-scmi/main.c | 75 |
1 files changed, 65 insertions, 10 deletions
diff --git a/tools/vhost-user-scmi/main.c b/tools/vhost-user-scmi/main.c index 24e52b0090..92945e70ea 100644 --- a/tools/vhost-user-scmi/main.c +++ b/tools/vhost-user-scmi/main.c @@ -63,6 +63,8 @@ typedef struct { GSocket *socket ; GThread *thread; VuVirtqElement *elem[VHOST_USER_SCMI_MAX_QUEUES]; + struct vhost_vring_addr vring[VHOST_USER_SCMI_MAX_QUEUES]; + int vring_num[VHOST_USER_SCMI_MAX_QUEUES]; bool guest; bool started; } VuChnl; @@ -119,15 +121,6 @@ static void vscmi_dump_msg(struct virtio_scmi_request *msg, size_t len) g_info("%s: %s", __func__, s->str); } -static uint8_t vscmi_xfer(VuDev *dev, struct virtio_scmi_request *msg, size_t len) -{ - if (debug) { - vscmi_dump_msg(msg, len); - } - - return VIRTIO_SCMI_MSG_OK; -} - /* * vscmi_queue_set_started: set vq handler * @@ -216,7 +209,7 @@ static int vscmi_forward_buffer(int qidx, VuChnl *src_chnl, VuChnl *dst_chnl) out_hdr_len = elem->out_sg[0].iov_len; g_info("%s: path %s sent OUT size %lu @ %p", __func__, src_chnl->path, out_hdr_len, out_hdr); if (debug) - vscmi_xfer(&src_chnl->dev.parent, out_hdr, out_hdr_len); + vscmi_dump_msg(out_hdr, out_hdr_len); vscmi_copy_req(src_chnl->elem[qidx], dst_chnl->elem[qidx]); // g_info("%s: path %s copied IN elem size %lu", __func__, dst_chnl->path, dst_chnl->elem[qidx]->in_sg[0].iov_len); } else @@ -315,6 +308,34 @@ vscmi_queue_set_started(VuDev *dev, int qidx, bool started) chnl->started = started; + if (notification && chnl->guest) { + /* + * In notification only mode, backend is a device that need to be setup + * with guest vring information. + * + * Set backend vring information when guest starts. + */ + if(started) { + /* Guest starts, set backend/device addresses */ + VuScmi *scmi = container_of(chnl, VuScmi, vm_dev); + VuChnl *be_chnl = &scmi->be_dev; + + /* update vring hw address of backend */ + vu_set_queue_host_num(&be_chnl->dev.parent, qidx, -1, chnl->vring_num[qidx]); + vu_set_queue_host_addr(&be_chnl->dev.parent, qidx, -1, &chnl->vring[qidx]); + vu_set_queue_host_state(&be_chnl->dev.parent, qidx, -1, 1); + vu_queue_notify(&be_chnl->dev.parent, vu_get_queue(&be_chnl->dev.parent, qidx)); + } else { + /* Guest stops, clear server/device status */ + VuScmi *scmi = container_of(chnl, VuScmi, vm_dev); + VuChnl *be_chnl = &scmi->be_dev; + + /* clear ready and status bits */ + vu_set_queue_host_state(&be_chnl->dev.parent, qidx, -1, 0); + vu_queue_notify(&be_chnl->dev.parent, vu_get_queue(&be_chnl->dev.parent, qidx)); + } + } + vu_set_queue_handler(dev, vq, started ? vscmi_handle_ctrl : NULL); } @@ -336,6 +357,40 @@ static int vscmi_process_msg(VuDev *dev, VhostUserMsg *msg, int *do_reply) return 1; } + if (notification && chnl->guest) { + /* + * In notification only mode, backend is a device that need to be setup + * with guest vring information. + * + * Save guest vring information. + */ + if (msg->request == VHOST_USER_SET_VRING_NUM) { + unsigned int index = msg->payload.state.index; + unsigned int num = msg->payload.state.num; + + /* Save guest virtqueue size */ + chnl->vring_num[index]= num; + + g_info("%s: path %s VHOST_USER_SET_VRING_NUM idx %d num %d", __func__, chnl->path, index, num); + } + + if (msg->request == VHOST_USER_SET_VRING_ADDR) { + struct vhost_vring_addr addr = msg->payload.addr, *vra = &addr; + unsigned int index = vra->index; + + /* Save guest virtqueue addresses */ + chnl->vring[index].index = index; + chnl->vring[index].desc_user_addr = (uint64_t)vu_qva_to_gpa(dev,vra->desc_user_addr); + chnl->vring[index].used_user_addr = (uint64_t)vu_qva_to_gpa(dev,vra->used_user_addr); + chnl->vring[index].avail_user_addr = (uint64_t)vu_qva_to_gpa(dev,vra->avail_user_addr); + + g_info("%s: path %s VHOST_USER_SET_VRING_ADDR idx %d", __func__, chnl->path, index); + g_info(" guest phys desc: 0x%016" PRIx64 , (uint64_t)chnl->vring[index].desc_user_addr); + g_info(" guest phys used: 0x%016" PRIx64 , (uint64_t)chnl->vring[index].used_user_addr); + g_info(" guest phys avail: 0x%016" PRIx64 , (uint64_t)chnl->vring[index].avail_user_addr); + } + } + if (debug) { g_info("%s: path %s : request %d", __func__, chnl->path, msg->request); } |