/* Host notifiers must be enabled at this point. */ void vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev) { int i, r; for (i = 0; i < hdev->nvqs; ++i) { vhost_virtqueue_cleanup(hdev, vdev, hdev->vqs + i, hdev->vq_index + i); } for (i = 0; i < hdev->n_mem_sections; ++i) { vhost_sync_dirty_bitmap(hdev, &hdev->mem_sections[i], 0, (target_phys_addr_t)~0x0ull); } if (hdev->vq_index == 0) { r = vdev->binding->set_guest_notifiers(vdev->binding_opaque, false); if (r < 0) { fprintf(stderr, "vhost guest notifier cleanup failed: %d\n", r); fflush(stderr); } assert (r >= 0); } hdev->started = false; g_free(hdev->log); hdev->log = NULL; hdev->log_size = 0; }
void vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev) { int i; for (i = 0; i < hdev->nvqs; ++i) { vhost_virtqueue_cleanup(hdev, vdev, hdev->vqs + i, i); } vhost_client_sync_dirty_bitmap(&hdev->client, 0, (target_phys_addr_t)~0x0ull); hdev->started = false; qemu_free(hdev->log); hdev->log_size = 0; }
int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev) { int i, r; r = vhost_dev_set_features(hdev, hdev->log_enabled); if (r < 0) { goto fail; } r = ioctl(hdev->control, VHOST_SET_MEM_TABLE, hdev->mem); if (r < 0) { r = -errno; goto fail; } if (hdev->log_enabled) { hdev->log_size = vhost_get_log_size(hdev); hdev->log = hdev->log_size ? qemu_mallocz(hdev->log_size * sizeof *hdev->log) : NULL; r = ioctl(hdev->control, VHOST_SET_LOG_BASE, (uint64_t)(unsigned long)hdev->log); if (r < 0) { r = -errno; goto fail; } } for (i = 0; i < hdev->nvqs; ++i) { r = vhost_virtqueue_init(hdev, vdev, hdev->vqs + i, i); if (r < 0) { goto fail_vq; } } hdev->started = true; return 0; fail_vq: while (--i >= 0) { vhost_virtqueue_cleanup(hdev, vdev, hdev->vqs + i, i); } fail: return r; }
void vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev) { int i, r; for (i = 0; i < hdev->nvqs; ++i) { vhost_virtqueue_cleanup(hdev, vdev, hdev->vqs + i, i); } vhost_client_sync_dirty_bitmap(&hdev->client, 0, (target_phys_addr_t)~0x0ull); r = vdev->binding->set_guest_notifiers(vdev->binding_opaque, false); if (r < 0) { fprintf(stderr, "vhost guest notifier cleanup failed: %d\n", r); fflush(stderr); } assert (r >= 0); hdev->started = false; qemu_free(hdev->log); hdev->log_size = 0; }
int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev) { int i, r; if (!vdev->binding->set_guest_notifiers) { fprintf(stderr, "binding does not support guest notifiers\n"); r = -ENOSYS; goto fail; } r = vdev->binding->set_guest_notifiers(vdev->binding_opaque, true); if (r < 0) { fprintf(stderr, "Error binding guest notifier: %d\n", -r); goto fail_notifiers; } r = vhost_dev_set_features(hdev, hdev->log_enabled); if (r < 0) { goto fail_features; } r = ioctl(hdev->control, VHOST_SET_MEM_TABLE, hdev->mem); if (r < 0) { r = -errno; goto fail_mem; } for (i = 0; i < hdev->nvqs; ++i) { r = vhost_virtqueue_init(hdev, vdev, hdev->vqs + i, i); if (r < 0) { goto fail_vq; } } if (hdev->log_enabled) { hdev->log_size = vhost_get_log_size(hdev); hdev->log = hdev->log_size ? qemu_mallocz(hdev->log_size * sizeof *hdev->log) : NULL; r = ioctl(hdev->control, VHOST_SET_LOG_BASE, (uint64_t)(unsigned long)hdev->log); if (r < 0) { r = -errno; goto fail_log; } } hdev->started = true; return 0; fail_log: fail_vq: while (--i >= 0) { vhost_virtqueue_cleanup(hdev, vdev, hdev->vqs + i, i); } fail_mem: fail_features: vdev->binding->set_guest_notifiers(vdev->binding_opaque, false); fail_notifiers: fail: return r; }