Hi
On Tue, Jul 8, 2025 at 9:07 PM Andrew Keesler wrote:
>
> Thanks to 72d277a7, 1ed2cb32, and others, EDID (Extended Display
> Identification Data) is propagated by QEMU such that a virtual display
> presents legitimate metadata (e.g., name, serial number, preferred
> resolutions, etc.) to its connected guest.
>
> This change adds the ability to specify the EDID name for a particular
> virtio-vga display. Previously, every virtual display would have the same
> name: "QEMU Monitor". Now, we can inject names of displays in order to test
> guest behavior that is specific to display names. We provide the ability to
> inject the display name from the frontend since this is guest visible
> data. Furthermore, this makes it clear where N potential display outputs
> would get their name from (which will be added in a future change).
>
> Note that we have elected to use a struct here for output data for
> extensibility - we intend to add per-output fields like resolution in a
> future change.
>
> It should be noted that EDID names longer than 12 bytes will be truncated
> per spec (I think?).
>
> Testing: verified that when I specified 2 outputs for a virtio-gpu with
> edid_name set, the names matched those that I configured with my vnc
> display.
>
> -display vnc=localhost:0,id=aaa,display=vga,head=0 \
> -display vnc=localhost:1,id=bbb,display=vga,head=1 \
> -device '{"driver":"virtio-vga",
> "max_outputs":2,
> "id":"vga",
> "outputs":[
> {
> "name":"AAA",
> },
> {
> "name":"BBB",
> }
> ]}'
>
(there are still invalid trailing ',' in this example)
Reviewed-by: Marc-André Lureau
> Signed-off-by: Andrew Keesler
> ---
> hw/core/qdev-properties-system.c| 44 +
> hw/display/virtio-gpu-base.c| 27 ++
> include/hw/display/edid.h | 2 ++
> include/hw/qdev-properties-system.h | 5
> include/hw/virtio/virtio-gpu.h | 3 ++
> qapi/virtio.json| 18 ++--
> 6 files changed, 97 insertions(+), 2 deletions(-)
>
> diff --git a/hw/core/qdev-properties-system.c
> b/hw/core/qdev-properties-system.c
> index 24e145d870..1f810b7ddf 100644
> --- a/hw/core/qdev-properties-system.c
> +++ b/hw/core/qdev-properties-system.c
> @@ -1299,3 +1299,47 @@ const PropertyInfo
> qdev_prop_vmapple_virtio_blk_variant = {
> .set = qdev_propinfo_set_enum,
> .set_default_value = qdev_propinfo_set_default_value_enum,
> };
> +
> +/* --- VirtIOGPUOutputList --- */
> +
> +static void get_virtio_gpu_output_list(Object *obj, Visitor *v,
> +const char *name, void *opaque, Error **errp)
> +{
> +VirtIOGPUOutputList **prop_ptr =
> +object_field_prop_ptr(obj, opaque);
> +
> +visit_type_VirtIOGPUOutputList(v, name, prop_ptr, errp);
> +}
> +
> +static void set_virtio_gpu_output_list(Object *obj, Visitor *v,
> +const char *name, void *opaque, Error **errp)
> +{
> +VirtIOGPUOutputList **prop_ptr =
> +object_field_prop_ptr(obj, opaque);
> +VirtIOGPUOutputList *list;
> +
> +if (!visit_type_VirtIOGPUOutputList(v, name, &list, errp)) {
> +return;
> +}
> +
> +qapi_free_VirtIOGPUOutputList(*prop_ptr);
> +*prop_ptr = list;
> +}
> +
> +static void release_virtio_gpu_output_list(Object *obj,
> +const char *name, void *opaque)
> +{
> +VirtIOGPUOutputList **prop_ptr =
> +object_field_prop_ptr(obj, opaque);
> +
> +qapi_free_VirtIOGPUOutputList(*prop_ptr);
> +*prop_ptr = NULL;
> +}
> +
> +const PropertyInfo qdev_prop_virtio_gpu_output_list = {
> +.type = "VirtIOGPUOutputList",
> +.description = "VirtIO GPU output list [{\"name\":\"\"},...]",
> +.get = get_virtio_gpu_output_list,
> +.set = set_virtio_gpu_output_list,
> +.release = release_virtio_gpu_output_list,
> +};
> diff --git a/hw/display/virtio-gpu-base.c b/hw/display/virtio-gpu-base.c
> index 9eb806b71f..7269477a1c 100644
> --- a/hw/display/virtio-gpu-base.c
> +++ b/hw/display/virtio-gpu-base.c
> @@ -19,6 +19,7 @@
> #include "qemu/error-report.h"
> #include "hw/display/edid.h"
> #include "trace.h"
> +#include "qapi/qapi-types-virtio.h"
>
> void
> virtio_gpu_base_reset(VirtIOGPUBase *g)
> @@ -56,6 +57,8 @@ void
> virtio_gpu_base_generate_edid(VirtIOGPUBase *g, int scanout,
>struct virtio_gpu_resp_edid *edid)
> {
> +size_t output_idx;
> +VirtIOGPUOutputList *node;
> qemu_edid_info info = {
> .width_mm = g->req_state[scanout].width_mm,
> .height_mm = g->req_state[scanout].height_mm,
> @@ -64,6 +67,14 @@ virtio_gpu_base_generate_edid(VirtIOGPUBase *g, int
> scanout,
> .refresh_rate = g->req_state[scanout].refresh_rate,
> };
>
> +for (output_idx = 0, node = g->conf.outputs;
> + output_idx <= scanout && node; output_idx++, node = node->next) {
> +if (output_id