From nobody Sun May 19 17:58:03 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 1550814771424824.7383867791685; Thu, 21 Feb 2019 21:52:51 -0800 (PST) Received: from localhost ([127.0.0.1]:44707 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gx3lN-0006rz-1P for importer@patchew.org; Fri, 22 Feb 2019 00:52:45 -0500 Received: from eggs.gnu.org ([209.51.188.92]:57226) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gx3jJ-0005jT-BF for qemu-devel@nongnu.org; Fri, 22 Feb 2019 00:50:41 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gx3jH-00089m-Vx for qemu-devel@nongnu.org; Fri, 22 Feb 2019 00:50:37 -0500 Received: from mx1.redhat.com ([209.132.183.28]:55618) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gx3jH-0007fd-JE for qemu-devel@nongnu.org; Fri, 22 Feb 2019 00:50:35 -0500 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 680623002DA2; Fri, 22 Feb 2019 05:49:45 +0000 (UTC) Received: from sirius.home.kraxel.org (ovpn-116-228.ams2.redhat.com [10.36.116.228]) by smtp.corp.redhat.com (Postfix) with ESMTP id 7CB6E600C2; Fri, 22 Feb 2019 05:49:40 +0000 (UTC) Received: by sirius.home.kraxel.org (Postfix, from userid 1000) id 82E9011AB5; Fri, 22 Feb 2019 06:49:39 +0100 (CET) From: Gerd Hoffmann To: qemu-devel@nongnu.org Date: Fri, 22 Feb 2019 06:49:37 +0100 Message-Id: <20190222054939.19739-2-kraxel@redhat.com> In-Reply-To: <20190222054939.19739-1-kraxel@redhat.com> References: <20190222054939.19739-1-kraxel@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.44]); Fri, 22 Feb 2019 05:49:45 +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] [PATCH v3 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: , Cc: Alex Williamson , intel-gvt-dev@lists.freedesktop.org, Gerd Hoffmann Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" 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 --- include/hw/vfio/vfio-common.h | 3 + hw/vfio/display.c | 127 ++++++++++++++++++++++++++++++++++++++= ++++ hw/vfio/trace-events | 7 +++ 3 files changed, 137 insertions(+) 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; diff --git a/hw/vfio/display.c b/hw/vfio/display.c index dead30e626cb..f59fcc487128 100644 --- a/hw/vfio/display.c +++ b/hw/vfio/display.c @@ -15,15 +15,139 @@ #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) \ + if (sizeof(_ptr->_fld) !=3D \ + pread(_fd, &(_ptr->_fld), sizeof(_ptr->_fld), \ + _reg->offset + offsetof(typeof(*_ptr), _fld))) \ + goto err; +#define pwrite_field(_fd, _reg, _ptr, _fld) \ + if (sizeof(_ptr->_fld) !=3D \ + pwrite(_fd, &(_ptr->_fld), sizeof(_ptr->_fld), \ + _reg->offset + offsetof(typeof(*_ptr), _fld))) \ + goto err; + + +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; + pwrite_field(fd, dpy->edid_info, dpy->edid_regs, link_state); + 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); + pwrite_field(fd, dpy->edid_info, dpy->edid_regs, edid_size); + 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; + pwrite_field(fd, dpy->edid_info, dpy->edid_regs, link_state); + 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); + pread_field(fd, dpy->edid_info, dpy->edid_regs, edid_offset); + pread_field(fd, dpy->edid_info, dpy->edid_regs, edid_max_size); + pread_field(fd, dpy->edid_info, dpy->edid_regs, max_xres); + pread_field(fd, dpy->edid_info, dpy->edid_regs, max_yres); + 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 +295,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 +312,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 +492,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 f41ca96160bf..28d445caaf74 100644 --- a/hw/vfio/trace-events +++ b/hw/vfio/trace-events @@ -131,3 +131,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) "%dx%d" +vfio_display_edid_write_error(void) "" --=20 2.9.3 From nobody Sun May 19 17:58:03 2024 Delivered-To: importer@patchew.org Received-SPF: temperror (zoho.com: Error in retrieving data from DNS) 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=temperror (zoho.com: Error in retrieving data from DNS) 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 1550814762472833.6337716272812; Thu, 21 Feb 2019 21:52:42 -0800 (PST) Received: from localhost ([127.0.0.1]:44705 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gx3lB-0006lA-3A for importer@patchew.org; Fri, 22 Feb 2019 00:52:33 -0500 Received: from eggs.gnu.org ([209.51.188.92]:57064) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gx3jD-0005ds-R6 for qemu-devel@nongnu.org; Fri, 22 Feb 2019 00:50:32 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gx3j9-000838-TD for qemu-devel@nongnu.org; Fri, 22 Feb 2019 00:50:29 -0500 Received: from mx1.redhat.com ([209.132.183.28]:50538) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gx3j9-0007fP-4E for qemu-devel@nongnu.org; Fri, 22 Feb 2019 00:50:27 -0500 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id E50673082E02; Fri, 22 Feb 2019 05:49:44 +0000 (UTC) Received: from sirius.home.kraxel.org (ovpn-116-228.ams2.redhat.com [10.36.116.228]) by smtp.corp.redhat.com (Postfix) with ESMTP id 7A6D316E55; Fri, 22 Feb 2019 05:49:40 +0000 (UTC) Received: by sirius.home.kraxel.org (Postfix, from userid 1000) id 8D2FF11AB7; Fri, 22 Feb 2019 06:49:39 +0100 (CET) From: Gerd Hoffmann To: qemu-devel@nongnu.org Date: Fri, 22 Feb 2019 06:49:38 +0100 Message-Id: <20190222054939.19739-3-kraxel@redhat.com> In-Reply-To: <20190222054939.19739-1-kraxel@redhat.com> References: <20190222054939.19739-1-kraxel@redhat.com> X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.46]); Fri, 22 Feb 2019 05:49:44 +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] [PATCH v3 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: , Cc: Alex Williamson , intel-gvt-dev@lists.freedesktop.org, Gerd Hoffmann Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" 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 --- hw/vfio/pci.h | 2 ++ hw/vfio/display.c | 12 ++++++++++-- hw/vfio/pci.c | 12 ++++++++++++ 3 files changed, 24 insertions(+), 2 deletions(-) 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; diff --git a/hw/vfio/display.c b/hw/vfio/display.c index f59fcc487128..8bf7c890be96 100644 --- a/hw/vfio/display.c +++ b/hw/vfio/display.c @@ -46,8 +46,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; @@ -128,6 +128,14 @@ static void vfio_display_edid_init(VFIOPCIDevice *vdev) pread_field(fd, dpy->edid_info, dpy->edid_regs, max_yres); 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, --=20 2.9.3 From nobody Sun May 19 17:58:03 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 1550814731668207.89830685918037; Thu, 21 Feb 2019 21:52:11 -0800 (PST) Received: from localhost ([127.0.0.1]:44703 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gx3ko-0006RO-KX for importer@patchew.org; Fri, 22 Feb 2019 00:52:10 -0500 Received: from eggs.gnu.org ([209.51.188.92]:56988) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gx3iu-0005OV-9d for qemu-devel@nongnu.org; Fri, 22 Feb 2019 00:50:14 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gx3iq-0007rw-G7 for qemu-devel@nongnu.org; Fri, 22 Feb 2019 00:50:10 -0500 Received: from mx1.redhat.com ([209.132.183.28]:32792) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gx3io-0007fR-Cz for qemu-devel@nongnu.org; Fri, 22 Feb 2019 00:50:06 -0500 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 1EBD0307D985; Fri, 22 Feb 2019 05:49:45 +0000 (UTC) Received: from sirius.home.kraxel.org (ovpn-116-228.ams2.redhat.com [10.36.116.228]) by smtp.corp.redhat.com (Postfix) with ESMTP id 7EECF6014E; Fri, 22 Feb 2019 05:49:40 +0000 (UTC) Received: by sirius.home.kraxel.org (Postfix, from userid 1000) id 9663A11AB8; Fri, 22 Feb 2019 06:49:39 +0100 (CET) From: Gerd Hoffmann To: qemu-devel@nongnu.org Date: Fri, 22 Feb 2019 06:49:39 +0100 Message-Id: <20190222054939.19739-4-kraxel@redhat.com> In-Reply-To: <20190222054939.19739-1-kraxel@redhat.com> References: <20190222054939.19739-1-kraxel@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.48]); Fri, 22 Feb 2019 05:49:45 +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] [PATCH v3 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: , Cc: Alex Williamson , intel-gvt-dev@lists.freedesktop.org, Gerd Hoffmann Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" 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 --- include/hw/vfio/vfio-common.h | 1 + hw/vfio/display.c | 26 +++++++++++++++++++++++--- 2 files changed, 24 insertions(+), 3 deletions(-) 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; diff --git a/hw/vfio/display.c b/hw/vfio/display.c index 8bf7c890be96..971e801dc05c 100644 --- a/hw/vfio/display.c +++ b/hw/vfio/display.c @@ -38,6 +38,21 @@ goto err; =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; + pwrite_field(fd, dpy->edid_info, dpy->edid_regs, link_state); + 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) { @@ -50,6 +65,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; pwrite_field(fd, dpy->edid_info, dpy->edid_regs, link_state); trace_vfio_display_edid_link_down(); @@ -77,9 +93,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; - pwrite_field(fd, dpy->edid_info, dpy->edid_regs, link_state); - trace_vfio_display_edid_link_up(); + timer_mod(dpy->edid_link_timer, + qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + 100); return; =20 err: @@ -136,6 +151,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 @@ -154,6 +172,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, --=20 2.9.3