From 59d901ad72d70911d782e5a4aafced0b34496b38 Mon Sep 17 00:00:00 2001 From: Dariusz Stojaczyk Date: Wed, 7 Feb 2018 16:08:13 +0100 Subject: [PATCH] virtio/user: implement get/set config messages This will let us e.g. read device blocksize in the upcoming vhost-blk initiator. All the public API was already there - we've been using it for virtio-pci. Now we're making use of it for vhost-user as well. Change-Id: I39eab820bb9bbff59c8b8efa79cc97d2ec7806fd Signed-off-by: Dariusz Stojaczyk Reviewed-on: https://review.gerrithub.io/398828 Tested-by: SPDK Automated Test System Reviewed-by: Daniel Verkamp Reviewed-by: Changpeng Liu Reviewed-by: Jim Harris --- lib/virtio/virtio_user.c | 25 +++++++++++++++++++++++-- lib/virtio/virtio_user/vhost.h | 12 ++++++++++++ lib/virtio/virtio_user/vhost_user.c | 23 ++++++++++++++++++++++- 3 files changed, 57 insertions(+), 3 deletions(-) diff --git a/lib/virtio/virtio_user.c b/lib/virtio/virtio_user.c index 415ecfc63..a4459bb2a 100644 --- a/lib/virtio/virtio_user.c +++ b/lib/virtio/virtio_user.c @@ -201,14 +201,35 @@ static void virtio_user_read_dev_config(struct virtio_dev *vdev, size_t offset, void *dst, int length) { - SPDK_ERRLOG("not supported offset=%zu, len=%d\n", offset, length); + struct virtio_user_dev *dev = vdev->ctx; + struct vhost_user_config cfg = {0}; + + cfg.offset = 0; + cfg.size = VHOST_USER_MAX_CONFIG_SIZE; + + if (dev->ops->send_request(dev, VHOST_USER_GET_CONFIG, &cfg) < 0) { + SPDK_ERRLOG("get_config failed: %s\n", spdk_strerror(errno)); + return; + } + + memcpy(dst, cfg.region + offset, length); } static void virtio_user_write_dev_config(struct virtio_dev *vdev, size_t offset, const void *src, int length) { - SPDK_ERRLOG("not supported offset=%zu, len=%d\n", offset, length); + struct virtio_user_dev *dev = vdev->ctx; + struct vhost_user_config cfg = {0}; + + cfg.offset = offset; + cfg.size = length; + memcpy(cfg.region, src, length); + + if (dev->ops->send_request(dev, VHOST_USER_SET_CONFIG, &cfg) < 0) { + SPDK_ERRLOG("set_config failed: %s\n", spdk_strerror(errno)); + return; + } } static void diff --git a/lib/virtio/virtio_user/vhost.h b/lib/virtio/virtio_user/vhost.h index 92a5828d4..35a1af349 100644 --- a/lib/virtio/virtio_user/vhost.h +++ b/lib/virtio/virtio_user/vhost.h @@ -41,6 +41,8 @@ #include "spdk_internal/log.h" #include "spdk_internal/virtio.h" +#define VHOST_USER_MAX_CONFIG_SIZE 256 + enum vhost_user_request { VHOST_USER_NONE = 0, VHOST_USER_GET_FEATURES = 1, @@ -61,6 +63,8 @@ enum vhost_user_request { VHOST_USER_SET_PROTOCOL_FEATURES = 16, VHOST_USER_GET_QUEUE_NUM = 17, VHOST_USER_SET_VRING_ENABLE = 18, + VHOST_USER_GET_CONFIG = 24, + VHOST_USER_SET_CONFIG = 25, VHOST_USER_MAX }; @@ -88,6 +92,14 @@ struct virtio_user_backend_ops { void *arg); }; +/* get/set config msg */ +struct vhost_user_config { + uint32_t offset; + uint32_t size; + uint32_t flags; + uint8_t region[VHOST_USER_MAX_CONFIG_SIZE]; +}; + extern struct virtio_user_backend_ops ops_user; extern struct virtio_user_backend_ops ops_kernel; diff --git a/lib/virtio/virtio_user/vhost_user.c b/lib/virtio/virtio_user/vhost_user.c index 59ea1e075..7911a2464 100644 --- a/lib/virtio/virtio_user/vhost_user.c +++ b/lib/virtio/virtio_user/vhost_user.c @@ -63,6 +63,7 @@ struct vhost_user_msg { struct vhost_vring_state state; struct vhost_vring_addr addr; struct vhost_memory_padded memory; + struct vhost_user_config cfg; } payload; int fds[VHOST_MEMORY_MAX_NREGIONS]; } __attribute((packed)); @@ -279,7 +280,9 @@ static const char *const vhost_msg_strings[VHOST_USER_MAX] = { [VHOST_USER_SET_VRING_KICK] = "VHOST_SET_VRING_KICK", [VHOST_USER_SET_MEM_TABLE] = "VHOST_SET_MEM_TABLE", [VHOST_USER_SET_VRING_ENABLE] = "VHOST_SET_VRING_ENABLE", - [VHOST_USER_GET_QUEUE_NUM] = "VHOST_USER_GET_QUEUE_NUM" + [VHOST_USER_GET_QUEUE_NUM] = "VHOST_USER_GET_QUEUE_NUM", + [VHOST_USER_GET_CONFIG] = "VHOST_USER_GET_CONFIG", + [VHOST_USER_SET_CONFIG] = "VHOST_USER_SET_CONFIG", }; static int @@ -362,6 +365,17 @@ vhost_user_sock(struct virtio_user_dev *dev, } break; + case VHOST_USER_GET_CONFIG: + memcpy(&msg.payload.cfg, arg, sizeof(msg.payload.cfg)); + msg.size = sizeof(msg.payload.cfg); + need_reply = 1; + break; + + case VHOST_USER_SET_CONFIG: + memcpy(&msg.payload.cfg, arg, sizeof(msg.payload.cfg)); + msg.size = sizeof(msg.payload.cfg); + break; + default: SPDK_ERRLOG("trying to send unhandled msg type\n"); return -1; @@ -407,6 +421,13 @@ vhost_user_sock(struct virtio_user_dev *dev, memcpy(arg, &msg.payload.state, sizeof(struct vhost_vring_state)); break; + case VHOST_USER_GET_CONFIG: + if (msg.size != sizeof(msg.payload.cfg)) { + SPDK_WARNLOG("Received bad msg size\n"); + return -1; + } + memcpy(arg, &msg.payload.cfg, sizeof(msg.payload.cfg)); + break; default: SPDK_WARNLOG("Received unexpected msg type\n"); return -1;