Commit 59d901ad authored by Dariusz Stojaczyk's avatar Dariusz Stojaczyk Committed by Jim Harris
Browse files

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: default avatarDariusz Stojaczyk <dariuszx.stojaczyk@intel.com>
Reviewed-on: https://review.gerrithub.io/398828


Tested-by: default avatarSPDK Automated Test System <sys_sgsw@intel.com>
Reviewed-by: default avatarDaniel Verkamp <daniel.verkamp@intel.com>
Reviewed-by: default avatarChangpeng Liu <changpeng.liu@intel.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
parent 1186c5e7
Loading
Loading
Loading
Loading
+23 −2
Original line number Diff line number Diff line
@@ -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
+12 −0
Original line number Diff line number Diff line
@@ -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;

+22 −1
Original line number Diff line number Diff line
@@ -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;