aboutsummaryrefslogtreecommitdiff
path: root/hw/virtio
diff options
context:
space:
mode:
Diffstat (limited to 'hw/virtio')
-rw-r--r--hw/virtio/vhost-backend.c6
-rw-r--r--hw/virtio/vhost-user-fs.c3
-rw-r--r--hw/virtio/vhost-user-vsock.c12
-rw-r--r--hw/virtio/vhost-user.c71
-rw-r--r--hw/virtio/vhost-vdpa.c8
-rw-r--r--hw/virtio/vhost-vsock.c3
-rw-r--r--hw/virtio/vhost.c41
7 files changed, 82 insertions, 62 deletions
diff --git a/hw/virtio/vhost-backend.c b/hw/virtio/vhost-backend.c
index 31b33bde37..594d770b75 100644
--- a/hw/virtio/vhost-backend.c
+++ b/hw/virtio/vhost-backend.c
@@ -24,13 +24,15 @@ static int vhost_kernel_call(struct vhost_dev *dev, unsigned long int request,
void *arg)
{
int fd = (uintptr_t) dev->opaque;
+ int ret;
assert(dev->vhost_ops->backend_type == VHOST_BACKEND_TYPE_KERNEL);
- return ioctl(fd, request, arg);
+ ret = ioctl(fd, request, arg);
+ return ret < 0 ? -errno : ret;
}
-static int vhost_kernel_init(struct vhost_dev *dev, void *opaque)
+static int vhost_kernel_init(struct vhost_dev *dev, void *opaque, Error **errp)
{
assert(dev->vhost_ops->backend_type == VHOST_BACKEND_TYPE_KERNEL);
diff --git a/hw/virtio/vhost-user-fs.c b/hw/virtio/vhost-user-fs.c
index 6f7f91533d..c595957983 100644
--- a/hw/virtio/vhost-user-fs.c
+++ b/hw/virtio/vhost-user-fs.c
@@ -235,9 +235,8 @@ static void vuf_device_realize(DeviceState *dev, Error **errp)
fs->vhost_dev.nvqs = 1 + fs->conf.num_request_queues;
fs->vhost_dev.vqs = g_new0(struct vhost_virtqueue, fs->vhost_dev.nvqs);
ret = vhost_dev_init(&fs->vhost_dev, &fs->vhost_user,
- VHOST_BACKEND_TYPE_USER, 0);
+ VHOST_BACKEND_TYPE_USER, 0, errp);
if (ret < 0) {
- error_setg_errno(errp, -ret, "vhost_dev_init failed");
goto err_virtio;
}
diff --git a/hw/virtio/vhost-user-vsock.c b/hw/virtio/vhost-user-vsock.c
index a6f08c26b9..6095ed7349 100644
--- a/hw/virtio/vhost-user-vsock.c
+++ b/hw/virtio/vhost-user-vsock.c
@@ -34,10 +34,12 @@ static void vuv_get_config(VirtIODevice *vdev, uint8_t *config)
static int vuv_handle_config_change(struct vhost_dev *dev)
{
VHostUserVSock *vsock = VHOST_USER_VSOCK(dev->vdev);
+ Error *local_err = NULL;
int ret = vhost_dev_get_config(dev, (uint8_t *)&vsock->vsockcfg,
- sizeof(struct virtio_vsock_config));
+ sizeof(struct virtio_vsock_config),
+ &local_err);
if (ret < 0) {
- error_report("get config space failed");
+ error_report_err(local_err);
return -1;
}
@@ -108,16 +110,14 @@ static void vuv_device_realize(DeviceState *dev, Error **errp)
vhost_dev_set_config_notifier(&vvc->vhost_dev, &vsock_ops);
ret = vhost_dev_init(&vvc->vhost_dev, &vsock->vhost_user,
- VHOST_BACKEND_TYPE_USER, 0);
+ VHOST_BACKEND_TYPE_USER, 0, errp);
if (ret < 0) {
- error_setg_errno(errp, -ret, "vhost_dev_init failed");
goto err_virtio;
}
ret = vhost_dev_get_config(&vvc->vhost_dev, (uint8_t *)&vsock->vsockcfg,
- sizeof(struct virtio_vsock_config));
+ sizeof(struct virtio_vsock_config), errp);
if (ret < 0) {
- error_setg_errno(errp, -ret, "get config space failed");
goto err_vhost_dev;
}
diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c
index ee57abe045..1ac4a2ebec 100644
--- a/hw/virtio/vhost-user.c
+++ b/hw/virtio/vhost-user.c
@@ -1353,7 +1353,11 @@ static int vhost_user_get_u64(struct vhost_dev *dev, int request, uint64_t *u64)
static int vhost_user_get_features(struct vhost_dev *dev, uint64_t *features)
{
- return vhost_user_get_u64(dev, VHOST_USER_GET_FEATURES, features);
+ if (vhost_user_get_u64(dev, VHOST_USER_GET_FEATURES, features) < 0) {
+ return -EPROTO;
+ }
+
+ return 0;
}
static int vhost_user_set_owner(struct vhost_dev *dev)
@@ -1364,7 +1368,7 @@ static int vhost_user_set_owner(struct vhost_dev *dev)
};
if (vhost_user_write(dev, &msg, NULL, 0) < 0) {
- return -1;
+ return -EPROTO;
}
return 0;
@@ -1856,7 +1860,8 @@ static int vhost_user_postcopy_notifier(NotifierWithReturn *notifier,
return 0;
}
-static int vhost_user_backend_init(struct vhost_dev *dev, void *opaque)
+static int vhost_user_backend_init(struct vhost_dev *dev, void *opaque,
+ Error **errp)
{
uint64_t features, protocol_features, ram_slots;
struct vhost_user *u;
@@ -1880,7 +1885,7 @@ static int vhost_user_backend_init(struct vhost_dev *dev, void *opaque)
err = vhost_user_get_u64(dev, VHOST_USER_GET_PROTOCOL_FEATURES,
&protocol_features);
if (err < 0) {
- return err;
+ return -EPROTO;
}
dev->protocol_features =
@@ -1891,14 +1896,14 @@ static int vhost_user_backend_init(struct vhost_dev *dev, void *opaque)
dev->protocol_features &= ~(1ULL << VHOST_USER_PROTOCOL_F_CONFIG);
} else if (!(protocol_features &
(1ULL << VHOST_USER_PROTOCOL_F_CONFIG))) {
- error_report("Device expects VHOST_USER_PROTOCOL_F_CONFIG "
- "but backend does not support it.");
- return -1;
+ error_setg(errp, "Device expects VHOST_USER_PROTOCOL_F_CONFIG "
+ "but backend does not support it.");
+ return -EINVAL;
}
err = vhost_user_set_protocol_features(dev, dev->protocol_features);
if (err < 0) {
- return err;
+ return -EPROTO;
}
/* query the max queues we support if backend supports Multiple Queue */
@@ -1906,12 +1911,12 @@ static int vhost_user_backend_init(struct vhost_dev *dev, void *opaque)
err = vhost_user_get_u64(dev, VHOST_USER_GET_QUEUE_NUM,
&dev->max_queues);
if (err < 0) {
- return err;
+ return -EPROTO;
}
}
if (dev->num_queues && dev->max_queues < dev->num_queues) {
- error_report("The maximum number of queues supported by the "
- "backend is %" PRIu64, dev->max_queues);
+ error_setg(errp, "The maximum number of queues supported by the "
+ "backend is %" PRIu64, dev->max_queues);
return -EINVAL;
}
@@ -1920,9 +1925,9 @@ static int vhost_user_backend_init(struct vhost_dev *dev, void *opaque)
VHOST_USER_PROTOCOL_F_SLAVE_REQ) &&
virtio_has_feature(dev->protocol_features,
VHOST_USER_PROTOCOL_F_REPLY_ACK))) {
- error_report("IOMMU support requires reply-ack and "
- "slave-req protocol features.");
- return -1;
+ error_setg(errp, "IOMMU support requires reply-ack and "
+ "slave-req protocol features.");
+ return -EINVAL;
}
/* get max memory regions if backend supports configurable RAM slots */
@@ -1932,15 +1937,15 @@ static int vhost_user_backend_init(struct vhost_dev *dev, void *opaque)
} else {
err = vhost_user_get_max_memslots(dev, &ram_slots);
if (err < 0) {
- return err;
+ return -EPROTO;
}
if (ram_slots < u->user->memory_slots) {
- error_report("The backend specified a max ram slots limit "
- "of %" PRIu64", when the prior validated limit was %d. "
- "This limit should never decrease.", ram_slots,
- u->user->memory_slots);
- return -1;
+ error_setg(errp, "The backend specified a max ram slots limit "
+ "of %" PRIu64", when the prior validated limit was "
+ "%d. This limit should never decrease.", ram_slots,
+ u->user->memory_slots);
+ return -EINVAL;
}
u->user->memory_slots = MIN(ram_slots, VHOST_USER_MAX_RAM_SLOTS);
@@ -1958,7 +1963,7 @@ static int vhost_user_backend_init(struct vhost_dev *dev, void *opaque)
if (dev->vq_index == 0) {
err = vhost_setup_slave_channel(dev);
if (err < 0) {
- return err;
+ return -EPROTO;
}
}
@@ -2112,7 +2117,7 @@ static void vhost_user_set_iotlb_callback(struct vhost_dev *dev, int enabled)
}
static int vhost_user_get_config(struct vhost_dev *dev, uint8_t *config,
- uint32_t config_len)
+ uint32_t config_len, Error **errp)
{
VhostUserMsg msg = {
.hdr.request = VHOST_USER_GET_CONFIG,
@@ -2122,32 +2127,32 @@ static int vhost_user_get_config(struct vhost_dev *dev, uint8_t *config,
if (!virtio_has_feature(dev->protocol_features,
VHOST_USER_PROTOCOL_F_CONFIG)) {
- return -1;
+ error_setg(errp, "VHOST_USER_PROTOCOL_F_CONFIG not supported");
+ return -EINVAL;
}
- if (config_len > VHOST_USER_MAX_CONFIG_SIZE) {
- return -1;
- }
+ assert(config_len <= VHOST_USER_MAX_CONFIG_SIZE);
msg.payload.config.offset = 0;
msg.payload.config.size = config_len;
if (vhost_user_write(dev, &msg, NULL, 0) < 0) {
- return -1;
+ return -EPROTO;
}
if (vhost_user_read(dev, &msg) < 0) {
- return -1;
+ return -EPROTO;
}
if (msg.hdr.request != VHOST_USER_GET_CONFIG) {
- error_report("Received unexpected msg type. Expected %d received %d",
- VHOST_USER_GET_CONFIG, msg.hdr.request);
- return -1;
+ error_setg(errp,
+ "Received unexpected msg type. Expected %d received %d",
+ VHOST_USER_GET_CONFIG, msg.hdr.request);
+ return -EINVAL;
}
if (msg.hdr.size != VHOST_USER_CONFIG_HDR_SIZE + config_len) {
- error_report("Received bad msg size.");
- return -1;
+ error_setg(errp, "Received bad msg size.");
+ return -EINVAL;
}
memcpy(config, msg.payload.config.region, config_len);
diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c
index 61ba313331..4fa414feea 100644
--- a/hw/virtio/vhost-vdpa.c
+++ b/hw/virtio/vhost-vdpa.c
@@ -245,10 +245,12 @@ static int vhost_vdpa_call(struct vhost_dev *dev, unsigned long int request,
{
struct vhost_vdpa *v = dev->opaque;
int fd = v->device_fd;
+ int ret;
assert(dev->vhost_ops->backend_type == VHOST_BACKEND_TYPE_VDPA);
- return ioctl(fd, request, arg);
+ ret = ioctl(fd, request, arg);
+ return ret < 0 ? -errno : ret;
}
static void vhost_vdpa_add_status(struct vhost_dev *dev, uint8_t status)
@@ -265,7 +267,7 @@ static void vhost_vdpa_add_status(struct vhost_dev *dev, uint8_t status)
vhost_vdpa_call(dev, VHOST_VDPA_SET_STATUS, &s);
}
-static int vhost_vdpa_init(struct vhost_dev *dev, void *opaque)
+static int vhost_vdpa_init(struct vhost_dev *dev, void *opaque, Error **errp)
{
struct vhost_vdpa *v;
assert(dev->vhost_ops->backend_type == VHOST_BACKEND_TYPE_VDPA);
@@ -521,7 +523,7 @@ static int vhost_vdpa_set_config(struct vhost_dev *dev, const uint8_t *data,
}
static int vhost_vdpa_get_config(struct vhost_dev *dev, uint8_t *config,
- uint32_t config_len)
+ uint32_t config_len, Error **errp)
{
struct vhost_vdpa_config *v_config;
unsigned long config_size = offsetof(struct vhost_vdpa_config, buf);
diff --git a/hw/virtio/vhost-vsock.c b/hw/virtio/vhost-vsock.c
index 8ddfb9abfe..777cafe70d 100644
--- a/hw/virtio/vhost-vsock.c
+++ b/hw/virtio/vhost-vsock.c
@@ -170,9 +170,8 @@ static void vhost_vsock_device_realize(DeviceState *dev, Error **errp)
vhost_vsock_common_realize(vdev, "vhost-vsock");
ret = vhost_dev_init(&vvc->vhost_dev, (void *)(uintptr_t)vhostfd,
- VHOST_BACKEND_TYPE_KERNEL, 0);
+ VHOST_BACKEND_TYPE_KERNEL, 0, errp);
if (ret < 0) {
- error_setg_errno(errp, -ret, "vhost-vsock: vhost_dev_init failed");
goto err_virtio;
}
diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
index 7b7bde7657..e8f85a5d2d 100644
--- a/hw/virtio/vhost.c
+++ b/hw/virtio/vhost.c
@@ -1286,11 +1286,12 @@ static void vhost_virtqueue_cleanup(struct vhost_virtqueue *vq)
}
int vhost_dev_init(struct vhost_dev *hdev, void *opaque,
- VhostBackendType backend_type, uint32_t busyloop_timeout)
+ VhostBackendType backend_type, uint32_t busyloop_timeout,
+ Error **errp)
{
+ ERRP_GUARD();
uint64_t features;
int i, r, n_initialized_vqs = 0;
- Error *local_err = NULL;
hdev->vdev = NULL;
hdev->migration_blocker = NULL;
@@ -1298,26 +1299,30 @@ int vhost_dev_init(struct vhost_dev *hdev, void *opaque,
r = vhost_set_backend_type(hdev, backend_type);
assert(r >= 0);
- r = hdev->vhost_ops->vhost_backend_init(hdev, opaque);
+ r = hdev->vhost_ops->vhost_backend_init(hdev, opaque, errp);
if (r < 0) {
+ if (!*errp) {
+ error_setg_errno(errp, -r, "vhost_backend_init failed");
+ }
goto fail;
}
r = hdev->vhost_ops->vhost_set_owner(hdev);
if (r < 0) {
- VHOST_OPS_DEBUG("vhost_set_owner failed");
+ error_setg_errno(errp, -r, "vhost_set_owner failed");
goto fail;
}
r = hdev->vhost_ops->vhost_get_features(hdev, &features);
if (r < 0) {
- VHOST_OPS_DEBUG("vhost_get_features failed");
+ error_setg_errno(errp, -r, "vhost_get_features failed");
goto fail;
}
for (i = 0; i < hdev->nvqs; ++i, ++n_initialized_vqs) {
r = vhost_virtqueue_init(hdev, hdev->vqs + i, hdev->vq_index + i);
if (r < 0) {
+ error_setg_errno(errp, -r, "Failed to initialize virtqueue %d", i);
goto fail;
}
}
@@ -1327,6 +1332,7 @@ int vhost_dev_init(struct vhost_dev *hdev, void *opaque,
r = vhost_virtqueue_set_busyloop_timeout(hdev, hdev->vq_index + i,
busyloop_timeout);
if (r < 0) {
+ error_setg_errno(errp, -r, "Failed to set busyloop timeout");
goto fail_busyloop;
}
}
@@ -1365,9 +1371,8 @@ int vhost_dev_init(struct vhost_dev *hdev, void *opaque,
}
if (hdev->migration_blocker != NULL) {
- r = migrate_add_blocker(hdev->migration_blocker, &local_err);
- if (local_err) {
- error_report_err(local_err);
+ r = migrate_add_blocker(hdev->migration_blocker, errp);
+ if (*errp) {
error_free(hdev->migration_blocker);
goto fail_busyloop;
}
@@ -1384,9 +1389,9 @@ int vhost_dev_init(struct vhost_dev *hdev, void *opaque,
QLIST_INSERT_HEAD(&vhost_devices, hdev, entry);
if (used_memslots > hdev->vhost_ops->vhost_backend_memslots_limit(hdev)) {
- error_report("vhost backend memory slots limit is less"
- " than current number of present memory slots");
- r = -1;
+ error_setg(errp, "vhost backend memory slots limit is less"
+ " than current number of present memory slots");
+ r = -EINVAL;
goto fail_busyloop;
}
@@ -1557,15 +1562,23 @@ void vhost_ack_features(struct vhost_dev *hdev, const int *feature_bits,
}
int vhost_dev_get_config(struct vhost_dev *hdev, uint8_t *config,
- uint32_t config_len)
+ uint32_t config_len, Error **errp)
{
+ ERRP_GUARD();
+ int ret;
+
assert(hdev->vhost_ops);
if (hdev->vhost_ops->vhost_get_config) {
- return hdev->vhost_ops->vhost_get_config(hdev, config, config_len);
+ ret = hdev->vhost_ops->vhost_get_config(hdev, config, config_len, errp);
+ if (ret < 0 && !*errp) {
+ error_setg_errno(errp, -ret, "vhost_get_config failed");
+ }
+ return ret;
}
- return -1;
+ error_setg(errp, "vhost_get_config not implemented");
+ return -ENOTSUP;
}
int vhost_dev_set_config(struct vhost_dev *hdev, const uint8_t *data,