diff --git a/hw/core/qdev.c b/hw/core/qdev.c index fc3425a8fe..e48616b2c6 100644 --- a/hw/core/qdev.c +++ b/hw/core/qdev.c @@ -420,7 +420,7 @@ const char *qdev_get_printable_name(DeviceState *vdev) * names. */ if (vdev->id) { - return vdev->id; + return g_strdup(vdev->id); } /* * Fall back to the canonical QOM device path (eg. ID for PCI @@ -437,7 +437,7 @@ const char *qdev_get_printable_name(DeviceState *vdev) * Final fallback: if all else fails, return a placeholder string. * This ensures the error message always contains a valid string. */ - return ""; + return g_strdup(""); } void qdev_add_unplug_blocker(DeviceState *dev, Error *reason) diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c index 4c5a4479bf..0ba734d0bc 100644 --- a/hw/virtio/virtio.c +++ b/hw/virtio/virtio.c @@ -281,10 +281,12 @@ 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) { + g_autofree const char *devname = qdev_get_printable_name(DEVICE(vdev)); + 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))); + devname); goto err_desc; } @@ -292,10 +294,12 @@ 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) { + g_autofree const char *devname = qdev_get_printable_name(DEVICE(vdev)); + virtio_error(vdev, "Failed to map used ring for device %s: " "possible guest misconfiguration or insufficient memory", - qdev_get_printable_name(DEVICE(vdev))); + devname); goto err_used; } @@ -303,10 +307,12 @@ 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) { + g_autofree const char *devname = qdev_get_printable_name(DEVICE(vdev)); + virtio_error(vdev, "Failed to map avalaible ring for device %s: " "possible queue misconfiguration or overlapping memory region", - qdev_get_printable_name(DEVICE(vdev))); + devname); goto err_avail; } diff --git a/include/hw/core/qdev.h b/include/hw/core/qdev.h index 29083bc907..f99a8979cc 100644 --- a/include/hw/core/qdev.h +++ b/include/hw/core/qdev.h @@ -1084,6 +1084,22 @@ extern bool qdev_hot_removed; * If @dev is NULL or not on a bus, returns NULL. */ char *qdev_get_dev_path(DeviceState *dev); + +/** + * qdev_get_printable_name: Return human readable name for device + * @dev: Device to get name of + * + * Returns: A newly allocated string containing some human + * readable name for the device, suitable for printing in + * user-facing error messages. The function will never return NULL, + * so the name can be used without further checking or fallbacks. + * + * If the device has an explicitly set ID (e.g. by the user on the + * command line via "-device thisdev,id=myid") this is preferred. + * Otherwise we try the canonical QOM device path (which will be + * the PCI ID for PCI devices, for example). If all else fails + * we will return the placeholder ". + */ const char *qdev_get_printable_name(DeviceState *dev); void qbus_set_hotplug_handler(BusState *bus, Object *handler);