1 // SPDX-License-Identifier: GPL-2.0
3 * virtio_pmem.c: Virtio pmem Driver
5 * Discovers persistent memory range information
6 * from host and registers the virtual pmem device
9 #include "virtio_pmem.h"
12 static struct virtio_device_id id_table
[] = {
13 { VIRTIO_ID_PMEM
, VIRTIO_DEV_ANY_ID
},
17 /* Initialize virt queue */
18 static int init_vq(struct virtio_pmem
*vpmem
)
21 vpmem
->req_vq
= virtio_find_single_vq(vpmem
->vdev
,
22 virtio_pmem_host_ack
, "flush_queue");
23 if (IS_ERR(vpmem
->req_vq
))
24 return PTR_ERR(vpmem
->req_vq
);
26 spin_lock_init(&vpmem
->pmem_lock
);
27 INIT_LIST_HEAD(&vpmem
->req_list
);
32 static int virtio_pmem_probe(struct virtio_device
*vdev
)
34 struct nd_region_desc ndr_desc
= {};
35 int nid
= dev_to_node(&vdev
->dev
);
36 struct nd_region
*nd_region
;
37 struct virtio_pmem
*vpmem
;
41 if (!vdev
->config
->get
) {
42 dev_err(&vdev
->dev
, "%s failure: config access disabled\n",
47 vpmem
= devm_kzalloc(&vdev
->dev
, sizeof(*vpmem
), GFP_KERNEL
);
57 dev_err(&vdev
->dev
, "failed to initialize virtio pmem vq's\n");
61 virtio_cread(vpmem
->vdev
, struct virtio_pmem_config
,
62 start
, &vpmem
->start
);
63 virtio_cread(vpmem
->vdev
, struct virtio_pmem_config
,
66 res
.start
= vpmem
->start
;
67 res
.end
= vpmem
->start
+ vpmem
->size
- 1;
68 vpmem
->nd_desc
.provider_name
= "virtio-pmem";
69 vpmem
->nd_desc
.module
= THIS_MODULE
;
71 vpmem
->nvdimm_bus
= nvdimm_bus_register(&vdev
->dev
,
73 if (!vpmem
->nvdimm_bus
) {
74 dev_err(&vdev
->dev
, "failed to register device with nvdimm_bus\n");
79 dev_set_drvdata(&vdev
->dev
, vpmem
->nvdimm_bus
);
82 ndr_desc
.numa_node
= nid
;
83 ndr_desc
.flush
= async_pmem_flush
;
84 set_bit(ND_REGION_PAGEMAP
, &ndr_desc
.flags
);
85 set_bit(ND_REGION_ASYNC
, &ndr_desc
.flags
);
86 nd_region
= nvdimm_pmem_region_create(vpmem
->nvdimm_bus
, &ndr_desc
);
88 dev_err(&vdev
->dev
, "failed to create nvdimm region\n");
92 nd_region
->provider_data
= dev_to_virtio(nd_region
->dev
.parent
->parent
);
95 nvdimm_bus_unregister(vpmem
->nvdimm_bus
);
97 vdev
->config
->del_vqs(vdev
);
102 static void virtio_pmem_remove(struct virtio_device
*vdev
)
104 struct nvdimm_bus
*nvdimm_bus
= dev_get_drvdata(&vdev
->dev
);
106 nvdimm_bus_unregister(nvdimm_bus
);
107 vdev
->config
->del_vqs(vdev
);
108 vdev
->config
->reset(vdev
);
111 static struct virtio_driver virtio_pmem_driver
= {
112 .driver
.name
= KBUILD_MODNAME
,
113 .driver
.owner
= THIS_MODULE
,
114 .id_table
= id_table
,
115 .probe
= virtio_pmem_probe
,
116 .remove
= virtio_pmem_remove
,
119 module_virtio_driver(virtio_pmem_driver
);
120 MODULE_DEVICE_TABLE(virtio
, id_table
);
121 MODULE_DESCRIPTION("Virtio pmem driver");
122 MODULE_LICENSE("GPL");