From nobody Fri May 3 15:27:53 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 15523332304161001.5015515621744; Mon, 11 Mar 2019 12:40:30 -0700 (PDT) Received: from localhost ([127.0.0.1]:39167 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h3Qmg-000584-6F for importer@patchew.org; Mon, 11 Mar 2019 15:40:26 -0400 Received: from eggs.gnu.org ([209.51.188.92]:34199) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h3Qaf-000408-Iy for qemu-devel@nongnu.org; Mon, 11 Mar 2019 15:28:02 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1h3QVp-0005Hw-MC for qemu-devel@nongnu.org; Mon, 11 Mar 2019 15:23:02 -0400 Received: from mx1.redhat.com ([209.132.183.28]:45207) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1h3QVp-0005HD-9I for qemu-devel@nongnu.org; Mon, 11 Mar 2019 15:23:01 -0400 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 1957981F31 for ; Mon, 11 Mar 2019 19:23:00 +0000 (UTC) Received: from gimli.home (ovpn-116-24.phx2.redhat.com [10.3.116.24]) by smtp.corp.redhat.com (Postfix) with ESMTP id CEB7C1001E6E; Mon, 11 Mar 2019 19:22:57 +0000 (UTC) From: Alex Williamson To: qemu-devel@nongnu.org Date: Mon, 11 Mar 2019 13:22:57 -0600 Message-ID: <155233217766.8141.3600946038669106048.stgit@gimli.home> In-Reply-To: <155233206671.8141.2579745444621332750.stgit@gimli.home> References: <155233206671.8141.2579745444621332750.stgit@gimli.home> User-Agent: StGit/0.19-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.27]); Mon, 11 Mar 2019 19:23:00 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL 1/3] vfio/display: add edid support. X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" From: Gerd Hoffmann This patch adds EDID support to the vfio display (aka vgpu) code. When supported by the mdev driver qemu will generate a EDID blob and pass it on using the new vfio edid region. The EDID blob will be updated on UI changes (i.e. window resize), so the guest can adapt. Signed-off-by: Gerd Hoffmann Reviewed-by: Liam Merwick [remove control flow via macro, use unsigned format specifier] Signed-off-by: Alex Williamson --- hw/vfio/display.c | 141 +++++++++++++++++++++++++++++++++++++= ++++ hw/vfio/trace-events | 7 ++ include/hw/vfio/vfio-common.h | 3 + 3 files changed, 151 insertions(+) diff --git a/hw/vfio/display.c b/hw/vfio/display.c index dead30e626cb..276fba090d8b 100644 --- a/hw/vfio/display.c +++ b/hw/vfio/display.c @@ -15,15 +15,153 @@ #include =20 #include "sysemu/sysemu.h" +#include "hw/display/edid.h" #include "ui/console.h" #include "qapi/error.h" #include "pci.h" +#include "trace.h" =20 #ifndef DRM_PLANE_TYPE_PRIMARY # define DRM_PLANE_TYPE_PRIMARY 1 # define DRM_PLANE_TYPE_CURSOR 2 #endif =20 +#define pread_field(_fd, _reg, _ptr, _fld) \ + (sizeof(_ptr->_fld) !=3D \ + pread(_fd, &(_ptr->_fld), sizeof(_ptr->_fld), \ + _reg->offset + offsetof(typeof(*_ptr), _fld))) + +#define pwrite_field(_fd, _reg, _ptr, _fld) \ + (sizeof(_ptr->_fld) !=3D \ + pwrite(_fd, &(_ptr->_fld), sizeof(_ptr->_fld), \ + _reg->offset + offsetof(typeof(*_ptr), _fld))) + + +static void vfio_display_edid_update(VFIOPCIDevice *vdev, bool enabled, + int prefx, int prefy) +{ + VFIODisplay *dpy =3D vdev->dpy; + int fd =3D vdev->vbasedev.fd; + qemu_edid_info edid =3D { + .maxx =3D dpy->edid_regs->max_xres, + .maxy =3D dpy->edid_regs->max_yres, + .prefx =3D prefx, + .prefy =3D prefy, + }; + + dpy->edid_regs->link_state =3D VFIO_DEVICE_GFX_LINK_STATE_DOWN; + if (pwrite_field(fd, dpy->edid_info, dpy->edid_regs, link_state)) { + goto err; + } + trace_vfio_display_edid_link_down(); + + if (!enabled) { + return; + } + + if (edid.maxx && edid.prefx > edid.maxx) { + edid.prefx =3D edid.maxx; + } + if (edid.maxy && edid.prefy > edid.maxy) { + edid.prefy =3D edid.maxy; + } + qemu_edid_generate(dpy->edid_blob, + dpy->edid_regs->edid_max_size, + &edid); + trace_vfio_display_edid_update(edid.prefx, edid.prefy); + + dpy->edid_regs->edid_size =3D qemu_edid_size(dpy->edid_blob); + if (pwrite_field(fd, dpy->edid_info, dpy->edid_regs, edid_size)) { + goto err; + } + if (pwrite(fd, dpy->edid_blob, dpy->edid_regs->edid_size, + dpy->edid_info->offset + dpy->edid_regs->edid_offset) + !=3D dpy->edid_regs->edid_size) { + goto err; + } + + dpy->edid_regs->link_state =3D VFIO_DEVICE_GFX_LINK_STATE_UP; + if (pwrite_field(fd, dpy->edid_info, dpy->edid_regs, link_state)) { + goto err; + } + trace_vfio_display_edid_link_up(); + return; + +err: + trace_vfio_display_edid_write_error(); + return; +} + +static int vfio_display_edid_ui_info(void *opaque, uint32_t idx, + QemuUIInfo *info) +{ + VFIOPCIDevice *vdev =3D opaque; + VFIODisplay *dpy =3D vdev->dpy; + + if (!dpy->edid_regs) { + return 0; + } + + if (info->width && info->height) { + vfio_display_edid_update(vdev, true, info->width, info->height); + } else { + vfio_display_edid_update(vdev, false, 0, 0); + } + + return 0; +} + +static void vfio_display_edid_init(VFIOPCIDevice *vdev) +{ + VFIODisplay *dpy =3D vdev->dpy; + int fd =3D vdev->vbasedev.fd; + int ret; + + ret =3D vfio_get_dev_region_info(&vdev->vbasedev, + VFIO_REGION_TYPE_GFX, + VFIO_REGION_SUBTYPE_GFX_EDID, + &dpy->edid_info); + if (ret) { + return; + } + + trace_vfio_display_edid_available(); + dpy->edid_regs =3D g_new0(struct vfio_region_gfx_edid, 1); + if (pread_field(fd, dpy->edid_info, dpy->edid_regs, edid_offset)) { + goto err; + } + if (pread_field(fd, dpy->edid_info, dpy->edid_regs, edid_max_size)) { + goto err; + } + if (pread_field(fd, dpy->edid_info, dpy->edid_regs, max_xres)) { + goto err; + } + if (pread_field(fd, dpy->edid_info, dpy->edid_regs, max_yres)) { + goto err; + } + + dpy->edid_blob =3D g_malloc0(dpy->edid_regs->edid_max_size); + + vfio_display_edid_update(vdev, true, 0, 0); + return; + +err: + trace_vfio_display_edid_write_error(); + g_free(dpy->edid_regs); + dpy->edid_regs =3D NULL; + return; +} + +static void vfio_display_edid_exit(VFIODisplay *dpy) +{ + if (!dpy->edid_regs) { + return; + } + + g_free(dpy->edid_regs); + g_free(dpy->edid_blob); +} + static void vfio_display_update_cursor(VFIODMABuf *dmabuf, struct vfio_device_gfx_plane_info *= plane) { @@ -171,6 +309,7 @@ static void vfio_display_dmabuf_update(void *opaque) =20 static const GraphicHwOps vfio_display_dmabuf_ops =3D { .gfx_update =3D vfio_display_dmabuf_update, + .ui_info =3D vfio_display_edid_ui_info, }; =20 static int vfio_display_dmabuf_init(VFIOPCIDevice *vdev, Error **errp) @@ -187,6 +326,7 @@ static int vfio_display_dmabuf_init(VFIOPCIDevice *vdev= , Error **errp) if (vdev->enable_ramfb) { vdev->dpy->ramfb =3D ramfb_setup(errp); } + vfio_display_edid_init(vdev); return 0; } =20 @@ -366,5 +506,6 @@ void vfio_display_finalize(VFIOPCIDevice *vdev) graphic_console_close(vdev->dpy->con); vfio_display_dmabuf_exit(vdev->dpy); vfio_display_region_exit(vdev->dpy); + vfio_display_edid_exit(vdev->dpy); g_free(vdev->dpy); } diff --git a/hw/vfio/trace-events b/hw/vfio/trace-events index ed2f333ad726..decbde495ac2 100644 --- a/hw/vfio/trace-events +++ b/hw/vfio/trace-events @@ -132,3 +132,10 @@ vfio_prereg_unregister(uint64_t va, uint64_t size, int= ret) "va=3D0x%"PRIx64" size vfio_spapr_create_window(int ps, uint64_t ws, uint64_t off) "pageshift=3D0= x%x winsize=3D0x%"PRIx64" offset=3D0x%"PRIx64 vfio_spapr_remove_window(uint64_t off) "offset=3D0x%"PRIx64 vfio_spapr_group_attach(int groupfd, int tablefd) "Attached groupfd %d to = liobn fd %d" + +# hw/vfio/display.c +vfio_display_edid_available(void) "" +vfio_display_edid_link_up(void) "" +vfio_display_edid_link_down(void) "" +vfio_display_edid_update(uint32_t prefx, uint32_t prefy) "%ux%u" +vfio_display_edid_write_error(void) "" diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h index 7624c9f511c4..5f7f709b95f1 100644 --- a/include/hw/vfio/vfio-common.h +++ b/include/hw/vfio/vfio-common.h @@ -148,6 +148,9 @@ typedef struct VFIODMABuf { typedef struct VFIODisplay { QemuConsole *con; RAMFBState *ramfb; + struct vfio_region_info *edid_info; + struct vfio_region_gfx_edid *edid_regs; + uint8_t *edid_blob; struct { VFIORegion buffer; DisplaySurface *surface; From nobody Fri May 3 15:27:53 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1552332656309705.0992395560091; Mon, 11 Mar 2019 12:30:56 -0700 (PDT) Received: from localhost ([127.0.0.1]:39047 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h3QdR-0005uH-8f for importer@patchew.org; Mon, 11 Mar 2019 15:30:53 -0400 Received: from eggs.gnu.org ([209.51.188.92]:34252) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h3Qaf-00042z-14 for qemu-devel@nongnu.org; Mon, 11 Mar 2019 15:28:01 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1h3QVx-0005Oc-Kn for qemu-devel@nongnu.org; Mon, 11 Mar 2019 15:23:10 -0400 Received: from mx1.redhat.com ([209.132.183.28]:53376) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1h3QVx-0005Nj-9D for qemu-devel@nongnu.org; Mon, 11 Mar 2019 15:23:09 -0400 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 7095F6696F for ; Mon, 11 Mar 2019 19:23:08 +0000 (UTC) Received: from gimli.home (ovpn-116-24.phx2.redhat.com [10.3.116.24]) by smtp.corp.redhat.com (Postfix) with ESMTP id 93E1D60BF1; Mon, 11 Mar 2019 19:23:05 +0000 (UTC) From: Alex Williamson To: qemu-devel@nongnu.org Date: Mon, 11 Mar 2019 13:23:05 -0600 Message-ID: <155233218516.8141.11063684664443124069.stgit@gimli.home> In-Reply-To: <155233206671.8141.2579745444621332750.stgit@gimli.home> References: <155233206671.8141.2579745444621332750.stgit@gimli.home> User-Agent: StGit/0.19-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.38]); Mon, 11 Mar 2019 19:23:08 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL 2/3] vfio/display: add xres + yres properties X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" From: Gerd Hoffmann This allows configure the display resolution which the vgpu should use. The information will be passed to the guest using EDID, so the mdev driver must support the vfio edid region for this to work. Signed-off-by: Gerd Hoffmann Reviewed-by: Liam Merwick Signed-off-by: Alex Williamson --- hw/vfio/display.c | 12 ++++++++++-- hw/vfio/pci.c | 12 ++++++++++++ hw/vfio/pci.h | 2 ++ 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/hw/vfio/display.c b/hw/vfio/display.c index 276fba090d8b..212ad1674ec1 100644 --- a/hw/vfio/display.c +++ b/hw/vfio/display.c @@ -45,8 +45,8 @@ static void vfio_display_edid_update(VFIOPCIDevice *vdev,= bool enabled, qemu_edid_info edid =3D { .maxx =3D dpy->edid_regs->max_xres, .maxy =3D dpy->edid_regs->max_yres, - .prefx =3D prefx, - .prefy =3D prefy, + .prefx =3D prefx ?: vdev->display_xres, + .prefy =3D prefy ?: vdev->display_yres, }; =20 dpy->edid_regs->link_state =3D VFIO_DEVICE_GFX_LINK_STATE_DOWN; @@ -142,6 +142,14 @@ static void vfio_display_edid_init(VFIOPCIDevice *vdev) =20 dpy->edid_blob =3D g_malloc0(dpy->edid_regs->edid_max_size); =20 + /* if xres + yres properties are unset use the maximum resolution */ + if (!vdev->display_xres) { + vdev->display_xres =3D dpy->edid_regs->max_xres; + } + if (!vdev->display_yres) { + vdev->display_yres =3D dpy->edid_regs->max_yres; + } + vfio_display_edid_update(vdev, true, 0, 0); return; =20 diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c index dd12f363915d..504019c4582b 100644 --- a/hw/vfio/pci.c +++ b/hw/vfio/pci.c @@ -3068,6 +3068,16 @@ static void vfio_realize(PCIDevice *pdev, Error **er= rp) error_setg(errp, "ramfb=3Don requires display=3Don"); goto out_teardown; } + if (vdev->display_xres || vdev->display_yres) { + if (vdev->dpy =3D=3D NULL) { + error_setg(errp, "xres and yres properties require display=3Do= n"); + goto out_teardown; + } + if (vdev->dpy->edid_regs =3D=3D NULL) { + error_setg(errp, "xres and yres properties need edid support"); + goto out_teardown; + } + } =20 vfio_register_err_notifier(vdev); vfio_register_req_notifier(vdev); @@ -3182,6 +3192,8 @@ static Property vfio_pci_dev_properties[] =3D { DEFINE_PROP_STRING("sysfsdev", VFIOPCIDevice, vbasedev.sysfsdev), DEFINE_PROP_ON_OFF_AUTO("display", VFIOPCIDevice, display, ON_OFF_AUTO_OFF), + DEFINE_PROP_UINT32("xres", VFIOPCIDevice, display_xres, 0), + DEFINE_PROP_UINT32("yres", VFIOPCIDevice, display_yres, 0), DEFINE_PROP_UINT32("x-intx-mmap-timeout-ms", VFIOPCIDevice, intx.mmap_timeout, 1100), DEFINE_PROP_BIT("x-vga", VFIOPCIDevice, features, diff --git a/hw/vfio/pci.h b/hw/vfio/pci.h index b1ae4c07549a..c11c3f167070 100644 --- a/hw/vfio/pci.h +++ b/hw/vfio/pci.h @@ -149,6 +149,8 @@ typedef struct VFIOPCIDevice { #define VFIO_FEATURE_ENABLE_IGD_OPREGION \ (1 << VFIO_FEATURE_ENABLE_IGD_OPREGION_BIT) OnOffAuto display; + uint32_t display_xres; + uint32_t display_yres; int32_t bootindex; uint32_t igd_gms; OffAutoPCIBAR msix_relo; From nobody Fri May 3 15:27:53 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 155233305801842.36463053625971; Mon, 11 Mar 2019 12:37:38 -0700 (PDT) Received: from localhost ([127.0.0.1]:39137 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h3Qjr-0002h7-Ma for importer@patchew.org; Mon, 11 Mar 2019 15:37:31 -0400 Received: from eggs.gnu.org ([209.51.188.92]:34252) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h3Qae-00042z-4x for qemu-devel@nongnu.org; Mon, 11 Mar 2019 15:28:00 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1h3QW5-0005Tr-9u for qemu-devel@nongnu.org; Mon, 11 Mar 2019 15:23:18 -0400 Received: from mx1.redhat.com ([209.132.183.28]:59712) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1h3QW4-0005TR-Tt for qemu-devel@nongnu.org; Mon, 11 Mar 2019 15:23:17 -0400 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 35D92155AC for ; Mon, 11 Mar 2019 19:23:16 +0000 (UTC) Received: from gimli.home (ovpn-116-24.phx2.redhat.com [10.3.116.24]) by smtp.corp.redhat.com (Postfix) with ESMTP id E204F5D70E; Mon, 11 Mar 2019 19:23:13 +0000 (UTC) From: Alex Williamson To: qemu-devel@nongnu.org Date: Mon, 11 Mar 2019 13:23:13 -0600 Message-ID: <155233219352.8141.477971660133647548.stgit@gimli.home> In-Reply-To: <155233206671.8141.2579745444621332750.stgit@gimli.home> References: <155233206671.8141.2579745444621332750.stgit@gimli.home> User-Agent: StGit/0.19-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.29]); Mon, 11 Mar 2019 19:23:16 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL 3/3] vfio/display: delay link up event X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" From: Gerd Hoffmann Kick the display link up event with a 0.1 sec delay, so the guest has a chance to notice the link down first. Signed-off-by: Gerd Hoffmann Reviewed-by: Liam Merwick [update for redefined macro] Signed-off-by: Alex Williamson --- hw/vfio/display.c | 30 +++++++++++++++++++++++++----- include/hw/vfio/vfio-common.h | 1 + 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/hw/vfio/display.c b/hw/vfio/display.c index 212ad1674ec1..a3d9c8f5beac 100644 --- a/hw/vfio/display.c +++ b/hw/vfio/display.c @@ -37,6 +37,23 @@ _reg->offset + offsetof(typeof(*_ptr), _fld))) =20 =20 +static void vfio_display_edid_link_up(void *opaque) +{ + VFIOPCIDevice *vdev =3D opaque; + VFIODisplay *dpy =3D vdev->dpy; + int fd =3D vdev->vbasedev.fd; + + dpy->edid_regs->link_state =3D VFIO_DEVICE_GFX_LINK_STATE_UP; + if (pwrite_field(fd, dpy->edid_info, dpy->edid_regs, link_state)) { + goto err; + } + trace_vfio_display_edid_link_up(); + return; + +err: + trace_vfio_display_edid_write_error(); +} + static void vfio_display_edid_update(VFIOPCIDevice *vdev, bool enabled, int prefx, int prefy) { @@ -49,6 +66,7 @@ static void vfio_display_edid_update(VFIOPCIDevice *vdev,= bool enabled, .prefy =3D prefy ?: vdev->display_yres, }; =20 + timer_del(dpy->edid_link_timer); dpy->edid_regs->link_state =3D VFIO_DEVICE_GFX_LINK_STATE_DOWN; if (pwrite_field(fd, dpy->edid_info, dpy->edid_regs, link_state)) { goto err; @@ -80,11 +98,8 @@ static void vfio_display_edid_update(VFIOPCIDevice *vdev= , bool enabled, goto err; } =20 - dpy->edid_regs->link_state =3D VFIO_DEVICE_GFX_LINK_STATE_UP; - if (pwrite_field(fd, dpy->edid_info, dpy->edid_regs, link_state)) { - goto err; - } - trace_vfio_display_edid_link_up(); + timer_mod(dpy->edid_link_timer, + qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + 100); return; =20 err: @@ -150,6 +165,9 @@ static void vfio_display_edid_init(VFIOPCIDevice *vdev) vdev->display_yres =3D dpy->edid_regs->max_yres; } =20 + dpy->edid_link_timer =3D timer_new_ms(QEMU_CLOCK_REALTIME, + vfio_display_edid_link_up, vdev); + vfio_display_edid_update(vdev, true, 0, 0); return; =20 @@ -168,6 +186,8 @@ static void vfio_display_edid_exit(VFIODisplay *dpy) =20 g_free(dpy->edid_regs); g_free(dpy->edid_blob); + timer_del(dpy->edid_link_timer); + timer_free(dpy->edid_link_timer); } =20 static void vfio_display_update_cursor(VFIODMABuf *dmabuf, diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h index 5f7f709b95f1..b65a2f051886 100644 --- a/include/hw/vfio/vfio-common.h +++ b/include/hw/vfio/vfio-common.h @@ -151,6 +151,7 @@ typedef struct VFIODisplay { struct vfio_region_info *edid_info; struct vfio_region_gfx_edid *edid_regs; uint8_t *edid_blob; + QEMUTimer *edid_link_timer; struct { VFIORegion buffer; DisplaySurface *surface;