@@ -61,7 +61,7 @@ static void virtio_9p_device_realize(DeviceState *dev, Error **errp)
QLIST_INSERT_HEAD(&s->free_list, &s->pdus[i], next);
}
- s->vq = virtio_add_queue(vdev, MAX_REQ, handle_9p_output);
+ s->vq = virtio_add_queue(vdev, MAX_REQ, handle_9p_output, &error_abort);
v9fs_path_init(&path);
@@ -904,7 +904,7 @@ static void virtio_blk_device_realize(DeviceState *dev, Error **errp)
s->rq = NULL;
s->sector_mask = (s->conf.conf.logical_block_size / BDRV_SECTOR_SIZE) - 1;
- s->vq = virtio_add_queue(vdev, 128, virtio_blk_handle_output);
+ s->vq = virtio_add_queue(vdev, 128, virtio_blk_handle_output, &error_abort);
s->complete_request = virtio_blk_complete_request;
virtio_blk_data_plane_create(vdev, conf, &s->dataplane, &err);
if (err != NULL) {
@@ -999,9 +999,9 @@ static void virtio_serial_device_realize(DeviceState *dev, Error **errp)
* sizeof(VirtQueue *));
/* Add a queue for host to guest transfers for port 0 (backward compat) */
- vser->ivqs[0] = virtio_add_queue(vdev, 128, handle_input);
+ vser->ivqs[0] = virtio_add_queue(vdev, 128, handle_input, &error_abort);
/* Add a queue for guest to host transfers for port 0 (backward compat) */
- vser->ovqs[0] = virtio_add_queue(vdev, 128, handle_output);
+ vser->ovqs[0] = virtio_add_queue(vdev, 128, handle_output, &error_abort);
/* TODO: host to guest notifications can get dropped
* if the queue fills up. Implement queueing in host,
@@ -1010,15 +1010,17 @@ static void virtio_serial_device_realize(DeviceState *dev, Error **errp)
* this will save 4Kbyte of guest memory per entry. */
/* control queue: host to guest */
- vser->c_ivq = virtio_add_queue(vdev, 32, control_in);
+ vser->c_ivq = virtio_add_queue(vdev, 32, control_in, &error_abort);
/* control queue: guest to host */
- vser->c_ovq = virtio_add_queue(vdev, 32, control_out);
+ vser->c_ovq = virtio_add_queue(vdev, 32, control_out, &error_abort);
for (i = 1; i < vser->bus.max_nr_ports; i++) {
/* Add a per-port queue for host to guest transfers */
- vser->ivqs[i] = virtio_add_queue(vdev, 128, handle_input);
+ vser->ivqs[i] = virtio_add_queue(vdev, 128, handle_input,
+ &error_abort);
/* Add a per-per queue for guest to host transfers */
- vser->ovqs[i] = virtio_add_queue(vdev, 128, handle_output);
+ vser->ovqs[i] = virtio_add_queue(vdev, 128, handle_output,
+ &error_abort);
}
vser->ports_map = g_malloc0(((vser->serial.max_virtserial_ports + 31) / 32)
@@ -1314,16 +1314,19 @@ static void virtio_net_set_multiqueue(VirtIONet *n, int multiqueue)
}
for (i = 1; i < max; i++) {
- n->vqs[i].rx_vq = virtio_add_queue(vdev, 256, virtio_net_handle_rx);
+ n->vqs[i].rx_vq = virtio_add_queue(vdev, 256, virtio_net_handle_rx,
+ &error_abort);
if (n->vqs[i].tx_timer) {
n->vqs[i].tx_vq =
- virtio_add_queue(vdev, 256, virtio_net_handle_tx_timer);
+ virtio_add_queue(vdev, 256, virtio_net_handle_tx_timer,
+ &error_abort);
n->vqs[i].tx_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
virtio_net_tx_timer,
&n->vqs[i]);
} else {
n->vqs[i].tx_vq =
- virtio_add_queue(vdev, 256, virtio_net_handle_tx_bh);
+ virtio_add_queue(vdev, 256, virtio_net_handle_tx_bh,
+ &error_abort);
n->vqs[i].tx_bh = qemu_bh_new(virtio_net_tx_bh, &n->vqs[i]);
}
@@ -1335,7 +1338,8 @@ static void virtio_net_set_multiqueue(VirtIONet *n, int multiqueue)
* VIRTIO_NET_F_CTRL_VQ. Create ctrl vq unconditionally to avoid
* breaking them.
*/
- n->ctrl_vq = virtio_add_queue(vdev, 64, virtio_net_handle_ctrl);
+ n->ctrl_vq = virtio_add_queue(vdev, 64, virtio_net_handle_ctrl,
+ &error_abort);
virtio_net_set_queues(n);
}
@@ -1596,7 +1600,8 @@ static void virtio_net_device_realize(DeviceState *dev, Error **errp)
return;
}
n->vqs = g_malloc0(sizeof(VirtIONetQueue) * n->max_queues);
- n->vqs[0].rx_vq = virtio_add_queue(vdev, 256, virtio_net_handle_rx);
+ n->vqs[0].rx_vq = virtio_add_queue(vdev, 256, virtio_net_handle_rx,
+ &error_abort);
n->curr_queues = 1;
n->vqs[0].n = n;
n->tx_timeout = n->net_conf.txtimer;
@@ -1611,15 +1616,18 @@ static void virtio_net_device_realize(DeviceState *dev, Error **errp)
if (n->net_conf.tx && !strcmp(n->net_conf.tx, "timer")) {
n->vqs[0].tx_vq = virtio_add_queue(vdev, 256,
- virtio_net_handle_tx_timer);
+ virtio_net_handle_tx_timer,
+ &error_abort);
n->vqs[0].tx_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, virtio_net_tx_timer,
&n->vqs[0]);
} else {
n->vqs[0].tx_vq = virtio_add_queue(vdev, 256,
- virtio_net_handle_tx_bh);
+ virtio_net_handle_tx_bh,
+ &error_abort);
n->vqs[0].tx_bh = qemu_bh_new(virtio_net_tx_bh, &n->vqs[0]);
}
- n->ctrl_vq = virtio_add_queue(vdev, 64, virtio_net_handle_ctrl);
+ n->ctrl_vq = virtio_add_queue(vdev, 64, virtio_net_handle_ctrl,
+ &error_abort);
qemu_macaddr_default_if_unset(&n->nic_conf.macaddr);
memcpy(&n->mac[0], &n->nic_conf.macaddr, sizeof(n->mac));
n->status = VIRTIO_NET_S_LINK_UP;
@@ -838,12 +838,12 @@ void virtio_scsi_common_realize(DeviceState *dev, Error **errp,
s->cdb_size = VIRTIO_SCSI_CDB_DEFAULT_SIZE;
s->ctrl_vq = virtio_add_queue(vdev, VIRTIO_SCSI_VQ_SIZE,
- ctrl);
+ ctrl, &error_abort);
s->event_vq = virtio_add_queue(vdev, VIRTIO_SCSI_VQ_SIZE,
- evt);
+ evt, &error_abort);
for (i = 0; i < s->conf.num_queues; i++) {
s->cmd_vqs[i] = virtio_add_queue(vdev, VIRTIO_SCSI_VQ_SIZE,
- cmd);
+ cmd, &error_abort);
}
if (s->conf.iothread) {
@@ -388,9 +388,12 @@ static void virtio_balloon_device_realize(DeviceState *dev, Error **errp)
return;
}
- s->ivq = virtio_add_queue(vdev, 128, virtio_balloon_handle_output);
- s->dvq = virtio_add_queue(vdev, 128, virtio_balloon_handle_output);
- s->svq = virtio_add_queue(vdev, 128, virtio_balloon_receive_stats);
+ s->ivq = virtio_add_queue(vdev, 128, virtio_balloon_handle_output,
+ &error_abort);
+ s->dvq = virtio_add_queue(vdev, 128, virtio_balloon_handle_output,
+ &error_abort);
+ s->svq = virtio_add_queue(vdev, 128, virtio_balloon_receive_stats,
+ &error_abort);
reset_stats(s);
@@ -194,7 +194,7 @@ static void virtio_rng_device_realize(DeviceState *dev, Error **errp)
virtio_init(vdev, "virtio-rng", VIRTIO_ID_RNG, 0);
- vrng->vq = virtio_add_queue(vdev, 8, handle_input);
+ vrng->vq = virtio_add_queue(vdev, 8, handle_input, &error_abort);
vrng->quota_remaining = vrng->conf.max_bytes;
vrng->rate_limit_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL,
@@ -862,7 +862,8 @@ void virtio_queue_set_vector(VirtIODevice *vdev, int n, uint16_t vector)
}
VirtQueue *virtio_add_queue(VirtIODevice *vdev, int queue_size,
- void (*handle_output)(VirtIODevice *, VirtQueue *))
+ void (*handle_output)(VirtIODevice *, VirtQueue *),
+ Error **errp)
{
int i;
@@ -871,8 +872,14 @@ VirtQueue *virtio_add_queue(VirtIODevice *vdev, int queue_size,
break;
}
- if (i == VIRTIO_PCI_QUEUE_MAX || queue_size > VIRTQUEUE_MAX_SIZE)
- abort();
+ if (i == VIRTIO_PCI_QUEUE_MAX) {
+ error_setg(errp, "Cannot find free vq");
+ return NULL;
+ }
+ if (queue_size > VIRTQUEUE_MAX_SIZE) {
+ error_setg(errp, "Queue size too big: %d", queue_size);
+ return NULL;
+ }
vdev->vq[i].vring.num = queue_size;
vdev->vq[i].vring.align = VIRTIO_PCI_VRING_ALIGN;
@@ -129,7 +129,8 @@ void virtio_device_set_child_bus_name(VirtIODevice *vdev, char *bus_name);
VirtQueue *virtio_add_queue(VirtIODevice *vdev, int queue_size,
void (*handle_output)(VirtIODevice *,
- VirtQueue *));
+ VirtQueue *),
+ Error **errp);
void virtio_del_queue(VirtIODevice *vdev, int n);
All callers pass in error_abort for now. Error handling will be added in separate patches later. Signed-off-by: Fam Zheng <famz@redhat.com> --- hw/9pfs/virtio-9p-device.c | 2 +- hw/block/virtio-blk.c | 2 +- hw/char/virtio-serial-bus.c | 14 ++++++++------ hw/net/virtio-net.c | 24 ++++++++++++++++-------- hw/scsi/virtio-scsi.c | 6 +++--- hw/virtio/virtio-balloon.c | 9 ++++++--- hw/virtio/virtio-rng.c | 2 +- hw/virtio/virtio.c | 13 ++++++++++--- include/hw/virtio/virtio.h | 3 ++- 9 files changed, 48 insertions(+), 27 deletions(-)