static int vhost_dev_set_log(struct vhost_dev *dev, bool enable_log) { int r, t, i; r = vhost_dev_set_features(dev, enable_log); if (r < 0) { goto err_features; } for (i = 0; i < dev->nvqs; ++i) { r = vhost_virtqueue_set_addr(dev, dev->vqs + i, i, enable_log); if (r < 0) { goto err_vq; } } return 0; err_vq: for (; i >= 0; --i) { t = vhost_virtqueue_set_addr(dev, dev->vqs + i, i, dev->log_enabled); assert(t >= 0); } t = vhost_dev_set_features(dev, dev->log_enabled); assert(t >= 0); err_features: return r; }
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; }
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; }