vfio-user: add disable-mappable-bar0 flag
It can be useful for testing or development purposes to force clients to write to doorbells using vfio-user messages instead of directly into shared memory; add a transport-specific option to disable the shared mapping. Signed-off-by: John Levon <john.levon@nutanix.com> Change-Id: I7ed062fbe211ba27c85d00b12d81a0f84a8322ed Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/7554 Community-CI: Broadcom CI Community-CI: Mellanox Build Bot Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Reviewed-by: Ben Walker <benjamin.walker@intel.com> Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com> Reviewed-by: Changpeng Liu <changpeng.liu@intel.com>
This commit is contained in:
parent
4f1530c9eb
commit
bbfbcc1967
@ -193,8 +193,13 @@ struct nvmf_vfio_user_endpoint {
|
|||||||
TAILQ_ENTRY(nvmf_vfio_user_endpoint) link;
|
TAILQ_ENTRY(nvmf_vfio_user_endpoint) link;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct nvmf_vfio_user_transport_opts {
|
||||||
|
bool disable_mappable_bar0;
|
||||||
|
};
|
||||||
|
|
||||||
struct nvmf_vfio_user_transport {
|
struct nvmf_vfio_user_transport {
|
||||||
struct spdk_nvmf_transport transport;
|
struct spdk_nvmf_transport transport;
|
||||||
|
struct nvmf_vfio_user_transport_opts transport_opts;
|
||||||
pthread_mutex_t lock;
|
pthread_mutex_t lock;
|
||||||
TAILQ_HEAD(, nvmf_vfio_user_endpoint) endpoints;
|
TAILQ_HEAD(, nvmf_vfio_user_endpoint) endpoints;
|
||||||
|
|
||||||
@ -324,6 +329,14 @@ nvmf_vfio_user_destroy(struct spdk_nvmf_transport *transport,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const struct spdk_json_object_decoder vfio_user_transport_opts_decoder[] = {
|
||||||
|
{
|
||||||
|
"disable-mappable-bar0",
|
||||||
|
offsetof(struct nvmf_vfio_user_transport, transport_opts.disable_mappable_bar0),
|
||||||
|
spdk_json_decode_bool, true
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
static struct spdk_nvmf_transport *
|
static struct spdk_nvmf_transport *
|
||||||
nvmf_vfio_user_create(struct spdk_nvmf_transport_opts *opts)
|
nvmf_vfio_user_create(struct spdk_nvmf_transport_opts *opts)
|
||||||
{
|
{
|
||||||
@ -345,6 +358,18 @@ nvmf_vfio_user_create(struct spdk_nvmf_transport_opts *opts)
|
|||||||
TAILQ_INIT(&vu_transport->endpoints);
|
TAILQ_INIT(&vu_transport->endpoints);
|
||||||
TAILQ_INIT(&vu_transport->new_qps);
|
TAILQ_INIT(&vu_transport->new_qps);
|
||||||
|
|
||||||
|
if (opts->transport_specific != NULL &&
|
||||||
|
spdk_json_decode_object_relaxed(opts->transport_specific, vfio_user_transport_opts_decoder,
|
||||||
|
SPDK_COUNTOF(vfio_user_transport_opts_decoder),
|
||||||
|
vu_transport)) {
|
||||||
|
SPDK_ERRLOG("spdk_json_decode_object_relaxed failed\n");
|
||||||
|
free(vu_transport);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
SPDK_DEBUGLOG(nvmf_vfio, "vfio_user transport: disable_mappable_bar0=%d\n",
|
||||||
|
vu_transport->transport_opts.disable_mappable_bar0);
|
||||||
|
|
||||||
return &vu_transport->transport;
|
return &vu_transport->transport;
|
||||||
|
|
||||||
err:
|
err:
|
||||||
@ -1330,10 +1355,10 @@ access_bar0_fn(vfu_ctx_t *vfu_ctx, char *buf, size_t count, loff_t pos,
|
|||||||
|
|
||||||
if (pos >= NVMF_VFIO_USER_DOORBELLS_OFFSET) {
|
if (pos >= NVMF_VFIO_USER_DOORBELLS_OFFSET) {
|
||||||
/*
|
/*
|
||||||
* XXX The fact that the doorbells can be memory mapped doesn't
|
* The fact that the doorbells can be memory mapped doesn't mean
|
||||||
* mean thath the client (VFIO in QEMU) is obliged to memory
|
* that the client (VFIO in QEMU) is obliged to memory map them,
|
||||||
* map them, it might still elect to access them via regular
|
* it might still elect to access them via regular read/write;
|
||||||
* read/write.
|
* we might also have had disable_mappable_bar0 set.
|
||||||
*/
|
*/
|
||||||
ret = handle_dbl_access(ctrlr, (uint32_t *)buf, count,
|
ret = handle_dbl_access(ctrlr, (uint32_t *)buf, count,
|
||||||
pos, is_write);
|
pos, is_write);
|
||||||
@ -1442,7 +1467,8 @@ init_pci_config_space(vfu_pci_config_space_t *p)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
vfio_user_dev_info_fill(struct nvmf_vfio_user_endpoint *endpoint)
|
vfio_user_dev_info_fill(struct nvmf_vfio_user_transport *vu_transport,
|
||||||
|
struct nvmf_vfio_user_endpoint *endpoint)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
ssize_t cap_offset;
|
ssize_t cap_offset;
|
||||||
@ -1508,9 +1534,16 @@ vfio_user_dev_info_fill(struct nvmf_vfio_user_endpoint *endpoint)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = vfu_setup_region(vfu_ctx, VFU_PCI_DEV_BAR0_REGION_IDX, NVME_REG_BAR0_SIZE,
|
if (vu_transport->transport_opts.disable_mappable_bar0) {
|
||||||
access_bar0_fn, VFU_REGION_FLAG_RW | VFU_REGION_FLAG_MEM,
|
ret = vfu_setup_region(vfu_ctx, VFU_PCI_DEV_BAR0_REGION_IDX, NVME_REG_BAR0_SIZE,
|
||||||
sparse_mmap, 1, endpoint->fd);
|
access_bar0_fn, VFU_REGION_FLAG_RW | VFU_REGION_FLAG_MEM,
|
||||||
|
NULL, 0, -1);
|
||||||
|
} else {
|
||||||
|
ret = vfu_setup_region(vfu_ctx, VFU_PCI_DEV_BAR0_REGION_IDX, NVME_REG_BAR0_SIZE,
|
||||||
|
access_bar0_fn, VFU_REGION_FLAG_RW | VFU_REGION_FLAG_MEM,
|
||||||
|
sparse_mmap, 1, endpoint->fd);
|
||||||
|
}
|
||||||
|
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
SPDK_ERRLOG("vfu_ctx %p failed to setup bar 0\n", vfu_ctx);
|
SPDK_ERRLOG("vfu_ctx %p failed to setup bar 0\n", vfu_ctx);
|
||||||
return ret;
|
return ret;
|
||||||
@ -1711,7 +1744,7 @@ nvmf_vfio_user_listen(struct spdk_nvmf_transport *transport,
|
|||||||
vfu_setup_log(endpoint->vfu_ctx, vfio_user_log,
|
vfu_setup_log(endpoint->vfu_ctx, vfio_user_log,
|
||||||
SPDK_DEBUGLOG_FLAG_ENABLED("nvmf_vfio") ? LOG_DEBUG : LOG_ERR);
|
SPDK_DEBUGLOG_FLAG_ENABLED("nvmf_vfio") ? LOG_DEBUG : LOG_ERR);
|
||||||
|
|
||||||
err = vfio_user_dev_info_fill(endpoint);
|
err = vfio_user_dev_info_fill(vu_transport, endpoint);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@ -2452,6 +2485,7 @@ nvmf_vfio_user_opts_init(struct spdk_nvmf_transport_opts *opts)
|
|||||||
opts->max_aq_depth = NVMF_VFIO_USER_DEFAULT_AQ_DEPTH;
|
opts->max_aq_depth = NVMF_VFIO_USER_DEFAULT_AQ_DEPTH;
|
||||||
opts->num_shared_buffers = NVMF_VFIO_USER_DEFAULT_NUM_SHARED_BUFFERS;
|
opts->num_shared_buffers = NVMF_VFIO_USER_DEFAULT_NUM_SHARED_BUFFERS;
|
||||||
opts->buf_cache_size = NVMF_VFIO_USER_DEFAULT_BUFFER_CACHE_SIZE;
|
opts->buf_cache_size = NVMF_VFIO_USER_DEFAULT_BUFFER_CACHE_SIZE;
|
||||||
|
opts->transport_specific = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
const struct spdk_nvmf_transport_ops spdk_nvmf_transport_vfio_user = {
|
const struct spdk_nvmf_transport_ops spdk_nvmf_transport_vfio_user = {
|
||||||
|
Loading…
Reference in New Issue
Block a user