Commit 53c24913 authored by Changpeng Liu's avatar Changpeng Liu Committed by Jim Harris
Browse files

vhost_lib: enable virtio configuration space feature



New added vhost user messages: GET_CONFIG/SET_CONFIG are
used for get/set virtio device's configuration space, this
commit enable the new added vhost messages.

Change-Id: I5c3e3f8fb6ed55e99299323c39658765b1724bb8
Signed-off-by: default avatarChangpeng Liu <changpeng.liu@intel.com>
Reviewed-on: https://review.gerrithub.io/386545


Tested-by: default avatarSPDK Automated Test System <sys_sgsw@intel.com>
Reviewed-by: default avatarDariusz Stojaczyk <dariuszx.stojaczyk@intel.com>
Reviewed-by: default avatarDaniel Verkamp <daniel.verkamp@intel.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
parent 88da45bf
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -108,6 +108,10 @@ struct vhost_device_ops {
	int (*new_connection)(int vid);
	void (*destroy_connection)(int vid);

	int (*get_config)(int vid, uint8_t *config, uint32_t config_len);
	int (*set_config)(int vid, uint8_t *config, uint32_t offset,
			  uint32_t len, uint32_t flags);

	void *reserved[2]; /**< Reserved for future extension */
};

+21 −0
Original line number Diff line number Diff line
@@ -76,6 +76,8 @@ static const char *vhost_message_str[VHOST_USER_MAX] = {
	[VHOST_USER_SET_VRING_ENABLE]  = "VHOST_USER_SET_VRING_ENABLE",
	[VHOST_USER_SEND_RARP]  = "VHOST_USER_SEND_RARP",
	[VHOST_USER_NET_SET_MTU]  = "VHOST_USER_NET_SET_MTU",
	[VHOST_USER_GET_CONFIG] = "VHOST_USER_GET_CONFIG",
	[VHOST_USER_SET_CONFIG] = "VHOST_USER_SET_CONFIG",
};

static uint64_t
@@ -1063,6 +1065,25 @@ vhost_user_msg_handler(int vid, int fd)
	}

	switch (msg.request) {
	case VHOST_USER_GET_CONFIG:
		if (dev->notify_ops->get_config(dev->vid,
						msg.payload.config.region,
						msg.payload.config.size) != 0) {
			msg.size = sizeof(uint64_t);
		}
		send_vhost_message(fd, &msg);
		break;
	case VHOST_USER_SET_CONFIG:
		if ((dev->notify_ops->set_config(dev->vid,
						msg.payload.config.region,
						msg.payload.config.offset,
						msg.payload.config.size,
						msg.payload.config.flags)) != 0) {
			ret = 1;
		} else {
			ret = 0;
		}
		break;
	case VHOST_USER_GET_FEATURES:
		msg.payload.u64 = vhost_user_get_features(dev);
		msg.size = sizeof(msg.payload.u64);
+22 −0
Original line number Diff line number Diff line
@@ -43,6 +43,11 @@

#define VHOST_MEMORY_MAX_NREGIONS 8

/*
 * Maximum size of virtio device config space
 */
#define VHOST_USER_MAX_CONFIG_SIZE 256

#define VHOST_USER_PROTOCOL_F_MQ	0
#define VHOST_USER_PROTOCOL_F_LOG_SHMFD	1
#define VHOST_USER_PROTOCOL_F_RARP	2
@@ -77,9 +82,18 @@ typedef enum VhostUserRequest {
	VHOST_USER_SET_VRING_ENABLE = 18,
	VHOST_USER_SEND_RARP = 19,
	VHOST_USER_NET_SET_MTU = 20,
	VHOST_USER_GET_CONFIG = 24,
	VHOST_USER_SET_CONFIG = 25,
	VHOST_USER_MAX
} VhostUserRequest;

typedef enum VhostUserSlaveRequest {
	VHOST_USER_SLAVE_NONE = 0,
	VHOST_USER_SLAVE_IOTLB_MSG = 1,
	VHOST_USER_SLAVE_CONFIG_CHANGE_MSG = 2,
	VHOST_USER_SLAVE_MAX
} VhostUserSlaveRequest;

typedef struct VhostUserMemoryRegion {
	uint64_t guest_phys_addr;
	uint64_t memory_size;
@@ -98,6 +112,13 @@ typedef struct VhostUserLog {
	uint64_t mmap_offset;
} VhostUserLog;

typedef struct VhostUserConfig {
	uint32_t offset;
	uint32_t size;
	uint32_t flags;
	uint8_t region[VHOST_USER_MAX_CONFIG_SIZE];
} VhostUserConfig;

typedef struct VhostUserMsg {
	VhostUserRequest request;

@@ -114,6 +135,7 @@ typedef struct VhostUserMsg {
		struct vhost_vring_addr addr;
		VhostUserMemory memory;
		VhostUserLog    log;
		VhostUserConfig config;
	} payload;
	int fds[VHOST_MEMORY_MAX_NREGIONS];
} __attribute((packed)) VhostUserMsg;
+49 −0
Original line number Diff line number Diff line
@@ -70,10 +70,15 @@ static int new_connection(int vid);
static int start_device(int vid);
static void stop_device(int vid);
static void destroy_connection(int vid);
static int get_config(int vid, uint8_t *config, uint32_t len);
static int set_config(int vid, uint8_t *config, uint32_t offset,
		      uint32_t size, uint32_t flags);

const struct vhost_device_ops g_spdk_vhost_ops = {
	.new_device =  start_device,
	.destroy_device = stop_device,
	.get_config = get_config,
	.set_config = set_config,
	.new_connection = new_connection,
	.destroy_connection = destroy_connection,
};
@@ -957,6 +962,50 @@ out:
	return rc;
}

static int
get_config(int vid, uint8_t *config, uint32_t len)
{
	struct spdk_vhost_dev *vdev;
	int rc = -1;

	pthread_mutex_lock(&g_spdk_vhost_mutex);
	vdev = spdk_vhost_dev_find_by_vid(vid);
	if (vdev == NULL) {
		SPDK_ERRLOG("Controller with vid %d doesn't exist.\n", vid);
		goto out;
	}

	if (vdev->backend->vhost_get_config) {
		rc = vdev->backend->vhost_get_config(vdev, config, len);
	}

out:
	pthread_mutex_unlock(&g_spdk_vhost_mutex);
	return rc;
}

static int
set_config(int vid, uint8_t *config, uint32_t offset, uint32_t size, uint32_t flags)
{
	struct spdk_vhost_dev *vdev;
	int rc = -1;

	pthread_mutex_lock(&g_spdk_vhost_mutex);
	vdev = spdk_vhost_dev_find_by_vid(vid);
	if (vdev == NULL) {
		SPDK_ERRLOG("Controller with vid %d doesn't exist.\n", vid);
		goto out;
	}

	if (vdev->backend->vhost_set_config) {
		rc = vdev->backend->vhost_set_config(vdev, config, offset, size, flags);
	}

out:
	pthread_mutex_unlock(&g_spdk_vhost_mutex);
	return rc;
}

void
spdk_vhost_startup(void *arg1, void *arg2)
{
+4 −0
Original line number Diff line number Diff line
@@ -130,6 +130,10 @@ struct spdk_vhost_dev_backend {
	spdk_vhost_event_fn start_device;
	spdk_vhost_event_fn stop_device;

	int (*vhost_get_config)(struct spdk_vhost_dev *vdev, uint8_t *config, uint32_t len);
	int (*vhost_set_config)(struct spdk_vhost_dev *vdev, uint8_t *config,
				uint32_t offset, uint32_t size, uint32_t flags);

	void (*dump_config_json)(struct spdk_vhost_dev *vdev, struct spdk_json_write_ctx *w);
	int (*vhost_remove_controller)(struct spdk_vhost_dev *vdev);
};