@@ -37,6 +37,8 @@ static int virtio_pmem_probe(struct virtio_device *vdev)
3737 struct virtio_pmem * vpmem ;
3838 struct resource res ;
3939 int err = 0 ;
40+ bool have_shm_region ;
41+ struct virtio_shm_region pmem_region ;
4042
4143 if (!vdev -> config -> get ) {
4244 dev_err (& vdev -> dev , "%s failure: config access disabled\n" ,
@@ -58,10 +60,21 @@ static int virtio_pmem_probe(struct virtio_device *vdev)
5860 goto out_err ;
5961 }
6062
61- virtio_cread_le (vpmem -> vdev , struct virtio_pmem_config ,
62- start , & vpmem -> start );
63- virtio_cread_le (vpmem -> vdev , struct virtio_pmem_config ,
64- size , & vpmem -> size );
63+ /* Retrieve the pmem device's address and size. It may have been supplied
64+ * as a PCI BAR-relative shared memory region, or as a guest absolute address.
65+ */
66+ have_shm_region = virtio_get_shm_region (vpmem -> vdev , & pmem_region ,
67+ VIRTIO_PMEM_SHMCAP_ID_PMEM_REGION );
68+
69+ if (have_shm_region ) {
70+ vpmem -> start = pmem_region .addr ;
71+ vpmem -> size = pmem_region .len ;
72+ } else {
73+ virtio_cread_le (vpmem -> vdev , struct virtio_pmem_config ,
74+ start , & vpmem -> start );
75+ virtio_cread_le (vpmem -> vdev , struct virtio_pmem_config ,
76+ size , & vpmem -> size );
77+ }
6578
6679 res .start = vpmem -> start ;
6780 res .end = vpmem -> start + vpmem -> size - 1 ;
@@ -78,6 +91,11 @@ static int virtio_pmem_probe(struct virtio_device *vdev)
7891
7992 dev_set_drvdata (& vdev -> dev , vpmem -> nvdimm_bus );
8093
94+ /* Online the device prior to creating a pmem region, to ensure that
95+ * the region is never touched while the device is offline.
96+ */
97+ virtio_device_ready (vdev );
98+
8199 ndr_desc .res = & res ;
82100 ndr_desc .numa_node = nid ;
83101 ndr_desc .flush = async_pmem_flush ;
@@ -92,6 +110,7 @@ static int virtio_pmem_probe(struct virtio_device *vdev)
92110 nd_region -> provider_data = dev_to_virtio (nd_region -> dev .parent -> parent );
93111 return 0 ;
94112out_nd :
113+ vdev -> config -> reset (vdev );
95114 nvdimm_bus_unregister (vpmem -> nvdimm_bus );
96115out_vq :
97116 vdev -> config -> del_vqs (vdev );
0 commit comments