1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * virtio_pmem.c: Virtio pmem Driver
4 *
5 * Discovers persistent memory range information
6 * from host and registers the virtual pmem device
7 * with libnvdimm core.
8 */
9 #include "virtio_pmem.h"
10 #include "nd.h"
11
12 static struct virtio_device_id id_table[] = {
13 { VIRTIO_ID_PMEM, VIRTIO_DEV_ANY_ID },
14 { 0 },
15 };
16
17 /* Initialize virt queue */
init_vq(struct virtio_pmem * vpmem)18 static int init_vq(struct virtio_pmem *vpmem)
19 {
20 int err;
21
22 /* single vq */
23 vpmem->req_vq = virtio_find_single_vq(vpmem->vdev,
24 virtio_pmem_host_ack, "flush_queue");
25 if (IS_ERR(vpmem->req_vq)) {
26 err = PTR_ERR(vpmem->req_vq);
27 vpmem->req_vq = NULL;
28 return err;
29 }
30
31 spin_lock_init(&vpmem->pmem_lock);
32 INIT_LIST_HEAD(&vpmem->req_list);
33 vpmem->req_inflight = NULL;
34 WRITE_ONCE(vpmem->broken, false);
35
36 return 0;
37 };
38
virtio_pmem_del_vqs(struct virtio_pmem * vpmem)39 static void virtio_pmem_del_vqs(struct virtio_pmem *vpmem)
40 {
41 if (!vpmem->req_vq)
42 return;
43
44 vpmem->vdev->config->del_vqs(vpmem->vdev);
45 vpmem->req_vq = NULL;
46 }
47
virtio_pmem_validate(struct virtio_device * vdev)48 static int virtio_pmem_validate(struct virtio_device *vdev)
49 {
50 struct virtio_shm_region shm_reg;
51
52 if (virtio_has_feature(vdev, VIRTIO_PMEM_F_SHMEM_REGION) &&
53 !virtio_get_shm_region(vdev, &shm_reg, (u8)VIRTIO_PMEM_SHMEM_REGION_ID)
54 ) {
55 dev_notice(&vdev->dev, "failed to get shared memory region %d\n",
56 VIRTIO_PMEM_SHMEM_REGION_ID);
57 __virtio_clear_bit(vdev, VIRTIO_PMEM_F_SHMEM_REGION);
58 }
59 return 0;
60 }
61
virtio_pmem_probe(struct virtio_device * vdev)62 static int virtio_pmem_probe(struct virtio_device *vdev)
63 {
64 struct nd_region_desc ndr_desc = {};
65 struct nd_region *nd_region;
66 struct virtio_pmem *vpmem;
67 struct resource res;
68 struct virtio_shm_region shm_reg;
69 int err = 0;
70
71 if (!vdev->config->get) {
72 dev_err(&vdev->dev, "%s failure: config access disabled\n",
73 __func__);
74 return -EINVAL;
75 }
76
77 vpmem = devm_kzalloc(&vdev->dev, sizeof(*vpmem), GFP_KERNEL);
78 if (!vpmem) {
79 err = -ENOMEM;
80 goto out_err;
81 }
82
83 mutex_init(&vpmem->flush_lock);
84 vpmem->vdev = vdev;
85 vdev->priv = vpmem;
86 vpmem->flush_wq = alloc_ordered_workqueue("virtio-pmem-flush",
87 WQ_MEM_RECLAIM);
88 if (!vpmem->flush_wq) {
89 err = -ENOMEM;
90 goto out_err;
91 }
92
93 err = init_vq(vpmem);
94 if (err) {
95 dev_err(&vdev->dev, "failed to initialize virtio pmem vq's\n");
96 goto out_wq;
97 }
98
99 if (virtio_has_feature(vdev, VIRTIO_PMEM_F_SHMEM_REGION)) {
100 virtio_get_shm_region(vdev, &shm_reg, (u8)VIRTIO_PMEM_SHMEM_REGION_ID);
101 vpmem->start = shm_reg.addr;
102 vpmem->size = shm_reg.len;
103 } else {
104 virtio_cread_le(vpmem->vdev, struct virtio_pmem_config,
105 start, &vpmem->start);
106 virtio_cread_le(vpmem->vdev, struct virtio_pmem_config,
107 size, &vpmem->size);
108 }
109
110 res.start = vpmem->start;
111 res.end = vpmem->start + vpmem->size - 1;
112 vpmem->nd_desc.provider_name = "virtio-pmem";
113 vpmem->nd_desc.module = THIS_MODULE;
114
115 vpmem->nvdimm_bus = nvdimm_bus_register(&vdev->dev,
116 &vpmem->nd_desc);
117 if (!vpmem->nvdimm_bus) {
118 dev_err(&vdev->dev, "failed to register device with nvdimm_bus\n");
119 err = -ENXIO;
120 goto out_vq;
121 }
122
123 dev_set_drvdata(&vdev->dev, vpmem->nvdimm_bus);
124
125 ndr_desc.res = &res;
126
127 ndr_desc.numa_node = memory_add_physaddr_to_nid(res.start);
128 ndr_desc.target_node = phys_to_target_node(res.start);
129 if (ndr_desc.target_node == NUMA_NO_NODE) {
130 ndr_desc.target_node = ndr_desc.numa_node;
131 dev_dbg(&vdev->dev, "changing target node from %d to %d",
132 NUMA_NO_NODE, ndr_desc.target_node);
133 }
134
135 ndr_desc.flush = async_pmem_flush;
136 ndr_desc.provider_data = vdev;
137 set_bit(ND_REGION_PAGEMAP, &ndr_desc.flags);
138 set_bit(ND_REGION_ASYNC, &ndr_desc.flags);
139 /*
140 * The NVDIMM region could be available before the
141 * virtio_device_ready() that is called by
142 * virtio_dev_probe(), so we set device ready here.
143 */
144 virtio_device_ready(vdev);
145 nd_region = nvdimm_pmem_region_create(vpmem->nvdimm_bus, &ndr_desc);
146 if (!nd_region) {
147 dev_err(&vdev->dev, "failed to create nvdimm region\n");
148 err = -ENXIO;
149 goto out_nd;
150 }
151 return 0;
152 out_nd:
153 virtio_reset_device(vdev);
154 nvdimm_bus_unregister(vpmem->nvdimm_bus);
155 out_vq:
156 virtio_pmem_del_vqs(vpmem);
157 out_wq:
158 destroy_workqueue(vpmem->flush_wq);
159 out_err:
160 return err;
161 }
162
virtio_pmem_remove(struct virtio_device * vdev)163 static void virtio_pmem_remove(struct virtio_device *vdev)
164 {
165 struct nvdimm_bus *nvdimm_bus = dev_get_drvdata(&vdev->dev);
166 struct virtio_pmem *vpmem = vdev->priv;
167 unsigned long flags;
168
169 spin_lock_irqsave(&vpmem->pmem_lock, flags);
170 virtio_pmem_mark_broken(vpmem);
171 spin_unlock_irqrestore(&vpmem->pmem_lock, flags);
172
173 drain_workqueue(vpmem->flush_wq);
174 virtio_reset_device(vdev);
175
176 spin_lock_irqsave(&vpmem->pmem_lock, flags);
177 virtio_pmem_drain(vpmem);
178 spin_unlock_irqrestore(&vpmem->pmem_lock, flags);
179
180 nvdimm_bus_unregister(nvdimm_bus);
181 virtio_pmem_del_vqs(vpmem);
182 destroy_workqueue(vpmem->flush_wq);
183 }
184
virtio_pmem_freeze(struct virtio_device * vdev)185 static int virtio_pmem_freeze(struct virtio_device *vdev)
186 {
187 struct virtio_pmem *vpmem = vdev->priv;
188 unsigned long flags;
189
190 spin_lock_irqsave(&vpmem->pmem_lock, flags);
191 virtio_pmem_mark_broken(vpmem);
192 spin_unlock_irqrestore(&vpmem->pmem_lock, flags);
193
194 drain_workqueue(vpmem->flush_wq);
195 virtio_reset_device(vdev);
196
197 spin_lock_irqsave(&vpmem->pmem_lock, flags);
198 virtio_pmem_drain(vpmem);
199 spin_unlock_irqrestore(&vpmem->pmem_lock, flags);
200
201 virtio_pmem_del_vqs(vpmem);
202
203 return 0;
204 }
205
virtio_pmem_restore(struct virtio_device * vdev)206 static int virtio_pmem_restore(struct virtio_device *vdev)
207 {
208 int ret;
209
210 ret = init_vq(vdev->priv);
211 if (ret) {
212 dev_err(&vdev->dev, "failed to initialize virtio pmem's vq\n");
213 return ret;
214 }
215 virtio_device_ready(vdev);
216
217 return 0;
218 }
219
220 static unsigned int features[] = {
221 VIRTIO_PMEM_F_SHMEM_REGION,
222 };
223
224 static struct virtio_driver virtio_pmem_driver = {
225 .feature_table = features,
226 .feature_table_size = ARRAY_SIZE(features),
227 .driver.name = KBUILD_MODNAME,
228 .id_table = id_table,
229 .validate = virtio_pmem_validate,
230 .probe = virtio_pmem_probe,
231 .remove = virtio_pmem_remove,
232 .freeze = virtio_pmem_freeze,
233 .restore = virtio_pmem_restore,
234 };
235
236 module_virtio_driver(virtio_pmem_driver);
237 MODULE_DEVICE_TABLE(virtio, id_table);
238 MODULE_DESCRIPTION("Virtio pmem driver");
239 MODULE_LICENSE("GPL");
240