virtio: improve virtqueue mapping error messages

Improve error reporting when virtqueue ring mapping fails by including a
device identifier in the error message.

Introduce a helper qdev_get_printable_name() in qdev-core, which returns
either:

 - the device ID, if explicitly provided (e.g. -device ...,id=foo)
 - the QOM path from qdev_get_dev_path(dev) otherwise
 - "<unknown device>" as a fallback when no identifier is present

This makes it easier to identify which device triggered the error in
multi-device setups or when debugging complex guest configurations.

Resolves: https://gitlab.com/qemu-project/qemu/-/issues/230
Buglink: https://bugs.launchpad.net/qemu/+bug/1919021
Suggested-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Alessandro Ratti <alessandro@0x65c.net>
Message-Id: <20250924093138.559872-2-alessandro@0x65c.net>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
This commit is contained in:
Alessandro Ratti
2025-10-05 16:19:12 -04:00
committed by Michael S. Tsirkin
parent 5c1ded52ac
commit e209d4d7a3
3 changed files with 42 additions and 3 deletions
+29
View File
@@ -411,6 +411,35 @@ char *qdev_get_dev_path(DeviceState *dev)
return NULL;
}
const char *qdev_get_printable_name(DeviceState *vdev)
{
/*
* Return device ID if explicity set
* (e.g. -device virtio-blk-pci,id=foo)
* This allows users to correlate errors with their custom device
* names.
*/
if (vdev->id) {
return vdev->id;
}
/*
* Fall back to the canonical QOM device path (eg. ID for PCI
* devices).
* This ensures the device is still uniquely and meaningfully
* identified.
*/
const char *path = qdev_get_dev_path(vdev);
if (path) {
return path;
}
/*
* Final fallback: if all else fails, return a placeholder string.
* This ensures the error message always contains a valid string.
*/
return "<unknown device>";
}
void qdev_add_unplug_blocker(DeviceState *dev, Error *reason)
{
dev->unplug_blockers = g_slist_prepend(dev->unplug_blockers, reason);
+12 -3
View File
@@ -257,7 +257,10 @@ void virtio_init_region_cache(VirtIODevice *vdev, int n)
len = address_space_cache_init(&new->desc, vdev->dma_as,
addr, size, packed);
if (len < size) {
virtio_error(vdev, "Cannot map desc");
virtio_error(vdev,
"Failed to map descriptor ring for device %s: "
"invalid guest physical address or corrupted queue setup",
qdev_get_printable_name(DEVICE(vdev)));
goto err_desc;
}
@@ -265,7 +268,10 @@ void virtio_init_region_cache(VirtIODevice *vdev, int n)
len = address_space_cache_init(&new->used, vdev->dma_as,
vq->vring.used, size, true);
if (len < size) {
virtio_error(vdev, "Cannot map used");
virtio_error(vdev,
"Failed to map used ring for device %s: "
"possible guest misconfiguration or insufficient memory",
qdev_get_printable_name(DEVICE(vdev)));
goto err_used;
}
@@ -273,7 +279,10 @@ void virtio_init_region_cache(VirtIODevice *vdev, int n)
len = address_space_cache_init(&new->avail, vdev->dma_as,
vq->vring.avail, size, false);
if (len < size) {
virtio_error(vdev, "Cannot map avail");
virtio_error(vdev,
"Failed to map avalaible ring for device %s: "
"possible queue misconfiguration or overlapping memory region",
qdev_get_printable_name(DEVICE(vdev)));
goto err_avail;
}
+1
View File
@@ -1064,6 +1064,7 @@ bool qdev_set_parent_bus(DeviceState *dev, BusState *bus, Error **errp);
extern bool qdev_hot_removed;
char *qdev_get_dev_path(DeviceState *dev);
const char *qdev_get_printable_name(DeviceState *dev);
void qbus_set_hotplug_handler(BusState *bus, Object *handler);
void qbus_set_bus_hotplug_handler(BusState *bus);