]> Git Repo - qemu.git/blob - hw/vhost.c
usb-redir: Move to core packet id and queue handling
[qemu.git] / hw / vhost.c
1 /*
2  * vhost support
3  *
4  * Copyright Red Hat, Inc. 2010
5  *
6  * Authors:
7  *  Michael S. Tsirkin <[email protected]>
8  *
9  * This work is licensed under the terms of the GNU GPL, version 2.  See
10  * the COPYING file in the top-level directory.
11  *
12  * Contributions after 2012-01-13 are licensed under the terms of the
13  * GNU GPL, version 2 or (at your option) any later version.
14  */
15
16 #include <sys/ioctl.h>
17 #include "vhost.h"
18 #include "hw/hw.h"
19 #include "range.h"
20 #include <linux/vhost.h>
21 #include "exec-memory.h"
22
23 static void vhost_dev_sync_region(struct vhost_dev *dev,
24                                   MemoryRegionSection *section,
25                                   uint64_t mfirst, uint64_t mlast,
26                                   uint64_t rfirst, uint64_t rlast)
27 {
28     uint64_t start = MAX(mfirst, rfirst);
29     uint64_t end = MIN(mlast, rlast);
30     vhost_log_chunk_t *from = dev->log + start / VHOST_LOG_CHUNK;
31     vhost_log_chunk_t *to = dev->log + end / VHOST_LOG_CHUNK + 1;
32     uint64_t addr = (start / VHOST_LOG_CHUNK) * VHOST_LOG_CHUNK;
33
34     if (end < start) {
35         return;
36     }
37     assert(end / VHOST_LOG_CHUNK < dev->log_size);
38     assert(start / VHOST_LOG_CHUNK < dev->log_size);
39
40     for (;from < to; ++from) {
41         vhost_log_chunk_t log;
42         int bit;
43         /* We first check with non-atomic: much cheaper,
44          * and we expect non-dirty to be the common case. */
45         if (!*from) {
46             addr += VHOST_LOG_CHUNK;
47             continue;
48         }
49         /* Data must be read atomically. We don't really
50          * need the barrier semantics of __sync
51          * builtins, but it's easier to use them than
52          * roll our own. */
53         log = __sync_fetch_and_and(from, 0);
54         while ((bit = sizeof(log) > sizeof(int) ?
55                 ffsll(log) : ffs(log))) {
56             ram_addr_t ram_addr;
57             bit -= 1;
58             ram_addr = section->offset_within_region + bit * VHOST_LOG_PAGE;
59             memory_region_set_dirty(section->mr, ram_addr, VHOST_LOG_PAGE);
60             log &= ~(0x1ull << bit);
61         }
62         addr += VHOST_LOG_CHUNK;
63     }
64 }
65
66 static int vhost_sync_dirty_bitmap(struct vhost_dev *dev,
67                                    MemoryRegionSection *section,
68                                    target_phys_addr_t start_addr,
69                                    target_phys_addr_t end_addr)
70 {
71     int i;
72
73     if (!dev->log_enabled || !dev->started) {
74         return 0;
75     }
76     for (i = 0; i < dev->mem->nregions; ++i) {
77         struct vhost_memory_region *reg = dev->mem->regions + i;
78         vhost_dev_sync_region(dev, section, start_addr, end_addr,
79                               reg->guest_phys_addr,
80                               range_get_last(reg->guest_phys_addr,
81                                              reg->memory_size));
82     }
83     for (i = 0; i < dev->nvqs; ++i) {
84         struct vhost_virtqueue *vq = dev->vqs + i;
85         vhost_dev_sync_region(dev, section, start_addr, end_addr, vq->used_phys,
86                               range_get_last(vq->used_phys, vq->used_size));
87     }
88     return 0;
89 }
90
91 static void vhost_log_sync(MemoryListener *listener,
92                           MemoryRegionSection *section)
93 {
94     struct vhost_dev *dev = container_of(listener, struct vhost_dev,
95                                          memory_listener);
96     target_phys_addr_t start_addr = section->offset_within_address_space;
97     target_phys_addr_t end_addr = start_addr + section->size;
98
99     vhost_sync_dirty_bitmap(dev, section, start_addr, end_addr);
100 }
101
102 /* Assign/unassign. Keep an unsorted array of non-overlapping
103  * memory regions in dev->mem. */
104 static void vhost_dev_unassign_memory(struct vhost_dev *dev,
105                                       uint64_t start_addr,
106                                       uint64_t size)
107 {
108     int from, to, n = dev->mem->nregions;
109     /* Track overlapping/split regions for sanity checking. */
110     int overlap_start = 0, overlap_end = 0, overlap_middle = 0, split = 0;
111
112     for (from = 0, to = 0; from < n; ++from, ++to) {
113         struct vhost_memory_region *reg = dev->mem->regions + to;
114         uint64_t reglast;
115         uint64_t memlast;
116         uint64_t change;
117
118         /* clone old region */
119         if (to != from) {
120             memcpy(reg, dev->mem->regions + from, sizeof *reg);
121         }
122
123         /* No overlap is simple */
124         if (!ranges_overlap(reg->guest_phys_addr, reg->memory_size,
125                             start_addr, size)) {
126             continue;
127         }
128
129         /* Split only happens if supplied region
130          * is in the middle of an existing one. Thus it can not
131          * overlap with any other existing region. */
132         assert(!split);
133
134         reglast = range_get_last(reg->guest_phys_addr, reg->memory_size);
135         memlast = range_get_last(start_addr, size);
136
137         /* Remove whole region */
138         if (start_addr <= reg->guest_phys_addr && memlast >= reglast) {
139             --dev->mem->nregions;
140             --to;
141             ++overlap_middle;
142             continue;
143         }
144
145         /* Shrink region */
146         if (memlast >= reglast) {
147             reg->memory_size = start_addr - reg->guest_phys_addr;
148             assert(reg->memory_size);
149             assert(!overlap_end);
150             ++overlap_end;
151             continue;
152         }
153
154         /* Shift region */
155         if (start_addr <= reg->guest_phys_addr) {
156             change = memlast + 1 - reg->guest_phys_addr;
157             reg->memory_size -= change;
158             reg->guest_phys_addr += change;
159             reg->userspace_addr += change;
160             assert(reg->memory_size);
161             assert(!overlap_start);
162             ++overlap_start;
163             continue;
164         }
165
166         /* This only happens if supplied region
167          * is in the middle of an existing one. Thus it can not
168          * overlap with any other existing region. */
169         assert(!overlap_start);
170         assert(!overlap_end);
171         assert(!overlap_middle);
172         /* Split region: shrink first part, shift second part. */
173         memcpy(dev->mem->regions + n, reg, sizeof *reg);
174         reg->memory_size = start_addr - reg->guest_phys_addr;
175         assert(reg->memory_size);
176         change = memlast + 1 - reg->guest_phys_addr;
177         reg = dev->mem->regions + n;
178         reg->memory_size -= change;
179         assert(reg->memory_size);
180         reg->guest_phys_addr += change;
181         reg->userspace_addr += change;
182         /* Never add more than 1 region */
183         assert(dev->mem->nregions == n);
184         ++dev->mem->nregions;
185         ++split;
186     }
187 }
188
189 /* Called after unassign, so no regions overlap the given range. */
190 static void vhost_dev_assign_memory(struct vhost_dev *dev,
191                                     uint64_t start_addr,
192                                     uint64_t size,
193                                     uint64_t uaddr)
194 {
195     int from, to;
196     struct vhost_memory_region *merged = NULL;
197     for (from = 0, to = 0; from < dev->mem->nregions; ++from, ++to) {
198         struct vhost_memory_region *reg = dev->mem->regions + to;
199         uint64_t prlast, urlast;
200         uint64_t pmlast, umlast;
201         uint64_t s, e, u;
202
203         /* clone old region */
204         if (to != from) {
205             memcpy(reg, dev->mem->regions + from, sizeof *reg);
206         }
207         prlast = range_get_last(reg->guest_phys_addr, reg->memory_size);
208         pmlast = range_get_last(start_addr, size);
209         urlast = range_get_last(reg->userspace_addr, reg->memory_size);
210         umlast = range_get_last(uaddr, size);
211
212         /* check for overlapping regions: should never happen. */
213         assert(prlast < start_addr || pmlast < reg->guest_phys_addr);
214         /* Not an adjacent or overlapping region - do not merge. */
215         if ((prlast + 1 != start_addr || urlast + 1 != uaddr) &&
216             (pmlast + 1 != reg->guest_phys_addr ||
217              umlast + 1 != reg->userspace_addr)) {
218             continue;
219         }
220
221         if (merged) {
222             --to;
223             assert(to >= 0);
224         } else {
225             merged = reg;
226         }
227         u = MIN(uaddr, reg->userspace_addr);
228         s = MIN(start_addr, reg->guest_phys_addr);
229         e = MAX(pmlast, prlast);
230         uaddr = merged->userspace_addr = u;
231         start_addr = merged->guest_phys_addr = s;
232         size = merged->memory_size = e - s + 1;
233         assert(merged->memory_size);
234     }
235
236     if (!merged) {
237         struct vhost_memory_region *reg = dev->mem->regions + to;
238         memset(reg, 0, sizeof *reg);
239         reg->memory_size = size;
240         assert(reg->memory_size);
241         reg->guest_phys_addr = start_addr;
242         reg->userspace_addr = uaddr;
243         ++to;
244     }
245     assert(to <= dev->mem->nregions + 1);
246     dev->mem->nregions = to;
247 }
248
249 static uint64_t vhost_get_log_size(struct vhost_dev *dev)
250 {
251     uint64_t log_size = 0;
252     int i;
253     for (i = 0; i < dev->mem->nregions; ++i) {
254         struct vhost_memory_region *reg = dev->mem->regions + i;
255         uint64_t last = range_get_last(reg->guest_phys_addr,
256                                        reg->memory_size);
257         log_size = MAX(log_size, last / VHOST_LOG_CHUNK + 1);
258     }
259     for (i = 0; i < dev->nvqs; ++i) {
260         struct vhost_virtqueue *vq = dev->vqs + i;
261         uint64_t last = vq->used_phys + vq->used_size - 1;
262         log_size = MAX(log_size, last / VHOST_LOG_CHUNK + 1);
263     }
264     return log_size;
265 }
266
267 static inline void vhost_dev_log_resize(struct vhost_dev* dev, uint64_t size)
268 {
269     vhost_log_chunk_t *log;
270     uint64_t log_base;
271     int r, i;
272     if (size) {
273         log = g_malloc0(size * sizeof *log);
274     } else {
275         log = NULL;
276     }
277     log_base = (uint64_t)(unsigned long)log;
278     r = ioctl(dev->control, VHOST_SET_LOG_BASE, &log_base);
279     assert(r >= 0);
280     for (i = 0; i < dev->n_mem_sections; ++i) {
281         /* Sync only the range covered by the old log */
282         vhost_sync_dirty_bitmap(dev, &dev->mem_sections[i], 0,
283                                 dev->log_size * VHOST_LOG_CHUNK - 1);
284     }
285     if (dev->log) {
286         g_free(dev->log);
287     }
288     dev->log = log;
289     dev->log_size = size;
290 }
291
292 static int vhost_verify_ring_mappings(struct vhost_dev *dev,
293                                       uint64_t start_addr,
294                                       uint64_t size)
295 {
296     int i;
297     for (i = 0; i < dev->nvqs; ++i) {
298         struct vhost_virtqueue *vq = dev->vqs + i;
299         target_phys_addr_t l;
300         void *p;
301
302         if (!ranges_overlap(start_addr, size, vq->ring_phys, vq->ring_size)) {
303             continue;
304         }
305         l = vq->ring_size;
306         p = cpu_physical_memory_map(vq->ring_phys, &l, 1);
307         if (!p || l != vq->ring_size) {
308             fprintf(stderr, "Unable to map ring buffer for ring %d\n", i);
309             return -ENOMEM;
310         }
311         if (p != vq->ring) {
312             fprintf(stderr, "Ring buffer relocated for ring %d\n", i);
313             return -EBUSY;
314         }
315         cpu_physical_memory_unmap(p, l, 0, 0);
316     }
317     return 0;
318 }
319
320 static struct vhost_memory_region *vhost_dev_find_reg(struct vhost_dev *dev,
321                                                       uint64_t start_addr,
322                                                       uint64_t size)
323 {
324     int i, n = dev->mem->nregions;
325     for (i = 0; i < n; ++i) {
326         struct vhost_memory_region *reg = dev->mem->regions + i;
327         if (ranges_overlap(reg->guest_phys_addr, reg->memory_size,
328                            start_addr, size)) {
329             return reg;
330         }
331     }
332     return NULL;
333 }
334
335 static bool vhost_dev_cmp_memory(struct vhost_dev *dev,
336                                  uint64_t start_addr,
337                                  uint64_t size,
338                                  uint64_t uaddr)
339 {
340     struct vhost_memory_region *reg = vhost_dev_find_reg(dev, start_addr, size);
341     uint64_t reglast;
342     uint64_t memlast;
343
344     if (!reg) {
345         return true;
346     }
347
348     reglast = range_get_last(reg->guest_phys_addr, reg->memory_size);
349     memlast = range_get_last(start_addr, size);
350
351     /* Need to extend region? */
352     if (start_addr < reg->guest_phys_addr || memlast > reglast) {
353         return true;
354     }
355     /* userspace_addr changed? */
356     return uaddr != reg->userspace_addr + start_addr - reg->guest_phys_addr;
357 }
358
359 static void vhost_set_memory(MemoryListener *listener,
360                              MemoryRegionSection *section,
361                              bool add)
362 {
363     struct vhost_dev *dev = container_of(listener, struct vhost_dev,
364                                          memory_listener);
365     target_phys_addr_t start_addr = section->offset_within_address_space;
366     ram_addr_t size = section->size;
367     bool log_dirty = memory_region_is_logging(section->mr);
368     int s = offsetof(struct vhost_memory, regions) +
369         (dev->mem->nregions + 1) * sizeof dev->mem->regions[0];
370     uint64_t log_size;
371     int r;
372     void *ram;
373
374     dev->mem = g_realloc(dev->mem, s);
375
376     if (log_dirty) {
377         add = false;
378     }
379
380     assert(size);
381
382     /* Optimize no-change case. At least cirrus_vga does this a lot at this time. */
383     ram = memory_region_get_ram_ptr(section->mr) + section->offset_within_region;
384     if (add) {
385         if (!vhost_dev_cmp_memory(dev, start_addr, size, (uintptr_t)ram)) {
386             /* Region exists with same address. Nothing to do. */
387             return;
388         }
389     } else {
390         if (!vhost_dev_find_reg(dev, start_addr, size)) {
391             /* Removing region that we don't access. Nothing to do. */
392             return;
393         }
394     }
395
396     vhost_dev_unassign_memory(dev, start_addr, size);
397     if (add) {
398         /* Add given mapping, merging adjacent regions if any */
399         vhost_dev_assign_memory(dev, start_addr, size, (uintptr_t)ram);
400     } else {
401         /* Remove old mapping for this memory, if any. */
402         vhost_dev_unassign_memory(dev, start_addr, size);
403     }
404
405     if (!dev->started) {
406         return;
407     }
408
409     if (dev->started) {
410         r = vhost_verify_ring_mappings(dev, start_addr, size);
411         assert(r >= 0);
412     }
413
414     if (!dev->log_enabled) {
415         r = ioctl(dev->control, VHOST_SET_MEM_TABLE, dev->mem);
416         assert(r >= 0);
417         return;
418     }
419     log_size = vhost_get_log_size(dev);
420     /* We allocate an extra 4K bytes to log,
421      * to reduce the * number of reallocations. */
422 #define VHOST_LOG_BUFFER (0x1000 / sizeof *dev->log)
423     /* To log more, must increase log size before table update. */
424     if (dev->log_size < log_size) {
425         vhost_dev_log_resize(dev, log_size + VHOST_LOG_BUFFER);
426     }
427     r = ioctl(dev->control, VHOST_SET_MEM_TABLE, dev->mem);
428     assert(r >= 0);
429     /* To log less, can only decrease log size after table update. */
430     if (dev->log_size > log_size + VHOST_LOG_BUFFER) {
431         vhost_dev_log_resize(dev, log_size);
432     }
433 }
434
435 static bool vhost_section(MemoryRegionSection *section)
436 {
437     return section->address_space == get_system_memory()
438         && memory_region_is_ram(section->mr);
439 }
440
441 static void vhost_begin(MemoryListener *listener)
442 {
443 }
444
445 static void vhost_commit(MemoryListener *listener)
446 {
447 }
448
449 static void vhost_region_add(MemoryListener *listener,
450                              MemoryRegionSection *section)
451 {
452     struct vhost_dev *dev = container_of(listener, struct vhost_dev,
453                                          memory_listener);
454
455     if (!vhost_section(section)) {
456         return;
457     }
458
459     ++dev->n_mem_sections;
460     dev->mem_sections = g_renew(MemoryRegionSection, dev->mem_sections,
461                                 dev->n_mem_sections);
462     dev->mem_sections[dev->n_mem_sections - 1] = *section;
463     vhost_set_memory(listener, section, true);
464 }
465
466 static void vhost_region_del(MemoryListener *listener,
467                              MemoryRegionSection *section)
468 {
469     struct vhost_dev *dev = container_of(listener, struct vhost_dev,
470                                          memory_listener);
471     int i;
472
473     if (!vhost_section(section)) {
474         return;
475     }
476
477     vhost_set_memory(listener, section, false);
478     for (i = 0; i < dev->n_mem_sections; ++i) {
479         if (dev->mem_sections[i].offset_within_address_space
480             == section->offset_within_address_space) {
481             --dev->n_mem_sections;
482             memmove(&dev->mem_sections[i], &dev->mem_sections[i+1],
483                     (dev->n_mem_sections - i) * sizeof(*dev->mem_sections));
484             break;
485         }
486     }
487 }
488
489 static void vhost_region_nop(MemoryListener *listener,
490                              MemoryRegionSection *section)
491 {
492 }
493
494 static int vhost_virtqueue_set_addr(struct vhost_dev *dev,
495                                     struct vhost_virtqueue *vq,
496                                     unsigned idx, bool enable_log)
497 {
498     struct vhost_vring_addr addr = {
499         .index = idx,
500         .desc_user_addr = (uint64_t)(unsigned long)vq->desc,
501         .avail_user_addr = (uint64_t)(unsigned long)vq->avail,
502         .used_user_addr = (uint64_t)(unsigned long)vq->used,
503         .log_guest_addr = vq->used_phys,
504         .flags = enable_log ? (1 << VHOST_VRING_F_LOG) : 0,
505     };
506     int r = ioctl(dev->control, VHOST_SET_VRING_ADDR, &addr);
507     if (r < 0) {
508         return -errno;
509     }
510     return 0;
511 }
512
513 static int vhost_dev_set_features(struct vhost_dev *dev, bool enable_log)
514 {
515     uint64_t features = dev->acked_features;
516     int r;
517     if (enable_log) {
518         features |= 0x1 << VHOST_F_LOG_ALL;
519     }
520     r = ioctl(dev->control, VHOST_SET_FEATURES, &features);
521     return r < 0 ? -errno : 0;
522 }
523
524 static int vhost_dev_set_log(struct vhost_dev *dev, bool enable_log)
525 {
526     int r, t, i;
527     r = vhost_dev_set_features(dev, enable_log);
528     if (r < 0) {
529         goto err_features;
530     }
531     for (i = 0; i < dev->nvqs; ++i) {
532         r = vhost_virtqueue_set_addr(dev, dev->vqs + i, i,
533                                      enable_log);
534         if (r < 0) {
535             goto err_vq;
536         }
537     }
538     return 0;
539 err_vq:
540     for (; i >= 0; --i) {
541         t = vhost_virtqueue_set_addr(dev, dev->vqs + i, i,
542                                      dev->log_enabled);
543         assert(t >= 0);
544     }
545     t = vhost_dev_set_features(dev, dev->log_enabled);
546     assert(t >= 0);
547 err_features:
548     return r;
549 }
550
551 static int vhost_migration_log(MemoryListener *listener, int enable)
552 {
553     struct vhost_dev *dev = container_of(listener, struct vhost_dev,
554                                          memory_listener);
555     int r;
556     if (!!enable == dev->log_enabled) {
557         return 0;
558     }
559     if (!dev->started) {
560         dev->log_enabled = enable;
561         return 0;
562     }
563     if (!enable) {
564         r = vhost_dev_set_log(dev, false);
565         if (r < 0) {
566             return r;
567         }
568         if (dev->log) {
569             g_free(dev->log);
570         }
571         dev->log = NULL;
572         dev->log_size = 0;
573     } else {
574         vhost_dev_log_resize(dev, vhost_get_log_size(dev));
575         r = vhost_dev_set_log(dev, true);
576         if (r < 0) {
577             return r;
578         }
579     }
580     dev->log_enabled = enable;
581     return 0;
582 }
583
584 static void vhost_log_global_start(MemoryListener *listener)
585 {
586     int r;
587
588     r = vhost_migration_log(listener, true);
589     if (r < 0) {
590         abort();
591     }
592 }
593
594 static void vhost_log_global_stop(MemoryListener *listener)
595 {
596     int r;
597
598     r = vhost_migration_log(listener, false);
599     if (r < 0) {
600         abort();
601     }
602 }
603
604 static void vhost_log_start(MemoryListener *listener,
605                             MemoryRegionSection *section)
606 {
607     /* FIXME: implement */
608 }
609
610 static void vhost_log_stop(MemoryListener *listener,
611                            MemoryRegionSection *section)
612 {
613     /* FIXME: implement */
614 }
615
616 static int vhost_virtqueue_init(struct vhost_dev *dev,
617                                 struct VirtIODevice *vdev,
618                                 struct vhost_virtqueue *vq,
619                                 unsigned idx)
620 {
621     target_phys_addr_t s, l, a;
622     int r;
623     struct vhost_vring_file file = {
624         .index = idx,
625     };
626     struct vhost_vring_state state = {
627         .index = idx,
628     };
629     struct VirtQueue *vvq = virtio_get_queue(vdev, idx);
630
631     vq->num = state.num = virtio_queue_get_num(vdev, idx);
632     r = ioctl(dev->control, VHOST_SET_VRING_NUM, &state);
633     if (r) {
634         return -errno;
635     }
636
637     state.num = virtio_queue_get_last_avail_idx(vdev, idx);
638     r = ioctl(dev->control, VHOST_SET_VRING_BASE, &state);
639     if (r) {
640         return -errno;
641     }
642
643     s = l = virtio_queue_get_desc_size(vdev, idx);
644     a = virtio_queue_get_desc_addr(vdev, idx);
645     vq->desc = cpu_physical_memory_map(a, &l, 0);
646     if (!vq->desc || l != s) {
647         r = -ENOMEM;
648         goto fail_alloc_desc;
649     }
650     s = l = virtio_queue_get_avail_size(vdev, idx);
651     a = virtio_queue_get_avail_addr(vdev, idx);
652     vq->avail = cpu_physical_memory_map(a, &l, 0);
653     if (!vq->avail || l != s) {
654         r = -ENOMEM;
655         goto fail_alloc_avail;
656     }
657     vq->used_size = s = l = virtio_queue_get_used_size(vdev, idx);
658     vq->used_phys = a = virtio_queue_get_used_addr(vdev, idx);
659     vq->used = cpu_physical_memory_map(a, &l, 1);
660     if (!vq->used || l != s) {
661         r = -ENOMEM;
662         goto fail_alloc_used;
663     }
664
665     vq->ring_size = s = l = virtio_queue_get_ring_size(vdev, idx);
666     vq->ring_phys = a = virtio_queue_get_ring_addr(vdev, idx);
667     vq->ring = cpu_physical_memory_map(a, &l, 1);
668     if (!vq->ring || l != s) {
669         r = -ENOMEM;
670         goto fail_alloc_ring;
671     }
672
673     r = vhost_virtqueue_set_addr(dev, vq, idx, dev->log_enabled);
674     if (r < 0) {
675         r = -errno;
676         goto fail_alloc;
677     }
678     file.fd = event_notifier_get_fd(virtio_queue_get_host_notifier(vvq));
679     r = ioctl(dev->control, VHOST_SET_VRING_KICK, &file);
680     if (r) {
681         r = -errno;
682         goto fail_kick;
683     }
684
685     file.fd = event_notifier_get_fd(virtio_queue_get_guest_notifier(vvq));
686     r = ioctl(dev->control, VHOST_SET_VRING_CALL, &file);
687     if (r) {
688         r = -errno;
689         goto fail_call;
690     }
691
692     return 0;
693
694 fail_call:
695 fail_kick:
696 fail_alloc:
697     cpu_physical_memory_unmap(vq->ring, virtio_queue_get_ring_size(vdev, idx),
698                               0, 0);
699 fail_alloc_ring:
700     cpu_physical_memory_unmap(vq->used, virtio_queue_get_used_size(vdev, idx),
701                               0, 0);
702 fail_alloc_used:
703     cpu_physical_memory_unmap(vq->avail, virtio_queue_get_avail_size(vdev, idx),
704                               0, 0);
705 fail_alloc_avail:
706     cpu_physical_memory_unmap(vq->desc, virtio_queue_get_desc_size(vdev, idx),
707                               0, 0);
708 fail_alloc_desc:
709     return r;
710 }
711
712 static void vhost_virtqueue_cleanup(struct vhost_dev *dev,
713                                     struct VirtIODevice *vdev,
714                                     struct vhost_virtqueue *vq,
715                                     unsigned idx)
716 {
717     struct vhost_vring_state state = {
718         .index = idx,
719     };
720     int r;
721     r = ioctl(dev->control, VHOST_GET_VRING_BASE, &state);
722     if (r < 0) {
723         fprintf(stderr, "vhost VQ %d ring restore failed: %d\n", idx, r);
724         fflush(stderr);
725     }
726     virtio_queue_set_last_avail_idx(vdev, idx, state.num);
727     assert (r >= 0);
728     cpu_physical_memory_unmap(vq->ring, virtio_queue_get_ring_size(vdev, idx),
729                               0, virtio_queue_get_ring_size(vdev, idx));
730     cpu_physical_memory_unmap(vq->used, virtio_queue_get_used_size(vdev, idx),
731                               1, virtio_queue_get_used_size(vdev, idx));
732     cpu_physical_memory_unmap(vq->avail, virtio_queue_get_avail_size(vdev, idx),
733                               0, virtio_queue_get_avail_size(vdev, idx));
734     cpu_physical_memory_unmap(vq->desc, virtio_queue_get_desc_size(vdev, idx),
735                               0, virtio_queue_get_desc_size(vdev, idx));
736 }
737
738 static void vhost_eventfd_add(MemoryListener *listener,
739                               MemoryRegionSection *section,
740                               bool match_data, uint64_t data, EventNotifier *e)
741 {
742 }
743
744 static void vhost_eventfd_del(MemoryListener *listener,
745                               MemoryRegionSection *section,
746                               bool match_data, uint64_t data, EventNotifier *e)
747 {
748 }
749
750 int vhost_dev_init(struct vhost_dev *hdev, int devfd, const char *devpath,
751                    bool force)
752 {
753     uint64_t features;
754     int r;
755     if (devfd >= 0) {
756         hdev->control = devfd;
757     } else {
758         hdev->control = open(devpath, O_RDWR);
759         if (hdev->control < 0) {
760             return -errno;
761         }
762     }
763     r = ioctl(hdev->control, VHOST_SET_OWNER, NULL);
764     if (r < 0) {
765         goto fail;
766     }
767
768     r = ioctl(hdev->control, VHOST_GET_FEATURES, &features);
769     if (r < 0) {
770         goto fail;
771     }
772     hdev->features = features;
773
774     hdev->memory_listener = (MemoryListener) {
775         .begin = vhost_begin,
776         .commit = vhost_commit,
777         .region_add = vhost_region_add,
778         .region_del = vhost_region_del,
779         .region_nop = vhost_region_nop,
780         .log_start = vhost_log_start,
781         .log_stop = vhost_log_stop,
782         .log_sync = vhost_log_sync,
783         .log_global_start = vhost_log_global_start,
784         .log_global_stop = vhost_log_global_stop,
785         .eventfd_add = vhost_eventfd_add,
786         .eventfd_del = vhost_eventfd_del,
787         .priority = 10
788     };
789     hdev->mem = g_malloc0(offsetof(struct vhost_memory, regions));
790     hdev->n_mem_sections = 0;
791     hdev->mem_sections = NULL;
792     hdev->log = NULL;
793     hdev->log_size = 0;
794     hdev->log_enabled = false;
795     hdev->started = false;
796     memory_listener_register(&hdev->memory_listener, NULL);
797     hdev->force = force;
798     return 0;
799 fail:
800     r = -errno;
801     close(hdev->control);
802     return r;
803 }
804
805 void vhost_dev_cleanup(struct vhost_dev *hdev)
806 {
807     memory_listener_unregister(&hdev->memory_listener);
808     g_free(hdev->mem);
809     g_free(hdev->mem_sections);
810     close(hdev->control);
811 }
812
813 bool vhost_dev_query(struct vhost_dev *hdev, VirtIODevice *vdev)
814 {
815     return !vdev->binding->query_guest_notifiers ||
816         vdev->binding->query_guest_notifiers(vdev->binding_opaque) ||
817         hdev->force;
818 }
819
820 /* Stop processing guest IO notifications in qemu.
821  * Start processing them in vhost in kernel.
822  */
823 int vhost_dev_enable_notifiers(struct vhost_dev *hdev, VirtIODevice *vdev)
824 {
825     int i, r;
826     if (!vdev->binding->set_host_notifier) {
827         fprintf(stderr, "binding does not support host notifiers\n");
828         r = -ENOSYS;
829         goto fail;
830     }
831
832     for (i = 0; i < hdev->nvqs; ++i) {
833         r = vdev->binding->set_host_notifier(vdev->binding_opaque, i, true);
834         if (r < 0) {
835             fprintf(stderr, "vhost VQ %d notifier binding failed: %d\n", i, -r);
836             goto fail_vq;
837         }
838     }
839
840     return 0;
841 fail_vq:
842     while (--i >= 0) {
843         r = vdev->binding->set_host_notifier(vdev->binding_opaque, i, false);
844         if (r < 0) {
845             fprintf(stderr, "vhost VQ %d notifier cleanup error: %d\n", i, -r);
846             fflush(stderr);
847         }
848         assert (r >= 0);
849     }
850 fail:
851     return r;
852 }
853
854 /* Stop processing guest IO notifications in vhost.
855  * Start processing them in qemu.
856  * This might actually run the qemu handlers right away,
857  * so virtio in qemu must be completely setup when this is called.
858  */
859 void vhost_dev_disable_notifiers(struct vhost_dev *hdev, VirtIODevice *vdev)
860 {
861     int i, r;
862
863     for (i = 0; i < hdev->nvqs; ++i) {
864         r = vdev->binding->set_host_notifier(vdev->binding_opaque, i, false);
865         if (r < 0) {
866             fprintf(stderr, "vhost VQ %d notifier cleanup failed: %d\n", i, -r);
867             fflush(stderr);
868         }
869         assert (r >= 0);
870     }
871 }
872
873 /* Host notifiers must be enabled at this point. */
874 int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev)
875 {
876     int i, r;
877     if (!vdev->binding->set_guest_notifiers) {
878         fprintf(stderr, "binding does not support guest notifiers\n");
879         r = -ENOSYS;
880         goto fail;
881     }
882
883     r = vdev->binding->set_guest_notifiers(vdev->binding_opaque, true);
884     if (r < 0) {
885         fprintf(stderr, "Error binding guest notifier: %d\n", -r);
886         goto fail_notifiers;
887     }
888
889     r = vhost_dev_set_features(hdev, hdev->log_enabled);
890     if (r < 0) {
891         goto fail_features;
892     }
893     r = ioctl(hdev->control, VHOST_SET_MEM_TABLE, hdev->mem);
894     if (r < 0) {
895         r = -errno;
896         goto fail_mem;
897     }
898     for (i = 0; i < hdev->nvqs; ++i) {
899         r = vhost_virtqueue_init(hdev,
900                                  vdev,
901                                  hdev->vqs + i,
902                                  i);
903         if (r < 0) {
904             goto fail_vq;
905         }
906     }
907
908     if (hdev->log_enabled) {
909         hdev->log_size = vhost_get_log_size(hdev);
910         hdev->log = hdev->log_size ?
911             g_malloc0(hdev->log_size * sizeof *hdev->log) : NULL;
912         r = ioctl(hdev->control, VHOST_SET_LOG_BASE,
913                   (uint64_t)(unsigned long)hdev->log);
914         if (r < 0) {
915             r = -errno;
916             goto fail_log;
917         }
918     }
919
920     hdev->started = true;
921
922     return 0;
923 fail_log:
924 fail_vq:
925     while (--i >= 0) {
926         vhost_virtqueue_cleanup(hdev,
927                                 vdev,
928                                 hdev->vqs + i,
929                                 i);
930     }
931 fail_mem:
932 fail_features:
933     vdev->binding->set_guest_notifiers(vdev->binding_opaque, false);
934 fail_notifiers:
935 fail:
936     return r;
937 }
938
939 /* Host notifiers must be enabled at this point. */
940 void vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev)
941 {
942     int i, r;
943
944     for (i = 0; i < hdev->nvqs; ++i) {
945         vhost_virtqueue_cleanup(hdev,
946                                 vdev,
947                                 hdev->vqs + i,
948                                 i);
949     }
950     for (i = 0; i < hdev->n_mem_sections; ++i) {
951         vhost_sync_dirty_bitmap(hdev, &hdev->mem_sections[i],
952                                 0, (target_phys_addr_t)~0x0ull);
953     }
954     r = vdev->binding->set_guest_notifiers(vdev->binding_opaque, false);
955     if (r < 0) {
956         fprintf(stderr, "vhost guest notifier cleanup failed: %d\n", r);
957         fflush(stderr);
958     }
959     assert (r >= 0);
960
961     hdev->started = false;
962     g_free(hdev->log);
963     hdev->log = NULL;
964     hdev->log_size = 0;
965 }
This page took 0.077835 seconds and 4 git commands to generate.