1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3 * VDPA device simulator core.
4 *
5 * Copyright (c) 2020, Red Hat Inc. All rights reserved.
6 * Author: Jason Wang <jasowang@redhat.com>
7 *
8 */
9
10 #include <linux/init.h>
11 #include <linux/module.h>
12 #include <linux/device.h>
13 #include <linux/kernel.h>
14 #include <linux/slab.h>
15 #include <linux/sched.h>
16 #include <linux/dma-map-ops.h>
17 #include <linux/vringh.h>
18 #include <linux/vdpa.h>
19 #include <linux/vhost_iotlb.h>
20 #include <uapi/linux/vdpa.h>
21
22 #include "vdpa_sim.h"
23
24 #define DRV_VERSION "0.1"
25 #define DRV_AUTHOR "Jason Wang <jasowang@redhat.com>"
26 #define DRV_DESC "vDPA Device Simulator core"
27 #define DRV_LICENSE "GPL v2"
28
29 static int batch_mapping = 1;
30 module_param(batch_mapping, int, 0444);
31 MODULE_PARM_DESC(batch_mapping, "Batched mapping 1 -Enable; 0 - Disable");
32
33 static int max_iotlb_entries = 2048;
34 module_param(max_iotlb_entries, int, 0444);
35 MODULE_PARM_DESC(max_iotlb_entries,
36 "Maximum number of iotlb entries for each address space. 0 means unlimited. (default: 2048)");
37
38 #define VDPASIM_QUEUE_ALIGN PAGE_SIZE
39 #define VDPASIM_QUEUE_MAX 256
40 #define VDPASIM_VENDOR_ID 0
41
vdpa_to_sim(struct vdpa_device * vdpa)42 static struct vdpasim *vdpa_to_sim(struct vdpa_device *vdpa)
43 {
44 return container_of(vdpa, struct vdpasim, vdpa);
45 }
46
vdpasim_vq_notify(struct vringh * vring)47 static void vdpasim_vq_notify(struct vringh *vring)
48 {
49 struct vdpasim_virtqueue *vq =
50 container_of(vring, struct vdpasim_virtqueue, vring);
51
52 if (!vq->cb)
53 return;
54
55 vq->cb(vq->private);
56 }
57
vdpasim_queue_ready(struct vdpasim * vdpasim,unsigned int idx)58 static void vdpasim_queue_ready(struct vdpasim *vdpasim, unsigned int idx)
59 {
60 struct vdpasim_virtqueue *vq = &vdpasim->vqs[idx];
61 uint16_t last_avail_idx = vq->vring.last_avail_idx;
62
63 vringh_init_iotlb(&vq->vring, vdpasim->features, vq->num, true,
64 (struct vring_desc *)(uintptr_t)vq->desc_addr,
65 (struct vring_avail *)
66 (uintptr_t)vq->driver_addr,
67 (struct vring_used *)
68 (uintptr_t)vq->device_addr);
69
70 vq->vring.last_avail_idx = last_avail_idx;
71 vq->vring.notify = vdpasim_vq_notify;
72 }
73
vdpasim_vq_reset(struct vdpasim * vdpasim,struct vdpasim_virtqueue * vq)74 static void vdpasim_vq_reset(struct vdpasim *vdpasim,
75 struct vdpasim_virtqueue *vq)
76 {
77 vq->ready = false;
78 vq->desc_addr = 0;
79 vq->driver_addr = 0;
80 vq->device_addr = 0;
81 vq->cb = NULL;
82 vq->private = NULL;
83 vringh_init_iotlb(&vq->vring, vdpasim->dev_attr.supported_features,
84 VDPASIM_QUEUE_MAX, false, NULL, NULL, NULL);
85
86 vq->vring.notify = NULL;
87 }
88
vdpasim_do_reset(struct vdpasim * vdpasim)89 static void vdpasim_do_reset(struct vdpasim *vdpasim)
90 {
91 int i;
92
93 spin_lock(&vdpasim->iommu_lock);
94
95 for (i = 0; i < vdpasim->dev_attr.nvqs; i++) {
96 vdpasim_vq_reset(vdpasim, &vdpasim->vqs[i]);
97 vringh_set_iotlb(&vdpasim->vqs[i].vring, &vdpasim->iommu[0],
98 &vdpasim->iommu_lock);
99 }
100
101 for (i = 0; i < vdpasim->dev_attr.nas; i++) {
102 vhost_iotlb_reset(&vdpasim->iommu[i]);
103 vhost_iotlb_add_range(&vdpasim->iommu[i], 0, ULONG_MAX,
104 0, VHOST_MAP_RW);
105 vdpasim->iommu_pt[i] = true;
106 }
107
108 vdpasim->running = true;
109 spin_unlock(&vdpasim->iommu_lock);
110
111 vdpasim->features = 0;
112 vdpasim->status = 0;
113 ++vdpasim->generation;
114 }
115
116 static const struct vdpa_config_ops vdpasim_config_ops;
117 static const struct vdpa_config_ops vdpasim_batch_config_ops;
118
vdpasim_create(struct vdpasim_dev_attr * dev_attr,const struct vdpa_dev_set_config * config)119 struct vdpasim *vdpasim_create(struct vdpasim_dev_attr *dev_attr,
120 const struct vdpa_dev_set_config *config)
121 {
122 const struct vdpa_config_ops *ops;
123 struct vdpa_device *vdpa;
124 struct vdpasim *vdpasim;
125 struct device *dev;
126 int i, ret = -ENOMEM;
127
128 if (!dev_attr->alloc_size)
129 return ERR_PTR(-EINVAL);
130
131 if (config->mask & BIT_ULL(VDPA_ATTR_DEV_FEATURES)) {
132 if (config->device_features &
133 ~dev_attr->supported_features)
134 return ERR_PTR(-EINVAL);
135 dev_attr->supported_features =
136 config->device_features;
137 }
138
139 if (batch_mapping)
140 ops = &vdpasim_batch_config_ops;
141 else
142 ops = &vdpasim_config_ops;
143
144 vdpa = __vdpa_alloc_device(NULL, ops,
145 dev_attr->ngroups, dev_attr->nas,
146 dev_attr->alloc_size,
147 dev_attr->name, false);
148 if (IS_ERR(vdpa)) {
149 ret = PTR_ERR(vdpa);
150 goto err_alloc;
151 }
152
153 vdpasim = vdpa_to_sim(vdpa);
154 vdpasim->dev_attr = *dev_attr;
155 INIT_WORK(&vdpasim->work, dev_attr->work_fn);
156 spin_lock_init(&vdpasim->lock);
157 spin_lock_init(&vdpasim->iommu_lock);
158
159 dev = &vdpasim->vdpa.dev;
160 dev->dma_mask = &dev->coherent_dma_mask;
161 if (dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64)))
162 goto err_iommu;
163 vdpasim->vdpa.mdev = dev_attr->mgmt_dev;
164
165 vdpasim->config = kzalloc(dev_attr->config_size, GFP_KERNEL);
166 if (!vdpasim->config)
167 goto err_iommu;
168
169 vdpasim->vqs = kcalloc(dev_attr->nvqs, sizeof(struct vdpasim_virtqueue),
170 GFP_KERNEL);
171 if (!vdpasim->vqs)
172 goto err_iommu;
173
174 vdpasim->iommu = kmalloc_array(vdpasim->dev_attr.nas,
175 sizeof(*vdpasim->iommu), GFP_KERNEL);
176 if (!vdpasim->iommu)
177 goto err_iommu;
178
179 vdpasim->iommu_pt = kmalloc_array(vdpasim->dev_attr.nas,
180 sizeof(*vdpasim->iommu_pt), GFP_KERNEL);
181 if (!vdpasim->iommu_pt)
182 goto err_iommu;
183
184 for (i = 0; i < vdpasim->dev_attr.nas; i++)
185 vhost_iotlb_init(&vdpasim->iommu[i], max_iotlb_entries, 0);
186
187 vdpasim->buffer = kvmalloc(dev_attr->buffer_size, GFP_KERNEL);
188 if (!vdpasim->buffer)
189 goto err_iommu;
190
191 for (i = 0; i < dev_attr->nvqs; i++)
192 vringh_set_iotlb(&vdpasim->vqs[i].vring, &vdpasim->iommu[0],
193 &vdpasim->iommu_lock);
194
195 vdpasim->vdpa.dma_dev = dev;
196
197 return vdpasim;
198
199 err_iommu:
200 put_device(dev);
201 err_alloc:
202 return ERR_PTR(ret);
203 }
204 EXPORT_SYMBOL_GPL(vdpasim_create);
205
vdpasim_set_vq_address(struct vdpa_device * vdpa,u16 idx,u64 desc_area,u64 driver_area,u64 device_area)206 static int vdpasim_set_vq_address(struct vdpa_device *vdpa, u16 idx,
207 u64 desc_area, u64 driver_area,
208 u64 device_area)
209 {
210 struct vdpasim *vdpasim = vdpa_to_sim(vdpa);
211 struct vdpasim_virtqueue *vq = &vdpasim->vqs[idx];
212
213 vq->desc_addr = desc_area;
214 vq->driver_addr = driver_area;
215 vq->device_addr = device_area;
216
217 return 0;
218 }
219
vdpasim_set_vq_num(struct vdpa_device * vdpa,u16 idx,u32 num)220 static void vdpasim_set_vq_num(struct vdpa_device *vdpa, u16 idx, u32 num)
221 {
222 struct vdpasim *vdpasim = vdpa_to_sim(vdpa);
223 struct vdpasim_virtqueue *vq = &vdpasim->vqs[idx];
224
225 vq->num = num;
226 }
227
vdpasim_kick_vq(struct vdpa_device * vdpa,u16 idx)228 static void vdpasim_kick_vq(struct vdpa_device *vdpa, u16 idx)
229 {
230 struct vdpasim *vdpasim = vdpa_to_sim(vdpa);
231 struct vdpasim_virtqueue *vq = &vdpasim->vqs[idx];
232
233 if (!vdpasim->running &&
234 (vdpasim->status & VIRTIO_CONFIG_S_DRIVER_OK)) {
235 vdpasim->pending_kick = true;
236 return;
237 }
238
239 if (vq->ready)
240 schedule_work(&vdpasim->work);
241 }
242
vdpasim_set_vq_cb(struct vdpa_device * vdpa,u16 idx,struct vdpa_callback * cb)243 static void vdpasim_set_vq_cb(struct vdpa_device *vdpa, u16 idx,
244 struct vdpa_callback *cb)
245 {
246 struct vdpasim *vdpasim = vdpa_to_sim(vdpa);
247 struct vdpasim_virtqueue *vq = &vdpasim->vqs[idx];
248
249 vq->cb = cb->callback;
250 vq->private = cb->private;
251 }
252
vdpasim_set_vq_ready(struct vdpa_device * vdpa,u16 idx,bool ready)253 static void vdpasim_set_vq_ready(struct vdpa_device *vdpa, u16 idx, bool ready)
254 {
255 struct vdpasim *vdpasim = vdpa_to_sim(vdpa);
256 struct vdpasim_virtqueue *vq = &vdpasim->vqs[idx];
257 bool old_ready;
258
259 spin_lock(&vdpasim->lock);
260 old_ready = vq->ready;
261 vq->ready = ready;
262 if (vq->ready && !old_ready) {
263 vdpasim_queue_ready(vdpasim, idx);
264 }
265 spin_unlock(&vdpasim->lock);
266 }
267
vdpasim_get_vq_ready(struct vdpa_device * vdpa,u16 idx)268 static bool vdpasim_get_vq_ready(struct vdpa_device *vdpa, u16 idx)
269 {
270 struct vdpasim *vdpasim = vdpa_to_sim(vdpa);
271 struct vdpasim_virtqueue *vq = &vdpasim->vqs[idx];
272
273 return vq->ready;
274 }
275
vdpasim_set_vq_state(struct vdpa_device * vdpa,u16 idx,const struct vdpa_vq_state * state)276 static int vdpasim_set_vq_state(struct vdpa_device *vdpa, u16 idx,
277 const struct vdpa_vq_state *state)
278 {
279 struct vdpasim *vdpasim = vdpa_to_sim(vdpa);
280 struct vdpasim_virtqueue *vq = &vdpasim->vqs[idx];
281 struct vringh *vrh = &vq->vring;
282
283 spin_lock(&vdpasim->lock);
284 vrh->last_avail_idx = state->split.avail_index;
285 spin_unlock(&vdpasim->lock);
286
287 return 0;
288 }
289
vdpasim_get_vq_state(struct vdpa_device * vdpa,u16 idx,struct vdpa_vq_state * state)290 static int vdpasim_get_vq_state(struct vdpa_device *vdpa, u16 idx,
291 struct vdpa_vq_state *state)
292 {
293 struct vdpasim *vdpasim = vdpa_to_sim(vdpa);
294 struct vdpasim_virtqueue *vq = &vdpasim->vqs[idx];
295 struct vringh *vrh = &vq->vring;
296
297 state->split.avail_index = vrh->last_avail_idx;
298 return 0;
299 }
300
vdpasim_get_vq_stats(struct vdpa_device * vdpa,u16 idx,struct sk_buff * msg,struct netlink_ext_ack * extack)301 static int vdpasim_get_vq_stats(struct vdpa_device *vdpa, u16 idx,
302 struct sk_buff *msg,
303 struct netlink_ext_ack *extack)
304 {
305 struct vdpasim *vdpasim = vdpa_to_sim(vdpa);
306
307 if (vdpasim->dev_attr.get_stats)
308 return vdpasim->dev_attr.get_stats(vdpasim, idx,
309 msg, extack);
310 return -EOPNOTSUPP;
311 }
312
vdpasim_get_vq_align(struct vdpa_device * vdpa)313 static u32 vdpasim_get_vq_align(struct vdpa_device *vdpa)
314 {
315 return VDPASIM_QUEUE_ALIGN;
316 }
317
vdpasim_get_vq_group(struct vdpa_device * vdpa,u16 idx)318 static u32 vdpasim_get_vq_group(struct vdpa_device *vdpa, u16 idx)
319 {
320 /* RX and TX belongs to group 0, CVQ belongs to group 1 */
321 if (idx == 2)
322 return 1;
323 else
324 return 0;
325 }
326
vdpasim_get_device_features(struct vdpa_device * vdpa)327 static u64 vdpasim_get_device_features(struct vdpa_device *vdpa)
328 {
329 struct vdpasim *vdpasim = vdpa_to_sim(vdpa);
330
331 return vdpasim->dev_attr.supported_features;
332 }
333
vdpasim_set_driver_features(struct vdpa_device * vdpa,u64 features)334 static int vdpasim_set_driver_features(struct vdpa_device *vdpa, u64 features)
335 {
336 struct vdpasim *vdpasim = vdpa_to_sim(vdpa);
337
338 /* DMA mapping must be done by driver */
339 if (!(features & (1ULL << VIRTIO_F_ACCESS_PLATFORM)))
340 return -EINVAL;
341
342 vdpasim->features = features & vdpasim->dev_attr.supported_features;
343
344 return 0;
345 }
346
vdpasim_get_driver_features(struct vdpa_device * vdpa)347 static u64 vdpasim_get_driver_features(struct vdpa_device *vdpa)
348 {
349 struct vdpasim *vdpasim = vdpa_to_sim(vdpa);
350
351 return vdpasim->features;
352 }
353
vdpasim_set_config_cb(struct vdpa_device * vdpa,struct vdpa_callback * cb)354 static void vdpasim_set_config_cb(struct vdpa_device *vdpa,
355 struct vdpa_callback *cb)
356 {
357 /* We don't support config interrupt */
358 }
359
vdpasim_get_vq_num_max(struct vdpa_device * vdpa)360 static u16 vdpasim_get_vq_num_max(struct vdpa_device *vdpa)
361 {
362 return VDPASIM_QUEUE_MAX;
363 }
364
vdpasim_get_device_id(struct vdpa_device * vdpa)365 static u32 vdpasim_get_device_id(struct vdpa_device *vdpa)
366 {
367 struct vdpasim *vdpasim = vdpa_to_sim(vdpa);
368
369 return vdpasim->dev_attr.id;
370 }
371
vdpasim_get_vendor_id(struct vdpa_device * vdpa)372 static u32 vdpasim_get_vendor_id(struct vdpa_device *vdpa)
373 {
374 return VDPASIM_VENDOR_ID;
375 }
376
vdpasim_get_status(struct vdpa_device * vdpa)377 static u8 vdpasim_get_status(struct vdpa_device *vdpa)
378 {
379 struct vdpasim *vdpasim = vdpa_to_sim(vdpa);
380 u8 status;
381
382 spin_lock(&vdpasim->lock);
383 status = vdpasim->status;
384 spin_unlock(&vdpasim->lock);
385
386 return status;
387 }
388
vdpasim_set_status(struct vdpa_device * vdpa,u8 status)389 static void vdpasim_set_status(struct vdpa_device *vdpa, u8 status)
390 {
391 struct vdpasim *vdpasim = vdpa_to_sim(vdpa);
392
393 spin_lock(&vdpasim->lock);
394 vdpasim->status = status;
395 spin_unlock(&vdpasim->lock);
396 }
397
vdpasim_reset(struct vdpa_device * vdpa)398 static int vdpasim_reset(struct vdpa_device *vdpa)
399 {
400 struct vdpasim *vdpasim = vdpa_to_sim(vdpa);
401
402 spin_lock(&vdpasim->lock);
403 vdpasim->status = 0;
404 vdpasim_do_reset(vdpasim);
405 spin_unlock(&vdpasim->lock);
406
407 return 0;
408 }
409
vdpasim_suspend(struct vdpa_device * vdpa)410 static int vdpasim_suspend(struct vdpa_device *vdpa)
411 {
412 struct vdpasim *vdpasim = vdpa_to_sim(vdpa);
413
414 spin_lock(&vdpasim->lock);
415 vdpasim->running = false;
416 spin_unlock(&vdpasim->lock);
417
418 return 0;
419 }
420
vdpasim_resume(struct vdpa_device * vdpa)421 static int vdpasim_resume(struct vdpa_device *vdpa)
422 {
423 struct vdpasim *vdpasim = vdpa_to_sim(vdpa);
424 int i;
425
426 spin_lock(&vdpasim->lock);
427 vdpasim->running = true;
428
429 if (vdpasim->pending_kick) {
430 /* Process pending descriptors */
431 for (i = 0; i < vdpasim->dev_attr.nvqs; ++i)
432 vdpasim_kick_vq(vdpa, i);
433
434 vdpasim->pending_kick = false;
435 }
436
437 spin_unlock(&vdpasim->lock);
438
439 return 0;
440 }
441
vdpasim_get_config_size(struct vdpa_device * vdpa)442 static size_t vdpasim_get_config_size(struct vdpa_device *vdpa)
443 {
444 struct vdpasim *vdpasim = vdpa_to_sim(vdpa);
445
446 return vdpasim->dev_attr.config_size;
447 }
448
vdpasim_get_config(struct vdpa_device * vdpa,unsigned int offset,void * buf,unsigned int len)449 static void vdpasim_get_config(struct vdpa_device *vdpa, unsigned int offset,
450 void *buf, unsigned int len)
451 {
452 struct vdpasim *vdpasim = vdpa_to_sim(vdpa);
453
454 if (offset + len > vdpasim->dev_attr.config_size)
455 return;
456
457 if (vdpasim->dev_attr.get_config)
458 vdpasim->dev_attr.get_config(vdpasim, vdpasim->config);
459
460 memcpy(buf, vdpasim->config + offset, len);
461 }
462
vdpasim_set_config(struct vdpa_device * vdpa,unsigned int offset,const void * buf,unsigned int len)463 static void vdpasim_set_config(struct vdpa_device *vdpa, unsigned int offset,
464 const void *buf, unsigned int len)
465 {
466 struct vdpasim *vdpasim = vdpa_to_sim(vdpa);
467
468 if (offset + len > vdpasim->dev_attr.config_size)
469 return;
470
471 memcpy(vdpasim->config + offset, buf, len);
472
473 if (vdpasim->dev_attr.set_config)
474 vdpasim->dev_attr.set_config(vdpasim, vdpasim->config);
475 }
476
vdpasim_get_generation(struct vdpa_device * vdpa)477 static u32 vdpasim_get_generation(struct vdpa_device *vdpa)
478 {
479 struct vdpasim *vdpasim = vdpa_to_sim(vdpa);
480
481 return vdpasim->generation;
482 }
483
vdpasim_get_iova_range(struct vdpa_device * vdpa)484 static struct vdpa_iova_range vdpasim_get_iova_range(struct vdpa_device *vdpa)
485 {
486 struct vdpa_iova_range range = {
487 .first = 0ULL,
488 .last = ULLONG_MAX,
489 };
490
491 return range;
492 }
493
vdpasim_set_group_asid(struct vdpa_device * vdpa,unsigned int group,unsigned int asid)494 static int vdpasim_set_group_asid(struct vdpa_device *vdpa, unsigned int group,
495 unsigned int asid)
496 {
497 struct vdpasim *vdpasim = vdpa_to_sim(vdpa);
498 struct vhost_iotlb *iommu;
499 int i;
500
501 if (group > vdpasim->dev_attr.ngroups)
502 return -EINVAL;
503
504 if (asid >= vdpasim->dev_attr.nas)
505 return -EINVAL;
506
507 iommu = &vdpasim->iommu[asid];
508
509 spin_lock(&vdpasim->lock);
510
511 for (i = 0; i < vdpasim->dev_attr.nvqs; i++)
512 if (vdpasim_get_vq_group(vdpa, i) == group)
513 vringh_set_iotlb(&vdpasim->vqs[i].vring, iommu,
514 &vdpasim->iommu_lock);
515
516 spin_unlock(&vdpasim->lock);
517
518 return 0;
519 }
520
vdpasim_set_map(struct vdpa_device * vdpa,unsigned int asid,struct vhost_iotlb * iotlb)521 static int vdpasim_set_map(struct vdpa_device *vdpa, unsigned int asid,
522 struct vhost_iotlb *iotlb)
523 {
524 struct vdpasim *vdpasim = vdpa_to_sim(vdpa);
525 struct vhost_iotlb_map *map;
526 struct vhost_iotlb *iommu;
527 u64 start = 0ULL, last = 0ULL - 1;
528 int ret;
529
530 if (asid >= vdpasim->dev_attr.nas)
531 return -EINVAL;
532
533 spin_lock(&vdpasim->iommu_lock);
534
535 iommu = &vdpasim->iommu[asid];
536 vhost_iotlb_reset(iommu);
537 vdpasim->iommu_pt[asid] = false;
538
539 for (map = vhost_iotlb_itree_first(iotlb, start, last); map;
540 map = vhost_iotlb_itree_next(map, start, last)) {
541 ret = vhost_iotlb_add_range(iommu, map->start,
542 map->last, map->addr, map->perm);
543 if (ret)
544 goto err;
545 }
546 spin_unlock(&vdpasim->iommu_lock);
547 return 0;
548
549 err:
550 vhost_iotlb_reset(iommu);
551 spin_unlock(&vdpasim->iommu_lock);
552 return ret;
553 }
554
vdpasim_dma_map(struct vdpa_device * vdpa,unsigned int asid,u64 iova,u64 size,u64 pa,u32 perm,void * opaque)555 static int vdpasim_dma_map(struct vdpa_device *vdpa, unsigned int asid,
556 u64 iova, u64 size,
557 u64 pa, u32 perm, void *opaque)
558 {
559 struct vdpasim *vdpasim = vdpa_to_sim(vdpa);
560 int ret;
561
562 if (asid >= vdpasim->dev_attr.nas)
563 return -EINVAL;
564
565 spin_lock(&vdpasim->iommu_lock);
566 if (vdpasim->iommu_pt[asid]) {
567 vhost_iotlb_reset(&vdpasim->iommu[asid]);
568 vdpasim->iommu_pt[asid] = false;
569 }
570 ret = vhost_iotlb_add_range_ctx(&vdpasim->iommu[asid], iova,
571 iova + size - 1, pa, perm, opaque);
572 spin_unlock(&vdpasim->iommu_lock);
573
574 return ret;
575 }
576
vdpasim_dma_unmap(struct vdpa_device * vdpa,unsigned int asid,u64 iova,u64 size)577 static int vdpasim_dma_unmap(struct vdpa_device *vdpa, unsigned int asid,
578 u64 iova, u64 size)
579 {
580 struct vdpasim *vdpasim = vdpa_to_sim(vdpa);
581
582 if (asid >= vdpasim->dev_attr.nas)
583 return -EINVAL;
584
585 if (vdpasim->iommu_pt[asid]) {
586 vhost_iotlb_reset(&vdpasim->iommu[asid]);
587 vdpasim->iommu_pt[asid] = false;
588 }
589
590 spin_lock(&vdpasim->iommu_lock);
591 vhost_iotlb_del_range(&vdpasim->iommu[asid], iova, iova + size - 1);
592 spin_unlock(&vdpasim->iommu_lock);
593
594 return 0;
595 }
596
vdpasim_free(struct vdpa_device * vdpa)597 static void vdpasim_free(struct vdpa_device *vdpa)
598 {
599 struct vdpasim *vdpasim = vdpa_to_sim(vdpa);
600 int i;
601
602 cancel_work_sync(&vdpasim->work);
603
604 for (i = 0; i < vdpasim->dev_attr.nvqs; i++) {
605 vringh_kiov_cleanup(&vdpasim->vqs[i].out_iov);
606 vringh_kiov_cleanup(&vdpasim->vqs[i].in_iov);
607 }
608
609 kvfree(vdpasim->buffer);
610 for (i = 0; i < vdpasim->dev_attr.nas; i++)
611 vhost_iotlb_reset(&vdpasim->iommu[i]);
612 kfree(vdpasim->iommu);
613 kfree(vdpasim->iommu_pt);
614 kfree(vdpasim->vqs);
615 kfree(vdpasim->config);
616 }
617
618 static const struct vdpa_config_ops vdpasim_config_ops = {
619 .set_vq_address = vdpasim_set_vq_address,
620 .set_vq_num = vdpasim_set_vq_num,
621 .kick_vq = vdpasim_kick_vq,
622 .set_vq_cb = vdpasim_set_vq_cb,
623 .set_vq_ready = vdpasim_set_vq_ready,
624 .get_vq_ready = vdpasim_get_vq_ready,
625 .set_vq_state = vdpasim_set_vq_state,
626 .get_vendor_vq_stats = vdpasim_get_vq_stats,
627 .get_vq_state = vdpasim_get_vq_state,
628 .get_vq_align = vdpasim_get_vq_align,
629 .get_vq_group = vdpasim_get_vq_group,
630 .get_device_features = vdpasim_get_device_features,
631 .set_driver_features = vdpasim_set_driver_features,
632 .get_driver_features = vdpasim_get_driver_features,
633 .set_config_cb = vdpasim_set_config_cb,
634 .get_vq_num_max = vdpasim_get_vq_num_max,
635 .get_device_id = vdpasim_get_device_id,
636 .get_vendor_id = vdpasim_get_vendor_id,
637 .get_status = vdpasim_get_status,
638 .set_status = vdpasim_set_status,
639 .reset = vdpasim_reset,
640 .suspend = vdpasim_suspend,
641 .resume = vdpasim_resume,
642 .get_config_size = vdpasim_get_config_size,
643 .get_config = vdpasim_get_config,
644 .set_config = vdpasim_set_config,
645 .get_generation = vdpasim_get_generation,
646 .get_iova_range = vdpasim_get_iova_range,
647 .set_group_asid = vdpasim_set_group_asid,
648 .dma_map = vdpasim_dma_map,
649 .dma_unmap = vdpasim_dma_unmap,
650 .free = vdpasim_free,
651 };
652
653 static const struct vdpa_config_ops vdpasim_batch_config_ops = {
654 .set_vq_address = vdpasim_set_vq_address,
655 .set_vq_num = vdpasim_set_vq_num,
656 .kick_vq = vdpasim_kick_vq,
657 .set_vq_cb = vdpasim_set_vq_cb,
658 .set_vq_ready = vdpasim_set_vq_ready,
659 .get_vq_ready = vdpasim_get_vq_ready,
660 .set_vq_state = vdpasim_set_vq_state,
661 .get_vendor_vq_stats = vdpasim_get_vq_stats,
662 .get_vq_state = vdpasim_get_vq_state,
663 .get_vq_align = vdpasim_get_vq_align,
664 .get_vq_group = vdpasim_get_vq_group,
665 .get_device_features = vdpasim_get_device_features,
666 .set_driver_features = vdpasim_set_driver_features,
667 .get_driver_features = vdpasim_get_driver_features,
668 .set_config_cb = vdpasim_set_config_cb,
669 .get_vq_num_max = vdpasim_get_vq_num_max,
670 .get_device_id = vdpasim_get_device_id,
671 .get_vendor_id = vdpasim_get_vendor_id,
672 .get_status = vdpasim_get_status,
673 .set_status = vdpasim_set_status,
674 .reset = vdpasim_reset,
675 .suspend = vdpasim_suspend,
676 .resume = vdpasim_resume,
677 .get_config_size = vdpasim_get_config_size,
678 .get_config = vdpasim_get_config,
679 .set_config = vdpasim_set_config,
680 .get_generation = vdpasim_get_generation,
681 .get_iova_range = vdpasim_get_iova_range,
682 .set_group_asid = vdpasim_set_group_asid,
683 .set_map = vdpasim_set_map,
684 .free = vdpasim_free,
685 };
686
687 MODULE_VERSION(DRV_VERSION);
688 MODULE_LICENSE(DRV_LICENSE);
689 MODULE_AUTHOR(DRV_AUTHOR);
690 MODULE_DESCRIPTION(DRV_DESC);
691