diff mbox series

[2/2] hw/display: Allow injection of virtio-gpu EDID name

Message ID 20241017215304.3916866-3-roqueh@google.com (mailing list archive)
State New
Headers show
Series Allow injection of virtio-gpu EDID name | expand

Commit Message

Roque Arcudia Hernandez Oct. 17, 2024, 9:53 p.m. UTC
From: Andrew Keesler <ankeesler@google.com>

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 display configuration as that most closely resembles how
real displays work (hardware displays contain static EDID information that is
provided to every connected host).

This new behavior must be enabled by setting the edid_name boolean property on
the display device (it is disabled by default).

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,name=AAA \
  -display vnc=localhost:1,id=bbb,display=vga,head=1,name=BBB \
  -device virtio-vga,max_outputs=2,id=vga,edid_name=true

Signed-off-by: Andrew Keesler <ankeesler@google.com>
Signed-off-by: Roque Arcudia Hernandez <roqueh@google.com>
---
 hw/display/virtio-gpu-base.c   | 4 ++++
 include/hw/virtio/virtio-gpu.h | 5 +++++
 include/ui/console.h           | 1 +
 ui/console.c                   | 8 ++++++++
 4 files changed, 18 insertions(+)
diff mbox series

Patch

diff --git a/hw/display/virtio-gpu-base.c b/hw/display/virtio-gpu-base.c
index 4fc7ef8896..778b798c45 100644
--- a/hw/display/virtio-gpu-base.c
+++ b/hw/display/virtio-gpu-base.c
@@ -64,6 +64,10 @@  virtio_gpu_base_generate_edid(VirtIOGPUBase *g, int scanout,
         .refresh_rate = g->req_state[scanout].refresh_rate,
     };
 
+    if (virtio_gpu_edid_name_enabled(g->conf)) {
+        info.name = qemu_console_get_name(g->scanout[scanout].con, NULL);
+    }
+
     edid->size = cpu_to_le32(sizeof(edid->edid));
     qemu_edid_generate(edid->edid, sizeof(edid->edid), &info);
 }
diff --git a/include/hw/virtio/virtio-gpu.h b/include/hw/virtio/virtio-gpu.h
index e343110e23..186355d0b9 100644
--- a/include/hw/virtio/virtio-gpu.h
+++ b/include/hw/virtio/virtio-gpu.h
@@ -97,6 +97,7 @@  enum virtio_gpu_base_conf_flags {
     VIRTIO_GPU_FLAG_BLOB_ENABLED,
     VIRTIO_GPU_FLAG_CONTEXT_INIT_ENABLED,
     VIRTIO_GPU_FLAG_RUTABAGA_ENABLED,
+    VIRTIO_GPU_FLAG_EDID_NAME_ENABLED,
 };
 
 #define virtio_gpu_virgl_enabled(_cfg) \
@@ -115,6 +116,8 @@  enum virtio_gpu_base_conf_flags {
     (_cfg.flags & (1 << VIRTIO_GPU_FLAG_RUTABAGA_ENABLED))
 #define virtio_gpu_hostmem_enabled(_cfg) \
     (_cfg.hostmem > 0)
+#define virtio_gpu_edid_name_enabled(_cfg) \
+    (_cfg.flags & (1 << VIRTIO_GPU_FLAG_EDID_NAME_ENABLED))
 
 struct virtio_gpu_base_conf {
     uint32_t max_outputs;
@@ -163,6 +166,8 @@  struct VirtIOGPUBaseClass {
     DEFINE_PROP_UINT32("max_outputs", _state, _conf.max_outputs, 1),    \
     DEFINE_PROP_BIT("edid", _state, _conf.flags, \
                     VIRTIO_GPU_FLAG_EDID_ENABLED, true), \
+    DEFINE_PROP_BIT("edid_name", _state, _conf.flags, \
+                    VIRTIO_GPU_FLAG_EDID_NAME_ENABLED, false), \
     DEFINE_PROP_UINT32("xres", _state, _conf.xres, 1280), \
     DEFINE_PROP_UINT32("yres", _state, _conf.yres, 800)
 
diff --git a/include/ui/console.h b/include/ui/console.h
index 74ab03ed72..ce90802e0e 100644
--- a/include/ui/console.h
+++ b/include/ui/console.h
@@ -408,6 +408,7 @@  int qemu_console_get_index(QemuConsole *con);
 uint32_t qemu_console_get_head(QemuConsole *con);
 int qemu_console_get_width(QemuConsole *con, int fallback);
 int qemu_console_get_height(QemuConsole *con, int fallback);
+const char *qemu_console_get_name(QemuConsole *con, const char *fallback);
 void qemu_console_set_name(QemuConsole *con, const char *name);
 /* Return the low-level window id for the console */
 int qemu_console_get_window_id(QemuConsole *con);
diff --git a/ui/console.c b/ui/console.c
index f377fd8417..329688858e 100644
--- a/ui/console.c
+++ b/ui/console.c
@@ -1452,6 +1452,14 @@  int qemu_console_get_height(QemuConsole *con, int fallback)
     }
 }
 
+const char *qemu_console_get_name(QemuConsole *con, const char *fallback)
+{
+    if (con == NULL) {
+        return fallback;
+    }
+    return con->name;
+}
+
 void qemu_console_set_name(QemuConsole *con, const char *name)
 {
     if (con == NULL) {