From nobody Thu Sep 24 20:23:38 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=reject dis=none) header.from=aol.com ARC-Seal: i=1; a=rsa-sha256; t=1789270088; cv=none; d=zohomail.com; s=zohoarc; b=E/B2gbnnpInoi4bhhTk4zLTsj6lycoViKOiTsAIwC8FBHti5Fpq3L/i8rqV2asZBqaEzIriVCK/LV+b60uY4PTw1Fkp1bUNkPRj2+U5tu0d5hLjuj5lA0czMuE4V4+zBFKV0tn9aXlgRELYhkp9o4k369rV4N/eqZ3XbPA065zk= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1789270088; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=g6sVmPbbWSgcriWyUOxys6QUYAKxA8mRO/u8gh7Vvqg=; b=CdrshkYciaWnfJTRiX1SS5CD3VaYfYXuPk+tmFgmbOf6IsbopGW8wcnJw/eRtmUuC3/cyn6jBqAjx4j9gv0WpBsu3EAWuaSeR5D1H/ZQBTla8mF7Q8dYn2FRt1KZxEO1MMp4BDzCU08P/mg+vuVtxxus6EC38b3d94lRyUGsVlU= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=reject dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 178927008803633.184349633127226; Sat, 12 Sep 2026 20:28:08 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1x5asU-0003op-9E; Sat, 12 Sep 2026 23:27:38 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1x5asS-0003oX-3A for qemu-devel@nongnu.org; Sat, 12 Sep 2026 23:27:36 -0400 Received: from sonic315-8.consmr.mail.gq1.yahoo.com ([98.137.65.32]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1x5asO-000612-RZ for qemu-devel@nongnu.org; Sat, 12 Sep 2026 23:27:35 -0400 Received: from sonic.gate.mail.ne1.yahoo.com by sonic315.consmr.mail.gq1.yahoo.com with HTTP; Sun, 13 Sep 2026 03:27:29 +0000 Received: by hermes--production-ne1-6dbcb84f44-w9zrq (Yahoo Inc. Hermes SMTP Server) with ESMTPA ID 14c5b846713c82b711c43225786a63a7; Sun, 13 Sep 2026 03:27:27 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=aol.com; s=a2048; t=1789270049; bh=g6sVmPbbWSgcriWyUOxys6QUYAKxA8mRO/u8gh7Vvqg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject:Reply-To; b=lNLGQ6+IzXgHybURv5QtyOTWJ/M1pBx9M9FcaQcSN+VQEap5wvfBs/SwAzqsMCZBZqmJAblveMZ76tk6yFRbP8B9ljvsE8ciT47EQY64s17AODwO0YUx9eAt1gtp1uj80bq2q1+G7k3GmkuTdAOvbsdHHMmjCBosnNf/mDfPENL70pvPyOXxA8sPPZzUyrf4mHsLW+AGDqA8r4IQ9B+FdvqFuSkRbnx2XoQdhPCyAzHo7KOcslWP3OY6yoAWyH9/yhl5Ms4SwPnGDBWU7QiSCzyFGtjsB2Ripq1chOwYz4QvPMyNUGQ62EK5PclW2rYRIAQc2c4oiI00O3RhjcSoUA== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1789270049; bh=k1QjJqPObvY+kp3pNOGyD4/IHYJIHdlOHQmtNrQwsEQ=; h=X-Sonic-MF:From:To:Subject:Date:From:Subject; b=c6p1ck+b9U8VCHEi9cfW0HGgAgx8djYoakvGHUkuZoPhgxEQ91mbpes1gzdTtN0iUPPdlXoGvzM5vPzR+kGBg1T5vgTC6IbU8HWWpn77oqur20//hAd4YnBiQ2KuuqtAwnXP2gZTB+Aonykc/l4PT/oPD6cWS/fuyxJdbySPcPjsEczU7ISolfUNy8KsBD/XEQ4Nq8MOrkOOZK2cPeTH4137luYdcHPL8udbHb2uLs5LifubNytCisRlVB14oyji1FIIUZ4rRNxn8/5vjRLLERmv6Jxw8oXZ1vQN8mzElczPgsunsaYu2Wfeu8HeqIYYn897iGgCB6IMyg50DxRb6A== X-YMail-OSG: DqWhuPQVM1mEjDiTVRhsZi5mrC0ABHntBCEg2xo6HRC4dsndt6vu6cW8iQ5lHyZ DtSKKJJH.FdHJSPKqSBlAIXiC7roIZA4nwyLtCWN1XmLTsBIXVT9HlMj0qbsxXlSud85DKpMYXM6 f2QZ9w7wIcNSxKDw_CFO4yE0fQsVv.ForvkhaexANwHesKJsUyvTeDSP3hoRVfC9is_4TCaJlvX_ jkdU39axBbP0DoZxvzBwowQWjETcTEAEvYskGyloRDF88JYWw1Y6M_pYA4Z5jTtW4j3wSBRKql3w gewpxSxZ9PdQgt6jogwQteFvSGFf1_WCuCuYEfNPLXoirJdCZzMc3Db7qYFaKQWgOqCiNm0JjrBe aqI25O6.wwzLz8a98Y.1Tbgplip2585lOOHf_x2UwuxLJ8gcnSrwPoSHZjc0jQVU9RuCDZhNllA0 dAlC1I_Zr_i6aBSHwCDuoQbgB0eXIgm_Zia1Ro1DXwbrPZvs4XvjC9kwybmfmGlVobd30zEKtBba 93QNIuD9._8A3i0JGNsbtF7uMNahJlU19Ae8R49bb.EHPHRYds8UW0C0e19bVEcf1s3.0Ghorok_ 8srByNfYrx7hpCq7eEZG7ay6ZBanzHWpnpVvYqcO0Fk9L7yVJ._xqt.zRopx9JWULpNt2M_PT9hl _Jm9fl584UfkbEWcwm8TydWbmeksUifsAUEhWRgKGsDQfelk.ij_urGvvjoNpsdqSdJnl71OOvLA hZcBN19zjFgLt6B77ExqM5YZ1zPXIWcxEBrgCUGo8vgOyOwzMtC_RXAVQYLCAtBV2CbzM0.a2a.K QNkIkkGiOKzWn5nDiRnArpy7hDXQ_vbMtnSP6JU.hKhmRabOnnF3_f8iIq5ArePCmPPv2QYNB9Io sddoxVUZwmR_Pnex_D9VzMwLNSFbmS3UtOZd92NKPLJn.Kt2W.INiY28K4T8ffXEmb3_dGaGWiGH kMIvDziHJTCiYKg7kZFsV9YlJJHJ5UnGCsbNdl5EO_qbBOr6UJ2i44EC1UJXbtqov.tpMpr43tBs e1gyNvzIUyKkZRY1MOd2dPoTDHtDsQFwmMl09JmLI_QbNcAd97WAmanXORKLtzLsFwqNUIP4NMHC NoI_XEdBpf8nENutmnpF9jZLpKTUKaiaYBg8ncr_dL4gHIVFN188fEw4hkzxzymhwoH_ycLAIzVj WUr_rGNdtlJ0NuQe9J7uSUhIUKHYtMcspGMG1G.7I1uMIkmGwiZ0.7AyrPkv7rSJgXptoDs2KRkF iwcCLvJ_xfRLDpiVC.unZI7LVGtYwu35EC_nN8bycaFRs0xQ.Mxj145rFxPRQAHFNAuw45gf2pwY Ee01TJJWucJB5aZcOUzSs3zbk6LcnMteMNNgXcMDmkgAn7KvAIMXoiEAba5WX2jvb6tBVX.fnJnW 755j4WCS2So9dudG3jwjhJE7VlRNWvCFDz2W2pvvU6OxdbKqCKxdOwJqKGVLdwP5wPz6wg8IV2E6 WqBZl3kakjfizNoze1YinRCvMlxdUsLan1vrb6J4TOWvzvDd2hTnMElR_JaUzPJqqhkcp5TnioOD X7QBywfrON1rLR.434P298bXck8d9HkkvG5jmNggSOMKnMl679CX848Cys6gXZP3mD4sjeA2OT.e vuBzeuuSSCtXy7qlDMsiyxxpGMJoTvWS2._A5aApL0AqqU9qLds5pK07SHSfd9Yqouj2jRLqg23Q 9nCMtc80lmOj1ipJjF.9tKstPdRswpfdVV25_JzpQ_zS5saP_sSV.9BcE6rUoKCL3GR4ZQ1uPOX6 k6NA9aag9i5GdOnKnpNg4kl8SqWlPOTzt5f2tChPE2emtjCXMjHJc8cl3ZCZFu5GavHUJFC2vUSR yeBtxKtdcNFDzVxLL2X4N8m9e60gOjBrF.Q2j8BUtAlsxuCpU0KuIqlhM1b_6JdqvWBHn89qRYR1 b1QYGaaLjrmxLF5CD9e5MBZdDoovirTuQ6bxOnWH84_oX5UM7j_elnC5CIoaBGXEBTvgc0NPljzp 1VjFew86rts624EqRTD0Qmd5v05VZ4EH5h9hIIZ_ph.WzqUIFM1nEzR7UPnlp4TRPvU46Ayu432E UrbPVM8PBB5TFigIgTo554n3NR74AZEU05qW7aKvgmQYBNOqe2j8BdmE1wqn._ulYAdm_JOF0brX KP9O9wImGTOCctmTtaw6h0w1ekujc3dLf0JOzMCSrWSWvrx1vCHytwLexa4KjWqzB0WUjmAo7CDE lyYKt.xyiHwm38lD6vVHcWJgmhriicnk. X-Sonic-MF: X-Sonic-ID: 8dc129f1-8b9b-442c-b983-0e3542f95d70 From: Chuck Zmudzinski To: xen-devel@lists.xenproject.org Cc: qemu-devel@nongnu.org, Jan Beulich , Andrew Cooper , =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= , Teddy Astie Subject: [PATCH v4 1/2] tools/hvmloader: implement Intel IGD extended VBT support Date: Sat, 12 Sep 2026 23:27:23 -0400 Message-ID: <20260913032724.62438-2-brchuckz@aol.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260913032724.62438-1-brchuckz@aol.com> References: <20260913032724.62438-1-brchuckz@aol.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Length: 21769 Received-SPF: pass (zohomail.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=lists1p.gnu.org; Received-SPF: pass client-ip=98.137.65.32; envelope-from=brchuckz@aol.com; helo=sonic315-8.consmr.mail.gq1.yahoo.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @aol.com) X-ZM-MESSAGEID: 1789270090506158500 Content-Type: text/plain; charset="utf-8" Modern Intel IGD devices do not work well with the current implementation of support for the Intel IGD in hvmloader because it lacks support for an extended video bios table (VBT). Code 43 errors in Windows guests and failure of the guest screen to light up are some of the problems that occur with the current implementation. To address this problem, this patch implements support for Intel IGD devices with an extended VBT and OpRegion version 2+ which is required for most mod= ern Intel IGD devices, as noted in the Linux kernel vfio commits referenced in = the Link tags below. This patch ports support for devices with an extended VBT = and OpRegion 2+ which was added in those commits for KVM/vfio, but adapted for = Xen HVM guests with PCI passthrough. This patch depends on compatible support in the device model. If hvmloader detects the device model lacks such support, it will fall back to the currently implemented protocol for configuring the OpRegion to provide backward compatibiltiy for systems that lack a device model with support for an extended VBT. The primary reason the OpRegion needs to be patched in some cases is that w= ith the addition of the RVDA and RVDS fields to the OpRegion, the OpRegion is n= ot position-independent and may need to be patched if it is moved to a differe= nt address in the guest. This means the current protocol of having the device model directly map the unmodified host OpRegion to the guest is not compati= ble with the requiremnts of the newer devices that in some cases require that t= he OpRegion be modified for it to be compatible with the guest address space. In this implementation, the device model has the responsibility to read the host OpRegion and patch it as needed before exposing it to the guest. Since= an extended VBT means more pages are needed for the OpRegion, depending on the size of the extended VBT, hvmloader has the responsibility to edit the E820 map to accomodate the additional pages needed to contain the OpRegion + VBT. To implement this in hvmloader, use a variable, igd_opregion_e820_pages, instead of the constant, IGD_OPREGION_PAGES, to represent the number of pag= es to reserve in the E820 map for the OpRegion + VBT. Also, to remove the confusion introduced by setting IGD_OPREGION_PAGES to 3 in an earlier patch to account for the fact that the OpRegion is not guaranteed to be aligned on a page boundary, reset IGD_OPREGION_PAGES to 2 so it matches the actual size of the OpRegion. Instead of only writing to the PCI_INTEL_OPREGION register, first read from= it to provide a way for both hvmloader and the device model to discover if both components have support for an extended VBT and more than 3 pages reserved = for the OpRegion + VBT. The device model detects the read of the register before the write to learn that hvmloader has support, and hvmoader detects that the device model returns the number of pages to reserve for the OpRegion + VBT instead of 0 when it first reads the register to learn that that the device model has support. When this new protocol is supported by both hvmloader and the device model, the device model will not expose the host OpRegion direct= ly to the guest via a direct mapping as the old protocol does but instead expo= ses an emulated copy of the OpRegion and VBT using its ioreq server. This has t= he added benefit of preventing extraneous host memory in the regions before or after a non-page-aligned OpRegion that should be confidential to the host f= rom being exposed to the guest. Testing reveals that when the device model exposes the OpRegion to the guest by mapping it to the device model's ioreq server, the Windows Intel IGD graphics dirvers are unable to access the OpRegion and report Code 43 errors with the result being that the guest screen never lights up. So after the device model exposes the OpRegion to the guest using its ioreq server, make= a copy of it and use a copy of the OpRegion and VBT which is backed by RAM allocated to the guest instead of mapped via the ioreq server. This fixes t= he Code 43 errors reported by the Windows IGD graphics drivers. Link: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/co= mmit/drivers/vfio/pci/vfio_pci_igd.c?id=3Dbab2c1990b78 Link: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/co= mmit/drivers/vfio/pci/vfio_pci_igd.c?id=3D49ba1a2976c8 Signed-off-by: Chuck Zmudzinski --- The companion patch for the Qemu device model (DM) is available here: https://lore.kernel.org/qemu-devel/20260911072453.46256-7-brchuckz@aol.com/ That patch is part of a larger patch series available here: https://lore.kernel.org/qemu-devel/20260911072453.46256-1-brchuckz@aol.com/ Up-to-date specifications for the Intel IGD are not available to the public but an older version is available from Intel here: https://www.intel.com/content/www/us/en/docs/graphics-for-linux/developer-r= eference/1-0/opregion-specification.html This patch derives the specifications for the OpRegion that are needed to add support for an extended VBT from the patches to the Linux kernel vfio driver. This mainly consists of the RVDA and RVDS fieds of the OpRegion whi= ch store the address and size of the extended VBT, respectively. See the links in the commit message which provide links to the vfio patches that added support for this feature to KVM/VFIO guests for more details. There is an undocumented setting that works in the xl.cfg(5) domain configuration file, firmware_override, that makes it possible to use a patched version of hvmloader alongside an installation of unpatched upstream Xen or a version of Xen packaged by a distro. So one can download the source for one's installed version of Xen, apply this patch and build just hvmloader and then install the patched version of hvmloader with a different filename, such as hvmloader-igd-testing, into the same directory where hvmloader is installed (usually something like /usr/libexec/xen/boot) and then one can configure a guest to use the patched version of hvmloader with one's installed version of Xen by adding a line like this to the domain xl.cfg file: firmware_override =3D 'hvmloader-igd-testing' The compatible patch for the DM is part of a larger patchset that fixes many of the problems that currently affect the feature of Intel IGD passthrough to Xen HVM guests. This patch should be considered as a compani= on patch to that patchset for the DM. Do not try to test this patch with a real Intel IGD device without also applying the patchset for the DM because with= out those patches, the guest will most likely fail to start if an Intel IGD is passed through to the guest. Changes in v4: - Now this patch is the first patch of a 2-patch series - Correct a spelling mistake in the commit message: beneift -> benefit - Added a link to the cover letter of the latest version of the companion Qemu device model patch series. Changes in v3: - The patch has been substantially re-worked. Most of the implementation of support for Intel IGD in v2 that could be implemented in the DM instead of in hvmloader has been moved to the DM. Specifically, the responsibility to read the OpRegion and patch it if necessary is done in the DM instead of in hvmloader. This change is in response to the comments that were made on v2 of this patch. - In contrast to both the current implementation and the implementation in v2, the host OpRegion is never directly exposed to the guest. Instea= d, the DM exposes an emulated copy of the OpRegion to the guest, patched appropriately for the guest, using the DM's ioreq server. - Hvmloader's main responsibility is to allocate enough pages in the E820 map to accomodate both the OpRegion and the extended VBT. In v3, hvmloa= der relies on the DM to communicate the number of pages that are needed for the OpRegion + VBT, and this change means all the code in v2 related to discovering the size of the extended VBT has been removed from hvmloader in v3 and moved to the DM. - Backward compatibility with versions of the DM that do not support an extended VBT has been simplified. There is no need for a bitmask setting to indicate support for extended VBT and OpRegion 2 and higher. Instead, the DM learns that hvmloader has support by detecting a read of the OpRegion register before a write to it, and hvmloader learns that t= he DM has support if the DM returns a non-zero value, the number of pages needed for the OpRegion + VBT, in response to the first read by hvmload= er. - It was necessary to retain the code that populates the pages allocated = for the OpRegion and VBT with guest RAM and copying the OpRegion and VBT to that guest RAM because testing revealed that when the OpRegion and VBT = are exposed to the guest by the DM's ioreq server, Windows graphics drivers are unable to access the OpRegion and VBT. - To remove the confusion with the value of IGD_OPREGION_PAGES that is currently set to 3 to account for the fact that the OpRegion is not alw= ays aligned on a page boundary, it has been changed in v3 to 2, the actual number of pages needed for the OpRegion (not including an extended VBT). - Added a check on the number of pages needed for the OpRegion + VBT to ensure the region does not take up an unreasonably large percentage of = the reserved dynamic memory range. I also provide the following table that hopefully helps illustrate how v3 of this patch differs from v2: Resource/Description Proposed in v2 Proposed in v3 ---------------------------------------------------------------------------= --- OpRegion register Emulated in DM Emulated in DM ---------------------------------------------------------------------------= --- OpRegion Emulated (hvmloader Emulated in DM (gue= st makes a copy from direct accesses emulated c= opy mapped host OpRegion provided by DM and and from then on guest from then on guest accesses its own copy accesses its own co= py stored in guest memory) stored in guest mem= ory) ---------------------------------------------------------------------------= --- Extended VBT Emulated (hvmloader Emulated in DM (gue= st makes a copy from direct accesses emulated c= opy mapped host VBT and provided by DM and = from from then on guest then on guest acces= ses accesses its own copy its own copy stored= in stored in guest memory) guest memory) ---------------------------------------------------------------------------= --- E820 pages allocated Depends on extended VBT Depends on extended= VBT size if there is an size if there is an extended VBT extended VBT ---------------------------------------------------------------------------= --- If OpRegion needs patching hvmloader patches it DM patches it ---------------------------------------------------------------------------= --- Setting the OpRegion Done by DM after complex Done by DM with hint register communication protocol from hvmloader which with hvmloader completes provides DM with pa= ge base address of OpRegion in guest ---------------------------------------------------------------------------= --- Changes in v2: - Correct the name of the new function in the commit message opregion_setup() -> intel_opregion_setup() - Add a link to the companion patchset for the device model - Describe how to use the firmware_override setting in xl.cfg(5) to simplify testing of this patch. - Correct a logical flaw that in case the size of the extended VBT is <=3D 2 pages, an extra, unnecessary page would be allocated in the memory hole. This correction is in the intel_opregion.c file. This code: /* Update the number of pages we need for the E820 map */ igd_opregion_e820_pages =3D pages_needed; /* * So far we have allocated vbt_pages_needed * and we will likely need to allocate more * pages to fully contain OpRegion + VBT. */ if ( pages_needed > vbt_pages_needed ) igd_opregion_pgbase =3D mem_hole_alloc (pages_needed - vbt_pages_needed); Is replaced with this code: /* * So far we have allocated igd_opregion_e820_pages * and we will likely need to allocate more * pages to fully contain OpRegion + VBT. */ if ( pages_needed > igd_opregion_e820_pages ) igd_opregion_pgbase =3D mem_hole_alloc (pages_needed - igd_opregion_e820_pages); /* Update the number of pages we need for the E820 map */ igd_opregion_e820_pages =3D pages_needed; tools/firmware/hvmloader/config.h | 6 +- tools/firmware/hvmloader/e820.c | 4 +- tools/firmware/hvmloader/pci.c | 96 ++++++++++++++++++++++++++++++- 3 files changed, 100 insertions(+), 6 deletions(-) diff --git a/tools/firmware/hvmloader/config.h b/tools/firmware/hvmloader/c= onfig.h index c159db3..edc3a8d 100644 --- a/tools/firmware/hvmloader/config.h +++ b/tools/firmware/hvmloader/config.h @@ -8,7 +8,8 @@ enum virtual_vga { VGA_none, VGA_std, VGA_cirrus, VGA_pt }; extern enum virtual_vga virtual_vga; =20 extern unsigned long igd_opregion_pgbase; -#define IGD_OPREGION_PAGES 3 +extern unsigned int igd_opregion_e820_pages; +#define IGD_OPREGION_PAGES 2 =20 struct bios_config { const char *name; @@ -75,6 +76,9 @@ extern bool acpi_enabled; #define ACPI_MEMORY_DYNAMIC_START 0xFC001000 #define RESERVED_MEMORY_DYNAMIC_START 0xFC100000 #define RESERVED_MEMORY_DYNAMIC_END 0xFE000000 +#define RESERVED_MEMORY_DYNAMIC_PAGES (RESERVED_MEMORY_DYNAMIC_END - \ + RESERVED_MEMORY_DYNAMIC_START) >> \ + PAGE_SHIFT /* * GUEST_RESERVED: Physical address space reserved for guest use. * This is not dynamically advertised to guests, so this range must *never* diff --git a/tools/firmware/hvmloader/e820.c b/tools/firmware/hvmloader/e82= 0.c index 86d3954..97a234e 100644 --- a/tools/firmware/hvmloader/e820.c +++ b/tools/firmware/hvmloader/e820.c @@ -243,11 +243,11 @@ int build_e820_table(struct e820entry *e820, nr++; =20 e820[nr].addr =3D igd_opregion_base; - e820[nr].size =3D IGD_OPREGION_PAGES * PAGE_SIZE; + e820[nr].size =3D igd_opregion_e820_pages * PAGE_SIZE; e820[nr].type =3D E820_NVS; nr++; =20 - e820[nr].addr =3D igd_opregion_base + IGD_OPREGION_PAGES * PAGE_SI= ZE; + e820[nr].addr =3D igd_opregion_base + igd_opregion_e820_pages * PA= GE_SIZE; e820[nr].size =3D (uint32_t)-e820[nr].addr; e820[nr].type =3D E820_RESERVED; nr++; diff --git a/tools/firmware/hvmloader/pci.c b/tools/firmware/hvmloader/pci.c index c41c8d9..efe6b68 100644 --- a/tools/firmware/hvmloader/pci.c +++ b/tools/firmware/hvmloader/pci.c @@ -44,6 +44,7 @@ uint64_t pci_hi_mem_start =3D 0, pci_hi_mem_end =3D 0; =20 enum virtual_vga virtual_vga =3D VGA_none; unsigned long igd_opregion_pgbase =3D 0; +unsigned int igd_opregion_e820_pages =3D 0; =20 /* Check if the specified range conflicts with any reserved device memory.= */ static bool check_overlap_all(uint64_t start, uint64_t size) @@ -93,6 +94,9 @@ void pci_setup(void) uint16_t class, vendor_id, device_id; unsigned int bar, pin, link, isa_irq; uint8_t pci_devfn_decode_type[256] =3D {}; + uint32_t igd_opregion; + void *opregion_vbt_scratch; + bool opregion_is_direct_mapped; =20 /* Resources assignable to PCI devices via BARs. */ struct resource { @@ -192,12 +196,98 @@ void pci_setup(void) { igd_opregion_pgbase =3D mem_hole_alloc(IGD_OPREGION_PA= GES); /* - * Write the the OpRegion offset to give the opregion - * address to the device model. The device model will = trap=20 - * and map the OpRegion at the give address. + * To be compatible with this interface for programmin= g the + * the PCI_INTEL_OPREGION register, the device model m= ust + * check if the guest reads the register before it wri= tes + * to the register. To indicate to the device model th= at + * we have support for an extended VBT, we read the + * PCI_INTEL_OPREGION register before writing to it. I= f the + * device model supports an extended VBT, it will retu= rn + * the number of pages needed for the OpRegion + VBT. = If + * not, it will return 0 which indicates that it does = not + * implement this interface for supporting an extended= VBT. + */ + igd_opregion_e820_pages =3D pci_readl(vga_devfn, + PCI_INTEL_OPREGION= ); + if ( !igd_opregion_e820_pages ) + { + /* + * This case provides backward compatibility with + * device model versions that lack support for an + * extended VBT. In this case the device model + * expects us to allocate an extra page in case the + * OpRegion is not aligned on a page boundary. Als= o, + * in this case, the host OpRegion is direct mapped + * into the guest. + */ + igd_opregion_pgbase =3D mem_hole_alloc(1); + igd_opregion_e820_pages =3D IGD_OPREGION_PAGES + 1; + opregion_is_direct_mapped =3D true; + } + else + { + /* Allocate extra pages for an extended VBT */ + if ( igd_opregion_e820_pages > IGD_OPREGION_PAGES ) + { + igd_opregion_pgbase =3D + mem_hole_alloc(igd_opregion_e820_pages - + IGD_OPREGION_PAGES); + } + opregion_is_direct_mapped =3D false; + } + /* + * This ensures the OpRegion + VBT does not take up mo= re + * than 1/32 of the reserved region. Also, we must rej= ect + * a value of 1 for igd_opregion_e820_pages. + */ + if ( igd_opregion_e820_pages > + RESERVED_MEMORY_DYNAMIC_PAGES >> 5 || + igd_opregion_e820_pages =3D=3D 1 ) + { + printf("too many or too few pages (%u) for OpRegio= n\n", + igd_opregion_e820_pages); + BUG(); + } + /* + * Write the the OpRegion offset to give the OpRegion + * address to the device model. The device model will = trap + * and make the OpRegion accessible at the given addre= ss. + * The device model is also expected to verify that the + * OpRegion is compatible with the guest address space= and + * patch it if necessary to make it compatible. */ pci_writel(vga_devfn, PCI_INTEL_OPREGION, igd_opregion_pgbase << PAGE_SHIFT); + + /* Don't use our own copy if OpRegion is direct mapped= */ + if ( opregion_is_direct_mapped ) + break; + + /* + * Windows IGD drivers do not work properly when the + * OpRegion is exposed by the device model's ioreq ser= ver, + * so make a copy of the OpRegion and use that copy wh= ich + * will be backed by RAM allocated to the guest. + */ + opregion_vbt_scratch =3D + scratch_alloc(igd_opregion_e820_pages << + PAGE_SHIFT, 0); + memcpy(opregion_vbt_scratch, + (void *)(igd_opregion_pgbase << PAGE_SHIFT), + igd_opregion_e820_pages << PAGE_SHIFT); + + igd_opregion =3D pci_readl(vga_devfn, PCI_INTEL_OPREGI= ON); + /* + * The device model will unmap the OpRegion from the i= oreq + * server so we can use our own copy of the OpRegion. + */ + pci_writel(vga_devfn, PCI_INTEL_OPREGION, igd_opregion= ); + + mem_hole_populate_ram(igd_opregion_pgbase, + igd_opregion_e820_pages); + memcpy((void *)(igd_opregion_pgbase << PAGE_SHIFT), + opregion_vbt_scratch, + igd_opregion_e820_pages << PAGE_SHIFT); } } break; --=20 2.52.0 From nobody Thu Sep 24 20:23:38 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass(p=reject dis=none) header.from=aol.com ARC-Seal: i=1; a=rsa-sha256; t=1789270077; cv=none; d=zohomail.com; s=zohoarc; b=gbaLXXR1+8W3TDM/d/+G28mtSYWIPupQAzsbtoPwSA52no2R5SFDw6rKCJJuykRckKPBfMoIB8oNROouaV5HdEIKYFOHyCZ5UIPs+M1d0+4bLGPxQoOJTFqvtwaIANXiA5w03al1pKZEgxp0BC9k8q5LUfmcDwgUI9QM10t0Htk= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1789270077; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=Hevw5B+Wr7DTBK/0kWmrMKgRnH/bAgiz5/Fykn/Eyuo=; b=bideYt1JeRmqi/Ew7sGqW13c5V9l6Nu5EaHCu5ZJDHtA8jtYsEqADcUqHfxErtSXYFaod6RcGAdckj0GP1Ei4bD/Yf/ravIECZyZyQNFDxON2l3p09ZD1ZyoB7ethYQVWSxkpfHRo57bHqNNL60R4rEYdTcBYcXwzLrZfby+T3I= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass header.from= (p=reject dis=none) Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 178927007794420.81720826452863; Sat, 12 Sep 2026 20:27:57 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1419482.1646635 (Exim 4.92) (envelope-from ) id 1x5asW-0003TR-6X; Sun, 13 Sep 2026 03:27:40 +0000 Received: by outflank-mailman (output) from mailman id 1419482.1646635; Sun, 13 Sep 2026 03:27:40 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1x5asW-0003TK-37; Sun, 13 Sep 2026 03:27:40 +0000 Received: by outflank-mailman (input) for mailman id 1419482; Sun, 13 Sep 2026 03:27:38 +0000 Received: from mx.expurgate.net ([195.190.135.10]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1x5asU-0003Rk-5h for xen-devel@lists.xenproject.org; Sun, 13 Sep 2026 03:27:38 +0000 Received: from mx.expurgate.net (helo=localhost) by mx.expurgate.net with esmtp id 1x5asT-00Cx8K-Ix for xen-devel@lists.xenproject.org; Sun, 13 Sep 2026 05:27:37 +0200 Received: from [10.42.69.9] (helo=localhost) by localhost with ESMTP (eXpurgate MTA 0.9.1) (envelope-from ) id 6aa61794-2eae-0a2a0a5409dd-0a2a4509c456-28 for ; Sun, 13 Sep 2026 05:27:36 +0200 Received: from [98.137.64.146] (helo=sonic301-20.consmr.mail.gq1.yahoo.com) by tlsNG-bad1c0.mxtls.expurgate.net with ESMTPS (eXpurgate 4.57.1) (envelope-from ) id 6aa61827-be1a-0a2a45090019-628940928ec7-3 for ; Sun, 13 Sep 2026 05:27:36 +0200 Received: from sonic.gate.mail.ne1.yahoo.com by sonic301.consmr.mail.gq1.yahoo.com with HTTP; Sun, 13 Sep 2026 03:27:34 +0000 Received: by hermes--production-ne1-6dbcb84f44-w9zrq (Yahoo Inc. Hermes SMTP Server) with ESMTPA ID 14c5b846713c82b711c43225786a63a7; Sun, 13 Sep 2026 03:27:28 +0000 (UTC) X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" Authentication-Results: eu.smtp.expurgate.cloud; dkim=pass header.s=a2048 header.d=aol.com header.i="@aol.com" header.h="From:To:Cc:Subject:Date:In-Reply-To:References" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=aol.com; s=a2048; t=1789270054; bh=Hevw5B+Wr7DTBK/0kWmrMKgRnH/bAgiz5/Fykn/Eyuo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject:Reply-To; b=uY2lp5G1atnaUMVr0UscmeYJdwP0iwLvqcIb5ek5Yx7Jk04f2MuLHly8JbL038h+Dz5j6g00HJB53lMFolBUFiKDhenuE7OiftMW4oGSWCLXAz/rgz7srt4ORRoMNHPi0ZyUYUHbULJ5saf9Vmel1wTVrZqa12gn3FCD82QDCTz5cfPK8ItEOP60DItPbd6AUkxKy6VEn3phhH2oZiyDtcc7yvFT+duXFP5c7u7QuWVdHnTVaBpvidn4Jrmd2ksOS/OPudnFvgKG5IR4TkWbz+t8alo65i/KFbd0p3VcgElxW/LJNaHDOlJ68pMhM9HaNhMVtgb0IbEKtRsAyanuAQ== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1789270054; bh=L/S97QuLM5PBrc49OcJhPUSRtUyjGcV/+NyI/8Pj037=; h=X-Sonic-MF:From:To:Subject:Date:From:Subject; b=UFQlu9zugYRcYYk+bet5IhgBoCs09GbijWWiC0cZ6E4Sa9RvGmLfeVf0VGi4FEOq4hhKDCRB7wyiPNeE4uNy3FpOKw0sCO1YxrKHRv2cI3YV6cQWjaKbhEc9OVuJE+WYVkDwe+ddLqhCb2dF8kreSccF+saeBDml0OOnhX/SrUhDjd7nUGmZCeYpNx/7nDa+cqOXgdS6bz8yKG1tXmzxkmXhOy5NmD/+bPhVP6NV3rE/8ztPXeC28PY005Mc/HelGrHw7+dLLFrfWygeyptEofMfbo8+R47yId1S8Fj2xA3T1e/R/lMBz46PbOLt4UzgwmHiym0Q5nTOtru6DLahtw== X-YMail-OSG: MABzF34VM1kLtJmAr1eV5IlNnii6cA6572ltl2Ut9a2FKZEgqP8dpOG53E35F9Q MMEkiElQEqUu3q9MJtkEUHjtnWQGqJXvzvWvnnhuyXVfbrX0CWnnmJeGgTU3W48tLC2Z5X8S8xwB wGiEsHHWI3zf0txp_8LyQB52YzEjUFuGqIq7DWtsmYzm7DKGcpYT8jqd223hI3sjQcx5Qa9krlIL diwlzVjPA3_uB.lDeyGeeG8NTRCATq.YYg7OtOr01JR1I13zeW.5wdAIpF79ssQKbIQ1Gj0ylNtN hF4tsLDZtSr4HjNOTuD6x93jdODa3YUpCS9QuURhjELyJw8T9YXnwyfIM.CrKtCrqazvPx.d6lhE SOoUBFuA80Uy4YAKxqFvM1hadL1XahH1My_bHZ4QVfYCrgaAoX0YaR_7rpMV76tPjs4_z9LvHwWC reRq54QDMluMPyQUUO4GFzEpCS3G7VVZNlJvJt8AcjsR9U1sLZZJ0qdR1t9HfGSRJOddPTXlX0Ts LEVKkb8ZoQqg0HjU_F3SuV.xHs2nC8W.TVgGQMGEHpV.6.0CDJxOH1kDfM5VIKbEzpiYrUuuSYkU ydUVqIzlrUcw9gXtAUFrDdTl9G6JQ_5U0b4MDQYm32K98Ub5GGk9kJy0wkV2udEO8QjpCT1DhTqR 8sU0L7AvFTu.SpydNBvHhVeDJFQDAoharDvTz8dQmJI5ha1j0Ay8PsXB00y82mjAglPsXEZ4oPjD SJRVM7MFYtlpths95YmXGJYMGHw78PPsBKxvfUYJnvzx8u3hYRqK4UjLwWz1caWG1DRSdDtVkNNQ .7Km9kc43nQcFKm2ToSTaaKaAMuu7N8ThN14KUHv2r37BEtXJHbG.vyClLPoyMhLfyARdkC9A7WZ 2rxniiviN8w_P7WSrQxZyglyNIKqIByvI4lptHSLCmF_miPu27BEQNcNYyDPyqhMGtHCmBSy.dsM gecEXRynxPBOAlCTKeQLQ3A6RM8_TLq4yb7CzLzqoB3IlZFWbCa7kR7r6OYLiFR7Dt8K8fO9yyRl czxC0t06WLjcjuJK_uZbBTcFRjUWEIwyGKVfBDHUomVCyyGG1eY4nllRLbIMkz2ECuT2sAEl8l3j 5UoZ17yWD4CRB0RLXDljPBroJKW3AOD2yhzfcxdX2Ak89evT3sdeXzCTWhtT1e8PcZmw7n2wDHz_ 0Sgn7Uu4bWSAdwpALaFqBEyD9BFFfQzfXsNulmf1QqyqKcpR1SIpxr3HyPL0D.ZqAFWC0AVX0jm. AVvvCwQtN7briAtzjGJ_CNL8qrZZz.OZh.q3EjYedFjFfY_Mq7jHn8DHWqIQM1v_kzl_NSAxn_H0 cjyqFy98NgcCDhd9_3r86H6NSkt6g9j2OZ3aX8j_x.MwGbAGD_qHiJnHH4ToQMJdTZgItsRddjm9 j_g0Y7fttDMw8PlYJMNw4SlPemyURDpQGUUY2YWTyDjQFqk9b8zbMcSv6WE_P5AtOsZjRy_aFWB3 UbRceVrRb6MpxiN6JBp3GQACgBE9Hh6l52osbv1ybWa2VXEqfsUr2AS6aWJfUWE4RAm5VIru49Xa prVQjhXynxxi1c3K2Nd1fOzbEgJrHPSxCaGC2KJ.yrtUtmVogp_CXA8L475NMxZ4lNxrkKnZiWVA Rx_i56tvlWWmzvTRBB61k1FPgjnd2pqcVAmx5ypcds2bLaB4puHzS6_St2joQ2Cc5mnkoJtTL4p0 5tkOzdFr3Tv1.efS8bxZAmiW1L.K0ZQIdbFmg3R2RBU4GyZsczCsEMJssfHoq5KbfIEB6UpocOmt SWOP38VFcWk3._iVmVFv9X7UF.edlDzXbwNOZ0Ed6Igk5HoSPTkrNu4ARCFGS5PtKsfXWwFuYVJR 3LCAzeqg3FtCJGzu.ymwnpxwqtS.88ksc152oaa99FT5K5k0n9FAJB_ORVYbYJukgjjaxTPaAXES Opk0xGvy3SjlKpZ0_mPDqij3SjJkTqgvBQ.v3oLXtr4XFHVIu18mdOCYLcb0bj6pH8kae8Zti1wb WFxJaYpUB2ztgxGxoXpllYRp5GmcvgBc3tTBFWGMKbRw_GaHxR89xb5NWXtInszNSwR0NYHOxi8o b4rs5n5Oc.zlbbBasnOhvphFbVK9.A6YN_fZF4Zgu.1gsFN.f6EVRseumFdKgN2R.yh6iM6.pD5o znmoIKD96PiOmj6L9lebFHVejVFSSG10uLMZBp7tm.9ZQgRxgJ3WzZ3o88_.kXzbeBZAlhVLY_Tq D..zwK7DEpCKjGU..8rRyQAP2P8fAQ14GJ9M- X-Sonic-MF: X-Sonic-ID: 25657ca0-4f28-40f3-9cdb-11cc86d67d9e From: Chuck Zmudzinski To: xen-devel@lists.xenproject.org Cc: qemu-devel@nongnu.org, Anthony PERARD , Juergen Gross Subject: [PATCH v4 2/2] libxl: add OpRegion and VBT to firmware when assigning IGD Date: Sat, 12 Sep 2026 23:27:24 -0400 Message-ID: <20260913032724.62438-3-brchuckz@aol.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260913032724.62438-1-brchuckz@aol.com> References: <20260913032724.62438-1-brchuckz@aol.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Length: 7623 X-purgate-ID: tlsNG-bad1c0/1789270056-BD4C3034-45F313F0/0/0 X-purgate-type: clean X-purgate-size: 7795 X-ZohoMail-DKIM: pass (identity @aol.com) X-ZM-MESSAGEID: 1789270079894158500 Content-Type: text/plain; charset="utf-8" To provide support for newer IGD devices with an extended video bios table (VBT), the device model needs to access the host OpRegion and VBT when the IGD is bound to the xen-pciback driver but the Linux kernel only exposes them in the debugfs when the IGD is bound to the i915 driver. Although the OpRegion and VBT can be manually copied to a firmware directory from the debugfs to a directory where the device model can access them when the IGD is bound to the xen-pciback driver, libxl can do this automatically by copying the OpRegion and VBT from the Linux debugfs to the Xen firmware directory before unbinding the IGD from the i915 driver. Since the copying of the OpRegion and VBT are not required for the device to be made assignab= le, don't return an error if the only error is that the attempt to copy the OpRegion and/or the VBT to the Xen firmware directory failed. It is necessary to read the RVDS field of the OpRegion which stores the size of the extended VBT. We cannot rely on stat(2) for this which returns a value of 0 for the size of files stored in the Linux debugfs. This patch relies on lstat(2) only to determine if the OpRegion and VBT files already exist in the Xen firmware directory. If the value stored in the RVDS field is 0, then there is no extended VBT and the VBT is embedded within mailbox # 4 of the OpRegion, in which case we can assume the size of the VBT is 6 KiB. For users of the Qemu device model, if the Xen firmware directory is not configured as one of the Qemu firmware directories, the "intel-opregion" and "intel-vbt" files must be moved or copied to a Qemu firmware directory to provide proper support for an IGD with an extended VBT that is passed through to a Xen HVM guest. Signed-off-by: Chuck Zmudzinski --- This patch also depends on the companion patch for the Qemu device model available here: https://lore.kernel.org/qemu-devel/20260911072453.46256-7-brchuckz@aol.com/ There is not an up-to-date specification for the OpRegion and VBT available to the public online but an older version is available here: https://www.intel.com/content/www/us/en/docs/graphics-for-linux/developer-r= eference/1-0/opregion-specification.html Despite the fact that we do not have an up-to-date specification, patches to the Linux kernel i915 driver and the igd-related files of the Linux kern= el vfio driver provide enough information about the specification to provide support for the Intel IGD in Xen HVM guests. These patches to the Linux kernel vfio driver were particularly helpful for this series of patches to fix support for IGD passthrough for Xen HVM guests: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/d= rivers/vfio/pci/vfio_pci_igd.c?id=3Dbab2c1990b78 https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/d= rivers/vfio/pci/vfio_pci_igd.c?id=3D49ba1a2976c8 Many more details about the support for Intel IGD passthrough to Xen guests is available in the other patch in this series and the 7 patches of the companion patch series for the device model. Please refer to those patches before asking questions that might be answered by reading through those other patches. Changes in v4: - This is the first version of this series of IGD fixes with this patch tools/libs/light/libxl_pci.c | 82 ++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) diff --git a/tools/libs/light/libxl_pci.c b/tools/libs/light/libxl_pci.c index 49d272d..ff28387 100644 --- a/tools/libs/light/libxl_pci.c +++ b/tools/libs/light/libxl_pci.c @@ -25,6 +25,9 @@ #define PCI_OPTIONS "msitranslate=3D%d,power_mgmt=3D%d" #define PCI_BDF_XSPATH "%04x-%02x-%02x-%01x" #define PCI_PT_QDEV_ID "pci-pt-%02x_%02x.%01x" +#define PCI_OPREGION_SIZE 0x2000 +#define PCI_OPREGION_RVDS 0x3c2 /* offset of RVDS in OpRegion */ +#define PCI_VBT_MBOX4_SIZE 0x1800 =20 /* PCI Interrupt Line is an 8-bit value, 0xff means disconnected. */ #define PCI_IRQ_LINE_LIMIT 0xff @@ -765,6 +768,17 @@ static int libxl__device_pci_assignable_add(libxl__gc = *gc, const char *name; int rc; struct stat st; + uint32_t rvds =3D 0; /* Intel VBT size */ + int fd =3D -1; + char *spath1 =3D NULL; + char *dpath1 =3D NULL; + char *spath2 =3D NULL; + char *dpath2 =3D NULL; + uint8_t *buf1 =3D NULL; + uint8_t *buf2 =3D NULL; + uint16_t pt_vendor =3D 0xffff; + uint16_t pt_device =3D 0xffff; + unsigned long class =3D 0; =20 /* Local copy for convenience */ dom =3D pci->domain; @@ -797,6 +811,74 @@ static int libxl__device_pci_assignable_add(libxl__gc = *gc, return ERROR_FAIL; } =20 + pt_vendor =3D sysfs_dev_get_vendor(gc, pci); + pt_device =3D sysfs_dev_get_device(gc, pci); + + /* Check if the device is an Intel IGD */ + if ( pt_vendor !=3D 0x8086 || pt_device =3D=3D 0xffff || + sysfs_dev_get_class(gc, pci, &class) || + (class !=3D 0x030000 && class !=3D 0x038000) ) + goto skipigd; + + /* These filenames match the filenames used in the device model */ + dpath1 =3D libxl__abs_path(gc, "intel-opregion", + libxl__xenfirmwaredir_path()); + dpath2 =3D libxl__abs_path(gc, "intel-vbt", + libxl__xenfirmwaredir_path()); + + /* Check if the OpRegion and VBT files are already present */ + if ( !lstat(dpath1, &st) && !lstat(dpath2, &st) ) + goto skipigd; + + spath1 =3D GCSPRINTF("/sys/kernel/debug/dri/"PCI_BDF"/i915_opregion", + dom, bus, dev, func); + spath2 =3D GCSPRINTF("/sys/kernel/debug/dri/"PCI_BDF"/i915_vbt", + dom, bus, dev, func); + + /* + * Try to copy the OpRegion and VBT while IGD is bound to i915 driver + * but don't return an error if one or both of the copies fail. + */ + if ( !lstat(spath1, &st) && !lstat(spath2, &st) ) { + fd =3D open(spath1, O_RDONLY); + GCNEW_ARRAY(buf1, PCI_OPREGION_SIZE); + rc =3D libxl_read_exactly(ctx, fd, (void *)buf1, PCI_OPREGION_SIZE, + spath1, NULL); + close(fd); + if ( !rc ) { + fd =3D open(dpath1, O_CREAT|O_WRONLY|O_TRUNC, 0644); + rc =3D libxl_write_exactly(ctx, fd, (void *)buf1, + PCI_OPREGION_SIZE, dpath1, NULL); + close(fd); + if ( !rc ) { + rvds =3D *(uint32_t *)(buf1 + PCI_OPREGION_RVDS); + if ( !rvds ) /* VBT is embedded in the OpRegion */ + rvds =3D PCI_VBT_MBOX4_SIZE; + fd =3D open(spath2, O_RDONLY); + GCNEW_ARRAY(buf2, rvds); + rc =3D libxl_read_exactly(ctx, fd, (void *)buf2, rvds, + spath2, NULL); + close(fd); + if ( !rc ) { + fd =3D open(dpath2, O_CREAT|O_WRONLY|O_TRUNC, 0644); + rc =3D libxl_write_exactly(ctx, fd, (void *)buf2, + rvds, dpath2, NULL); + close(fd); + if ( rc ) { + LOG(INFO, "Failed to copy VBT"); + } + } else { + LOG(INFO, "Failed to read VBT from debugfs"); + } + } else { + LOG(INFO, "Failed to copy OpRegion"); + } + } else { + LOG(INFO, "Failed to read OpRegion from debugfs"); + } + } + +skipigd: /* Check to see if it's already assigned to pciback */ rc =3D pciback_dev_is_assigned(gc, pci); if ( rc < 0 ) { --=20 2.52.0