summaryrefslogtreecommitdiff
path: root/tools/vhost-user-scmi/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/vhost-user-scmi/main.c')
-rw-r--r--tools/vhost-user-scmi/main.c75
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);
}