aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSwapnil Ingle <swapnil.ingle@nutanix.com>2020-09-28 06:45:17 -0400
committerSwapnil Ingle <swapnil.ingle@nutanix.com>2020-09-28 06:45:17 -0400
commit217b60de1edac35460cab20cf812be8f2ec428f4 (patch)
tree108f543e8fccadc89ae47041eb6469fec19f538e
parent1d04b84719f443656badabdf672da592a4f85e59 (diff)
downloadlibvfio-user-217b60de1edac35460cab20cf812be8f2ec428f4.zip
libvfio-user-217b60de1edac35460cab20cf812be8f2ec428f4.tar.gz
libvfio-user-217b60de1edac35460cab20cf812be8f2ec428f4.tar.bz2
Fix handling of VFIO_USER_DEVICE_GET_INFO
vfio_device_info.argsz is set by the client and server is expected to use/validate it. Signed-off-by: Swapnil Ingle <swapnil.ingle@nutanix.com>
-rw-r--r--lib/libmuser.c34
-rw-r--r--samples/client.c8
2 files changed, 27 insertions, 15 deletions
diff --git a/lib/libmuser.c b/lib/libmuser.c
index 71d9ba2..b887afa 100644
--- a/lib/libmuser.c
+++ b/lib/libmuser.c
@@ -1643,23 +1643,27 @@ out:
}
static int handle_device_get_info(lm_ctx_t *lm_ctx,
- struct vfio_user_header *hdr)
+ struct vfio_user_header *hdr,
+ struct vfio_device_info *dev_info)
{
- struct vfio_device_info dev_info;
int ret;
- dev_info.argsz = sizeof(struct vfio_device_info);
+ if ((hdr->msg_size - sizeof(*hdr)) != sizeof(*dev_info)) {
+ return -EINVAL;
+ }
+
+ ret = recv(lm_ctx->conn_fd, dev_info, sizeof(*dev_info), 0);
+ if (ret < 0) {
+ return -errno;
+ }
- ret = dev_get_info(&dev_info);
+ ret = dev_get_info(dev_info);
if (ret < 0) {
return ret;
}
- ret = send_vfio_user_msg(lm_ctx->conn_fd, hdr->msg_id, true,
- VFIO_USER_DEVICE_GET_INFO, (void *)&dev_info,
- dev_info.argsz, NULL, 0);
lm_log(lm_ctx, LM_DBG, "sent devinfo flags %#x, num_regions %d, num_irqs"
- " %d", dev_info.flags, dev_info.num_regions, dev_info.num_irqs);
+ " %d", dev_info->flags, dev_info->num_regions, dev_info->num_irqs);
return ret;
}
@@ -1796,6 +1800,7 @@ process_request(lm_ctx_t *lm_ctx)
int *fds = NULL;
int nr_fds;
struct vfio_irq_info irq_info;
+ struct vfio_device_info dev_info;
void *data = NULL;
int len;
@@ -1844,8 +1849,11 @@ process_request(lm_ctx_t *lm_ctx)
fds, nr_fds);
break;
case VFIO_USER_DEVICE_GET_INFO:
- ret = handle_device_get_info(lm_ctx, &hdr);
- goto out;
+ ret = handle_device_get_info(lm_ctx, &hdr, &dev_info);
+ if (ret == 0) {
+ data = &dev_info;
+ len = dev_info.argsz;
+ }
break;
case VFIO_USER_DEVICE_GET_IRQ_INFO:
ret = handle_device_get_irq_info(lm_ctx, &hdr, &irq_info);
@@ -1859,10 +1867,12 @@ process_request(lm_ctx_t *lm_ctx)
return -EINVAL;
}
+ /*
+ * TODO: In case of error during command handling set errno respectively
+ * in the reply message.
+ */
ret = send_vfio_user_msg(lm_ctx->conn_fd, hdr.msg_id, true,
0, data, len, NULL, 0);
-
-out:
if (unlikely(ret < 0)) {
lm_log(lm_ctx, LM_ERR, "failed to complete command: %s\n",
strerror(-ret));
diff --git a/samples/client.c b/samples/client.c
index e8afb11..9756141 100644
--- a/samples/client.c
+++ b/samples/client.c
@@ -94,7 +94,7 @@ set_version(int sock, int client_max_fds, int *server_max_fds)
goto out;
}
- ret = send_version(sock, mj, mn, msg_id, true, client_caps);
+ ret = send_version(sock, mj, mn, msg_id, true, client_caps);
if (ret < 0) {
fprintf(stderr, "failed to send version to server: %s\n",
strerror(-ret));
@@ -111,14 +111,16 @@ static int
get_device_info(int sock)
{
struct vfio_user_header hdr;
- struct vfio_device_info dev_info;
+ struct vfio_device_info dev_info = {
+ .argsz = sizeof(dev_info)
+ };
uint16_t msg_id;
int ret;
int size = sizeof dev_info;
msg_id = 1;
ret = send_vfio_user_msg(sock, msg_id, false, VFIO_USER_DEVICE_GET_INFO,
- NULL, 0, NULL,0);
+ &dev_info, size, NULL,0);
if (ret < 0) {
fprintf(stderr, "%s: failed to send message: %s\n", __func__,
strerror(-ret));