As per virtio spec 1.2 section 5.19.5.2, if the feature VIRTIO_PMEM_F_SHMEM_REGION has been negotiated, the driver MUST query shared memory ID 0 for the physical address ranges. Signed-off-by: Changyuan Lyu <changyuanl@xxxxxxxxxx> --- drivers/nvdimm/virtio_pmem.c | 29 +++++++++++++++++++++++++---- include/uapi/linux/virtio_pmem.h | 8 ++++++++ 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/drivers/nvdimm/virtio_pmem.c b/drivers/nvdimm/virtio_pmem.c index a92eb172f0e7..5b28d543728b 100644 --- a/drivers/nvdimm/virtio_pmem.c +++ b/drivers/nvdimm/virtio_pmem.c @@ -35,6 +35,8 @@ static int virtio_pmem_probe(struct virtio_device *vdev) struct nd_region *nd_region; struct virtio_pmem *vpmem; struct resource res; + struct virtio_shm_region shm_reg; + bool have_shm; int err = 0; if (!vdev->config->get) { @@ -57,10 +59,23 @@ static int virtio_pmem_probe(struct virtio_device *vdev) goto out_err; } - virtio_cread_le(vpmem->vdev, struct virtio_pmem_config, - start, &vpmem->start); - virtio_cread_le(vpmem->vdev, struct virtio_pmem_config, - size, &vpmem->size); + if (virtio_has_feature(vdev, VIRTIO_PMEM_F_SHMEM_REGION)) { + have_shm = virtio_get_shm_region(vdev, &shm_reg, + (u8)VIRTIO_PMEM_SHMCAP_ID); + if (!have_shm) { + dev_err(&vdev->dev, "failed to get shared memory region %d\n", + VIRTIO_PMEM_SHMCAP_ID); + return -EINVAL; + } + vpmem->start = shm_reg.addr; + vpmem->size = shm_reg.len; + } else { + virtio_cread_le(vpmem->vdev, struct virtio_pmem_config, + start, &vpmem->start); + virtio_cread_le(vpmem->vdev, struct virtio_pmem_config, + size, &vpmem->size); + } + res.start = vpmem->start; res.end = vpmem->start + vpmem->size - 1; @@ -122,7 +137,13 @@ static void virtio_pmem_remove(struct virtio_device *vdev) virtio_reset_device(vdev); } +static unsigned int features[] = { + VIRTIO_PMEM_F_SHMEM_REGION, +}; + static struct virtio_driver virtio_pmem_driver = { + .feature_table = features, + .feature_table_size = ARRAY_SIZE(features), .driver.name = KBUILD_MODNAME, .driver.owner = THIS_MODULE, .id_table = id_table, diff --git a/include/uapi/linux/virtio_pmem.h b/include/uapi/linux/virtio_pmem.h index d676b3620383..025174f6eacf 100644 --- a/include/uapi/linux/virtio_pmem.h +++ b/include/uapi/linux/virtio_pmem.h @@ -14,6 +14,14 @@ #include <linux/virtio_ids.h> #include <linux/virtio_config.h> +/* Feature bits */ +#define VIRTIO_PMEM_F_SHMEM_REGION 0 /* guest physical address range will be + * indicated as shared memory region 0 + */ + +/* shmid of the shared memory region corresponding to the pmem */ +#define VIRTIO_PMEM_SHMCAP_ID 0 + struct virtio_pmem_config { __le64 start; __le64 size; -- 2.43.0.472.g3155946c3a-goog