Re: [PATCH v2 2/2] virtio: use Error for queue size validation in virtio_add_queue()
Laurent Vivier <[email protected]> Fri, 31 Jul 2026 08:58:36 +0200
| Newsgroups | dev.linux.lists.virtio-fs,org.nongnu.qemu-devel |
|---|---|
| Message-ID | <[email protected]> |
On 7/30/26 22:58, Stefan Hajnoczi wrote: > Coverity is unhappy with the code path where the x-override-queue-size > property value is passed to g_new0() since it is a signed int rather > than an unsigned int: > > *** CID 1664271: Error handling issues (NEGATIVE_RETURNS) > /builds/qemu-project/qemu/hw/virtio/virtio.c: 2595 in virtio_add_queue() > 2589 } > 2590 > 2591 vdev->vq[i].vring.num = queue_size; > 2592 vdev->vq[i].vring.num_default = queue_size; > 2593 vdev->vq[i].vring.align = VIRTIO_PCI_VRING_ALIGN; > 2594 vdev->vq[i].handle_output = handle_output; > >>> CID 1664271: Error handling issues (NEGATIVE_RETURNS) > >>> "__n" is passed to a parameter that cannot be negative. > 2595 vdev->vq[i].used_elems = g_new0(VirtQueueElement, queue_size); > > Introduce an Error **errp argument to virtio_add_queue() and set it when > the queue_size argument or the x-override-queue-size property value are > invalid. > > At the moment none of the callers propagate the Error object. Instead > they are all modified to pass &error_abort so that the error message is > printed and the program terminates (it also terminated before). Further > work, especially in new device emulation code, could actually propagate > the Error object but is left for the future. > > Signed-off-by: Stefan Hajnoczi <[email protected]> > --- > include/hw/virtio/virtio.h | 2 +- > hw/9pfs/virtio-9p-device.c | 2 +- > hw/audio/virtio-snd.c | 8 ++++---- > hw/block/vhost-user-blk.c | 3 ++- > hw/block/virtio-blk.c | 3 ++- > hw/char/virtio-serial-bus.c | 14 +++++++------ > hw/display/virtio-gpu-base.c | 8 ++++---- > hw/input/virtio-input.c | 6 ++++-- > hw/net/virtio-net.c | 15 +++++++++----- > hw/scsi/virtio-scsi.c | 9 ++++++--- > hw/virtio/vdpa-dev.c | 3 ++- > hw/virtio/vhost-user-base.c | 3 ++- > hw/virtio/vhost-user-fs.c | 8 ++++++-- > hw/virtio/vhost-user-scmi.c | 6 ++++-- > hw/virtio/vhost-vsock-common.c | 9 ++++++--- > hw/virtio/virtio-balloon.c | 15 +++++++++----- > hw/virtio/virtio-crypto.c | 6 ++++-- > hw/virtio/virtio-iommu.c | 6 ++++-- > hw/virtio/virtio-mem.c | 3 ++- > hw/virtio/virtio-nsm.c | 2 +- > hw/virtio/virtio-pmem.c | 2 +- > hw/virtio/virtio-rng.c | 2 +- > hw/virtio/virtio-rtc.c | 3 ++- > hw/virtio/virtio.c | 37 ++++++++++++++++++++++++++++++---- > 24 files changed, 120 insertions(+), 55 deletions(-) Reviewed-by: Laurent Vivier <[email protected]> > > diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h > index ff7f837fb92..a5d4264cd42 100644 > --- a/include/hw/virtio/virtio.h > +++ b/include/hw/virtio/virtio.h > @@ -303,7 +303,7 @@ void virtio_device_set_child_bus_name(VirtIODevice *vdev, char *bus_name); > typedef void (*VirtIOHandleOutput)(VirtIODevice *, VirtQueue *); > > VirtQueue *virtio_add_queue(VirtIODevice *vdev, unsigned int queue_size, > - VirtIOHandleOutput handle_output); > + VirtIOHandleOutput handle_output, Error **errp); > > void virtio_del_queue(VirtIODevice *vdev, int n); > > diff --git a/hw/9pfs/virtio-9p-device.c b/hw/9pfs/virtio-9p-device.c > index 2774fc2290a..6b96ca77621 100644 > --- a/hw/9pfs/virtio-9p-device.c > +++ b/hw/9pfs/virtio-9p-device.c > @@ -236,7 +236,7 @@ static void virtio_9p_device_realize(DeviceState *dev, Error **errp) > > v->config_size = sizeof(struct virtio_9p_config) + strlen(s->fsconf.tag); > virtio_init(vdev, VIRTIO_ID_9P, v->config_size); > - v->vq = virtio_add_queue(vdev, MAX_REQ, handle_9p_output); > + v->vq = virtio_add_queue(vdev, MAX_REQ, handle_9p_output, &error_abort); > } > > static void virtio_9p_device_unrealize(DeviceState *dev) > diff --git a/hw/audio/virtio-snd.c b/hw/audio/virtio-snd.c > index 694bcebb60f..bfd9abecd13 100644 > --- a/hw/audio/virtio-snd.c > +++ b/hw/audio/virtio-snd.c > @@ -1089,13 +1089,13 @@ static void virtio_snd_realize(DeviceState *dev, Error **errp) > default_params.format = VIRTIO_SND_PCM_FMT_S16; > default_params.rate = VIRTIO_SND_PCM_RATE_48000; > vsnd->queues[VIRTIO_SND_VQ_CONTROL] = > - virtio_add_queue(vdev, 64, virtio_snd_handle_ctrl); > + virtio_add_queue(vdev, 64, virtio_snd_handle_ctrl, &error_abort); > vsnd->queues[VIRTIO_SND_VQ_EVENT] = > - virtio_add_queue(vdev, 64, virtio_snd_handle_event); > + virtio_add_queue(vdev, 64, virtio_snd_handle_event, &error_abort); > vsnd->queues[VIRTIO_SND_VQ_TX] = > - virtio_add_queue(vdev, 64, virtio_snd_handle_tx_xfer); > + virtio_add_queue(vdev, 64, virtio_snd_handle_tx_xfer, &error_abort); > vsnd->queues[VIRTIO_SND_VQ_RX] = > - virtio_add_queue(vdev, 64, virtio_snd_handle_rx_xfer); > + virtio_add_queue(vdev, 64, virtio_snd_handle_rx_xfer, &error_abort); > qemu_mutex_init(&vsnd->cmdq_mutex); > QTAILQ_INIT(&vsnd->cmdq); > QSIMPLEQ_INIT(&vsnd->invalid); > diff --git a/hw/block/vhost-user-blk.c b/hw/block/vhost-user-blk.c > index 2e5b3ae1b14..77fc53ee681 100644 > --- a/hw/block/vhost-user-blk.c > +++ b/hw/block/vhost-user-blk.c > @@ -516,7 +516,8 @@ static void vhost_user_blk_device_realize(DeviceState *dev, Error **errp) > s->virtqs = g_new(VirtQueue *, s->num_queues); > for (i = 0; i < s->num_queues; i++) { > s->virtqs[i] = virtio_add_queue(vdev, s->queue_size, > - vhost_user_blk_handle_output); > + vhost_user_blk_handle_output, > + &error_abort); > } > > s->inflight = g_new0(struct vhost_inflight, 1); > diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c > index 6b92066aff4..5b978e357ee 100644 > --- a/hw/block/virtio-blk.c > +++ b/hw/block/virtio-blk.c > @@ -1815,7 +1815,8 @@ static void virtio_blk_device_realize(DeviceState *dev, Error **errp) > s->sector_mask = (s->conf.conf.logical_block_size / BDRV_SECTOR_SIZE) - 1; > > for (i = 0; i < conf->num_queues; i++) { > - virtio_add_queue(vdev, conf->queue_size, virtio_blk_handle_output); > + virtio_add_queue(vdev, conf->queue_size, virtio_blk_handle_output, > + &error_abort); > } > qemu_coroutine_inc_pool_size(conf->num_queues * conf->queue_size / 2); > > diff --git a/hw/char/virtio-serial-bus.c b/hw/char/virtio-serial-bus.c > index c1973f0248f..7e1d74c988c 100644 > --- a/hw/char/virtio-serial-bus.c > +++ b/hw/char/virtio-serial-bus.c > @@ -1033,9 +1033,9 @@ static void virtio_serial_device_realize(DeviceState *dev, Error **errp) > vser->ovqs = g_new(VirtQueue *, vser->serial.max_virtserial_ports); > > /* 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, > @@ -1044,15 +1044,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((DIV_ROUND_UP(vser->serial.max_virtserial_ports, 32)) > diff --git a/hw/display/virtio-gpu-base.c b/hw/display/virtio-gpu-base.c > index 946e56b42f6..f808d1f6743 100644 > --- a/hw/display/virtio-gpu-base.c > +++ b/hw/display/virtio-gpu-base.c > @@ -238,11 +238,11 @@ virtio_gpu_base_device_realize(DeviceState *qdev, > > if (virtio_gpu_virgl_enabled(g->conf)) { > /* use larger control queue in 3d mode */ > - virtio_add_queue(vdev, 256, ctrl_cb); > - virtio_add_queue(vdev, 16, cursor_cb); > + virtio_add_queue(vdev, 256, ctrl_cb, &error_abort); > + virtio_add_queue(vdev, 16, cursor_cb, &error_abort); > } else { > - virtio_add_queue(vdev, 64, ctrl_cb); > - virtio_add_queue(vdev, 16, cursor_cb); > + virtio_add_queue(vdev, 64, ctrl_cb, &error_abort); > + virtio_add_queue(vdev, 16, cursor_cb, &error_abort); > } > > g->hw_ops = &virtio_gpu_ops; > diff --git a/hw/input/virtio-input.c b/hw/input/virtio-input.c > index 6494cfbbe82..192b1ea8c61 100644 > --- a/hw/input/virtio-input.c > +++ b/hw/input/virtio-input.c > @@ -259,8 +259,10 @@ static void virtio_input_device_realize(DeviceState *dev, Error **errp) > assert(vinput->cfg_size <= sizeof(virtio_input_config)); > > virtio_init(vdev, VIRTIO_ID_INPUT, vinput->cfg_size); > - vinput->evt = virtio_add_queue(vdev, 64, virtio_input_handle_evt); > - vinput->sts = virtio_add_queue(vdev, 64, virtio_input_handle_sts); > + vinput->evt = virtio_add_queue(vdev, 64, virtio_input_handle_evt, > + &error_abort); > + vinput->sts = virtio_add_queue(vdev, 64, virtio_input_handle_sts, > + &error_abort); > } > > static void virtio_input_finalize(Object *obj) > diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c > index 814b99a43d2..ab7611274a7 100644 > --- a/hw/net/virtio-net.c > +++ b/hw/net/virtio-net.c > @@ -2996,19 +2996,22 @@ static void virtio_net_add_queue(VirtIONet *n, int index) > VirtIODevice *vdev = VIRTIO_DEVICE(n); > > n->vqs[index].rx_vq = virtio_add_queue(vdev, n->net_conf.rx_queue_size, > - virtio_net_handle_rx); > + virtio_net_handle_rx, > + &error_abort); > > if (n->net_conf.tx && !strcmp(n->net_conf.tx, "timer")) { > n->vqs[index].tx_vq = > virtio_add_queue(vdev, n->net_conf.tx_queue_size, > - virtio_net_handle_tx_timer); > + virtio_net_handle_tx_timer, > + &error_abort); > n->vqs[index].tx_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, > virtio_net_tx_timer, > &n->vqs[index]); > } else { > n->vqs[index].tx_vq = > virtio_add_queue(vdev, n->net_conf.tx_queue_size, > - virtio_net_handle_tx_bh); > + virtio_net_handle_tx_bh, > + &error_abort); > n->vqs[index].tx_bh = virtio_bh_new_guarded(DEVICE(vdev), > virtio_net_tx_bh, > &n->vqs[index]); > @@ -3069,7 +3072,8 @@ static void virtio_net_change_num_queues(VirtIONet *n, int new_num_queues) > } > > /* add ctrl_vq last */ > - 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); > } > > static void virtio_net_set_multiqueue(VirtIONet *n, int multiqueue) > @@ -4001,7 +4005,8 @@ static void virtio_net_device_realize(DeviceState *dev, Error **errp) > > virtio_net_add_queue(n, 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; > diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c > index bf64d1231a8..4045414cd2f 100644 > --- a/hw/scsi/virtio-scsi.c > +++ b/hw/scsi/virtio-scsi.c > @@ -1317,10 +1317,13 @@ void virtio_scsi_common_realize(DeviceState *dev, > s->sense_size = VIRTIO_SCSI_SENSE_DEFAULT_SIZE; > s->cdb_size = VIRTIO_SCSI_CDB_DEFAULT_SIZE; > > - s->ctrl_vq = virtio_add_queue(vdev, s->conf.virtqueue_size, ctrl); > - s->event_vq = virtio_add_queue(vdev, s->conf.virtqueue_size, evt); > + s->ctrl_vq = virtio_add_queue(vdev, s->conf.virtqueue_size, ctrl, > + &error_abort); > + s->event_vq = virtio_add_queue(vdev, s->conf.virtqueue_size, evt, > + &error_abort); > for (i = 0; i < s->conf.num_queues; i++) { > - s->cmd_vqs[i] = virtio_add_queue(vdev, s->conf.virtqueue_size, cmd); > + s->cmd_vqs[i] = virtio_add_queue(vdev, s->conf.virtqueue_size, cmd, > + &error_abort); > } > } > > diff --git a/hw/virtio/vdpa-dev.c b/hw/virtio/vdpa-dev.c > index 6dc684ab096..1f96985056b 100644 > --- a/hw/virtio/vdpa-dev.c > +++ b/hw/virtio/vdpa-dev.c > @@ -151,7 +151,8 @@ static void vhost_vdpa_device_realize(DeviceState *dev, Error **errp) > v->virtqs = g_new0(VirtQueue *, v->dev.nvqs); > for (i = 0; i < v->dev.nvqs; i++) { > v->virtqs[i] = virtio_add_queue(vdev, v->queue_size, > - vhost_vdpa_device_dummy_handle_output); > + vhost_vdpa_device_dummy_handle_output, > + &error_abort); > } > > return; > diff --git a/hw/virtio/vhost-user-base.c b/hw/virtio/vhost-user-base.c > index 478ec68f093..fe14718fba3 100644 > --- a/hw/virtio/vhost-user-base.c > +++ b/hw/virtio/vhost-user-base.c > @@ -334,7 +334,8 @@ static void vub_device_realize(DeviceState *dev, Error **errp) > for (i = 0; i < vub->num_vqs; i++) { > g_ptr_array_add(vub->vqs, > virtio_add_queue(vdev, vub->vq_size, > - vub_handle_output)); > + vub_handle_output, > + &error_abort)); > } > > vub->vhost_dev.nvqs = vub->num_vqs; > diff --git a/hw/virtio/vhost-user-fs.c b/hw/virtio/vhost-user-fs.c > index 209993918a3..57100ba2c4c 100644 > --- a/hw/virtio/vhost-user-fs.c > +++ b/hw/virtio/vhost-user-fs.c > @@ -245,12 +245,16 @@ static void vuf_device_realize(DeviceState *dev, Error **errp) > virtio_init(vdev, VIRTIO_ID_FS, sizeof(struct virtio_fs_config)); > > /* Hiprio queue */ > - fs->hiprio_vq = virtio_add_queue(vdev, fs->conf.queue_size, vuf_handle_output); > + fs->hiprio_vq = virtio_add_queue(vdev, fs->conf.queue_size, > + vuf_handle_output, > + &error_abort); > > /* Request queues */ > fs->req_vqs = g_new(VirtQueue *, fs->conf.num_request_queues); > for (i = 0; i < fs->conf.num_request_queues; i++) { > - fs->req_vqs[i] = virtio_add_queue(vdev, fs->conf.queue_size, vuf_handle_output); > + fs->req_vqs[i] = virtio_add_queue(vdev, fs->conf.queue_size, > + vuf_handle_output, > + &error_abort); > } > > /* 1 high prio queue, plus the number configured */ > diff --git a/hw/virtio/vhost-user-scmi.c b/hw/virtio/vhost-user-scmi.c > index 02dc088ea98..1da916585aa 100644 > --- a/hw/virtio/vhost-user-scmi.c > +++ b/hw/virtio/vhost-user-scmi.c > @@ -250,8 +250,10 @@ static void vu_scmi_device_realize(DeviceState *dev, Error **errp) > > virtio_init(vdev, VIRTIO_ID_SCMI, 0); > > - scmi->cmd_vq = virtio_add_queue(vdev, 256, vu_scmi_handle_output); > - scmi->event_vq = virtio_add_queue(vdev, 256, vu_scmi_handle_output); > + scmi->cmd_vq = virtio_add_queue(vdev, 256, vu_scmi_handle_output, > + &error_abort); > + scmi->event_vq = virtio_add_queue(vdev, 256, vu_scmi_handle_output, > + &error_abort); > scmi->vhost_dev.nvqs = 2; > scmi->vhost_dev.vqs = g_new0(struct vhost_virtqueue, scmi->vhost_dev.nvqs); > vhost_vqs = scmi->vhost_dev.vqs; > diff --git a/hw/virtio/vhost-vsock-common.c b/hw/virtio/vhost-vsock-common.c > index b79f4c9ce66..584891ff005 100644 > --- a/hw/virtio/vhost-vsock-common.c > +++ b/hw/virtio/vhost-vsock-common.c > @@ -254,13 +254,16 @@ void vhost_vsock_common_realize(VirtIODevice *vdev) > > /* Receive and transmit queues belong to vhost */ > vvc->recv_vq = virtio_add_queue(vdev, VHOST_VSOCK_QUEUE_SIZE, > - vhost_vsock_common_handle_output); > + vhost_vsock_common_handle_output, > + &error_abort); > vvc->trans_vq = virtio_add_queue(vdev, VHOST_VSOCK_QUEUE_SIZE, > - vhost_vsock_common_handle_output); > + vhost_vsock_common_handle_output, > + &error_abort); > > /* The event queue belongs to QEMU */ > vvc->event_vq = virtio_add_queue(vdev, VHOST_VSOCK_QUEUE_SIZE, > - vhost_vsock_common_handle_output); > + vhost_vsock_common_handle_output, > + &error_abort); > > vvc->vhost_dev.nvqs = ARRAY_SIZE(vvc->vhost_vqs); > vvc->vhost_dev.vqs = vvc->vhost_vqs; > diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c > index 4c5f486ba23..3aca375d5c6 100644 > --- a/hw/virtio/virtio-balloon.c > +++ b/hw/virtio/virtio-balloon.c > @@ -887,13 +887,17 @@ 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); > > if (virtio_has_feature(s->host_features, VIRTIO_BALLOON_F_FREE_PAGE_HINT)) { > s->free_page_vq = virtio_add_queue(vdev, VIRTQUEUE_MAX_SIZE, > - virtio_balloon_handle_free_page_vq); > + virtio_balloon_handle_free_page_vq, > + &error_abort); > precopy_add_notifier(&s->free_page_hint_notify); > > object_ref(OBJECT(s->iothread)); > @@ -904,7 +908,8 @@ static void virtio_balloon_device_realize(DeviceState *dev, Error **errp) > > if (virtio_has_feature(s->host_features, VIRTIO_BALLOON_F_REPORTING)) { > s->reporting_vq = virtio_add_queue(vdev, 32, > - virtio_balloon_handle_report); > + virtio_balloon_handle_report, > + &error_abort); > } > > reset_stats(s); > diff --git a/hw/virtio/virtio-crypto.c b/hw/virtio/virtio-crypto.c > index 79e2acb56cc..b65ec611163 100644 > --- a/hw/virtio/virtio-crypto.c > +++ b/hw/virtio/virtio-crypto.c > @@ -1091,14 +1091,16 @@ static void virtio_crypto_device_realize(DeviceState *dev, Error **errp) > vcrypto->vqs = g_new0(VirtIOCryptoQueue, vcrypto->max_queues); > for (i = 0; i < vcrypto->max_queues; i++) { > vcrypto->vqs[i].dataq = > - virtio_add_queue(vdev, 1024, virtio_crypto_handle_dataq_bh); > + virtio_add_queue(vdev, 1024, virtio_crypto_handle_dataq_bh, > + &error_abort); > vcrypto->vqs[i].dataq_bh = > virtio_bh_new_guarded(dev, virtio_crypto_dataq_bh, > &vcrypto->vqs[i]); > vcrypto->vqs[i].vcrypto = vcrypto; > } > > - vcrypto->ctrl_vq = virtio_add_queue(vdev, 1024, virtio_crypto_handle_ctrl); > + vcrypto->ctrl_vq = virtio_add_queue(vdev, 1024, virtio_crypto_handle_ctrl, > + &error_abort); > if (!cryptodev_backend_is_ready(vcrypto->cryptodev)) { > vcrypto->status &= ~VIRTIO_CRYPTO_S_HW_READY; > } else { > diff --git a/hw/virtio/virtio-iommu.c b/hw/virtio/virtio-iommu.c > index 533bd5073f2..c2ccdd87889 100644 > --- a/hw/virtio/virtio-iommu.c > +++ b/hw/virtio/virtio-iommu.c > @@ -1433,8 +1433,10 @@ static void virtio_iommu_device_realize(DeviceState *dev, Error **errp) > virtio_init(vdev, VIRTIO_ID_IOMMU, sizeof(struct virtio_iommu_config)); > > s->req_vq = virtio_add_queue(vdev, VIOMMU_DEFAULT_QUEUE_SIZE, > - virtio_iommu_handle_command); > - s->event_vq = virtio_add_queue(vdev, VIOMMU_DEFAULT_QUEUE_SIZE, NULL); > + virtio_iommu_handle_command, > + &error_abort); > + s->event_vq = virtio_add_queue(vdev, VIOMMU_DEFAULT_QUEUE_SIZE, NULL, > + &error_abort); > s->cmd_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL_RT, > virtio_iommu_handle_command_timer, s); > > diff --git a/hw/virtio/virtio-mem.c b/hw/virtio/virtio-mem.c > index 35e03ed7599..1c79bc75c13 100644 > --- a/hw/virtio/virtio-mem.c > +++ b/hw/virtio/virtio-mem.c > @@ -966,7 +966,8 @@ static void virtio_mem_device_realize(DeviceState *dev, Error **errp) > vmem->bitmap = bitmap_new(vmem->bitmap_size); > > virtio_init(vdev, VIRTIO_ID_MEM, sizeof(struct virtio_mem_config)); > - vmem->vq = virtio_add_queue(vdev, 128, virtio_mem_handle_request); > + vmem->vq = virtio_add_queue(vdev, 128, virtio_mem_handle_request, > + &error_abort); > > /* > * With "dynamic-memslots=off" (old behavior) we always map the whole > diff --git a/hw/virtio/virtio-nsm.c b/hw/virtio/virtio-nsm.c > index 3bf5e7009a4..6fc3fbb5852 100644 > --- a/hw/virtio/virtio-nsm.c > +++ b/hw/virtio/virtio-nsm.c > @@ -1660,7 +1660,7 @@ static void virtio_nsm_device_realize(DeviceState *dev, Error **errp) > > virtio_init(vdev, VIRTIO_ID_NITRO_SEC_MOD, 0); > > - vnsm->vq = virtio_add_queue(vdev, 2, handle_input); > + vnsm->vq = virtio_add_queue(vdev, 2, handle_input, &error_abort); > } > > static void virtio_nsm_device_unrealize(DeviceState *dev) > diff --git a/hw/virtio/virtio-pmem.c b/hw/virtio/virtio-pmem.c > index 6f7271c140a..ac7952bbf4f 100644 > --- a/hw/virtio/virtio-pmem.c > +++ b/hw/virtio/virtio-pmem.c > @@ -129,7 +129,7 @@ static void virtio_pmem_realize(DeviceState *dev, Error **errp) > > host_memory_backend_set_mapped(pmem->memdev, true); > virtio_init(vdev, VIRTIO_ID_PMEM, sizeof(struct virtio_pmem_config)); > - pmem->rq_vq = virtio_add_queue(vdev, 128, virtio_pmem_flush); > + pmem->rq_vq = virtio_add_queue(vdev, 128, virtio_pmem_flush, &error_abort); > pmem->inflight = 1; > } > > diff --git a/hw/virtio/virtio-rng.c b/hw/virtio/virtio-rng.c > index d68d9011953..b3136431252 100644 > --- a/hw/virtio/virtio-rng.c > +++ b/hw/virtio/virtio-rng.c > @@ -219,7 +219,7 @@ static void virtio_rng_device_realize(DeviceState *dev, Error **errp) > > virtio_init(vdev, 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, > check_rate_limit, vrng); > diff --git a/hw/virtio/virtio-rtc.c b/hw/virtio/virtio-rtc.c > index 32de9c16503..3bd488bc7ba 100644 > --- a/hw/virtio/virtio-rtc.c > +++ b/hw/virtio/virtio-rtc.c > @@ -135,7 +135,8 @@ static void virtio_rtc_device_realize(DeviceState *dev, Error **errp) > VirtIORtc *vrtc = VIRTIO_RTC(dev); > > virtio_init(vdev, VIRTIO_ID_CLOCK, 0); > - vrtc->vq = virtio_add_queue(vdev, 64, virtio_rtc_handle_request); > + vrtc->vq = virtio_add_queue(vdev, 64, virtio_rtc_handle_request, > + &error_abort); > } > > static void virtio_rtc_device_unrealize(DeviceState *dev) > diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c > index e1210f024c6..629eadeb74b 100644 > --- a/hw/virtio/virtio.c > +++ b/hw/virtio/virtio.c > @@ -2565,8 +2565,9 @@ void virtio_queue_set_vector(VirtIODevice *vdev, int n, uint16_t vector) > } > > VirtQueue *virtio_add_queue(VirtIODevice *vdev, unsigned int queue_size, > - VirtIOHandleOutput handle_output) > + VirtIOHandleOutput handle_output, Error **errp) > { > + ERRP_GUARD(); > int i; > > for (i = 0; i < VIRTIO_QUEUE_MAX; i++) { > @@ -2574,15 +2575,43 @@ VirtQueue *virtio_add_queue(VirtIODevice *vdev, unsigned int queue_size, > break; > } > > - if (i == VIRTIO_QUEUE_MAX || queue_size > VIRTQUEUE_MAX_SIZE) > - abort(); > + if (i == VIRTIO_QUEUE_MAX) { > + error_setg(errp, "Exceeded maximum number of virtqueues (%d)", i); > + return NULL; > + } > + > + if (queue_size > VIRTQUEUE_MAX_SIZE) { > + error_setg(errp, "Virtqueue size %u exceeds the max (%u)", > + queue_size, VIRTQUEUE_MAX_SIZE); > + return NULL; > + } > > BusState *qbus = qdev_get_parent_bus(DEVICE(vdev)); > if (qbus && qbus->parent && > object_property_find(OBJECT(qbus->parent), VIRTIO_QUEUE_SIZE_OVERRIDE)) { > int override = object_property_get_int(OBJECT(qbus->parent), > VIRTIO_QUEUE_SIZE_OVERRIDE, > - &error_abort); > + errp); > + > + if (*errp) { > + return NULL; > + } > + if (override < 0) { > + /* > + * The property type should be UINT16, so this can't happen, but > + * help out Coverity. > + */ > + error_setg(errp, "%s (%d) cannot be negative", > + VIRTIO_QUEUE_SIZE_OVERRIDE, override); > + return NULL; > + } > + if (override > VIRTQUEUE_MAX_SIZE) { > + error_setg(errp, "%s (%d) exceeds the max (%d)", > + VIRTIO_QUEUE_SIZE_OVERRIDE, override, > + VIRTQUEUE_MAX_SIZE); > + return NULL; > + } > + > if (override) { > queue_size = override; > }