From nobody Tue Nov 26 01:56:41 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.12 as permitted sender) client-ip=66.175.222.12; envelope-from=bounce+27952+63881+1787277+3901457@groups.io; helo=web01.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.12 as permitted sender) smtp.mailfrom=bounce+27952+63881+1787277+3901457@groups.io; arc=fail (BodyHash is different from the expected one) Received: from web01.groups.io (web01.groups.io [66.175.222.12]) by mx.zohomail.com with SMTPS id 1596829505948390.2362237263925; Fri, 7 Aug 2020 12:45:05 -0700 (PDT) Return-Path: X-Received: by 127.0.0.2 with SMTP id ZUz3YY1788612xQD77VvyLq4; Fri, 07 Aug 2020 12:45:05 -0700 X-Received: from NAM12-BN8-obe.outbound.protection.outlook.com (NAM12-BN8-obe.outbound.protection.outlook.com [40.107.237.71]) by mx.groups.io with SMTP id smtpd.web12.4290.1596829504461146371 for ; Fri, 07 Aug 2020 12:45:04 -0700 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=QzrkCQJPAZHd5UJAxu+OOnRMUWVbGWx+weXUJUdNputFO5A7DON4Hq+GfgDoeBDs6FR5eNwlLCdXi/CDQSKKrNqU/8Z4sVyQeOrI/Edsdnr6VVe8SBpaMjRQiCYRYgg6JrE9w1uPo/xdi/ogSUp2h5jW45P5DnIERyDGBagemV5/Opj6/6BlaArgn+JoAeEE8Qj41GN6YEpGTQQMlW4qm9UStM3mV1Wq2bLdGvsUY5D5TMmIxT3iK+klhDeJKsck55A69VD3rRIVkpYOrlZridmqeQm7yKyaMaFP3A2z0AH+OG5LzUWYmTXNS6KJ6bXS+y+1FpwU3yyA73w4lvCC2w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=9SL7ZuvVbtegSaUIJvRjeIedgAr9HaaB2JEMJds61HY=; b=hB6qKCZkjNmlDlAmCNP+nGnjkAKxtsl1BlPzlXzJlHSYo6q/bVGG/74wsuwW4DuqXosG5xlbkgY6tjk6aVF1Gar6JTheBqxmLAJ/QIt77/Jshx/BdM/hPMihfzj6pPAfOtACvRRGS6YThbiHDCNK6b9BbJbmQbMCQxbK923M0wquNfUV7pWPYTXSwVGwpn1HorPG63YcNkGUQ30GzNUvn9nAsnKwxvFX1+oBmbLQGbNNaosOpAxCvtE/NLUWsICty35126RoI9Jx2GFnRqshqnJHtA7MlnCeaSJkCOUIAVdIzTHftocdYIL65/t/6kMyf83ATVLz4Xf8MhHAUq1RDQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=amd.com; dmarc=pass action=none header.from=amd.com; dkim=pass header.d=amd.com; arc=none X-Received: from CY4PR12MB1352.namprd12.prod.outlook.com (2603:10b6:903:3a::13) by CY4PR12MB1541.namprd12.prod.outlook.com (2603:10b6:910:7::23) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3261.18; Fri, 7 Aug 2020 19:45:02 +0000 X-Received: from CY4PR12MB1352.namprd12.prod.outlook.com ([fe80::9181:78bf:bf0:702b]) by CY4PR12MB1352.namprd12.prod.outlook.com ([fe80::9181:78bf:bf0:702b%5]) with mapi id 15.20.3239.024; Fri, 7 Aug 2020 19:45:02 +0000 From: "Lendacky, Thomas" To: devel@edk2.groups.io CC: Brijesh Singh , Ard Biesheuvel , Eric Dong , Jordan Justen , Laszlo Ersek , Liming Gao , Michael D Kinney , Ray Ni Subject: [edk2-devel] [PATCH v14 39/46] OvmfPkg/QemuFlashFvbServicesRuntimeDxe: Bypass flash detection with SEV-ES Date: Fri, 7 Aug 2020 14:39:24 -0500 Message-ID: <90b04c686b5f7228cdad28c615465e57b63bf511.1596829170.git.thomas.lendacky@amd.com> In-Reply-To: References: X-ClientProxiedBy: DM3PR12CA0086.namprd12.prod.outlook.com (2603:10b6:0:57::30) To CY4PR12MB1352.namprd12.prod.outlook.com (2603:10b6:903:3a::13) MIME-Version: 1.0 X-MS-Exchange-MessageSentRepresentingType: 1 X-Received: from tlendack-t1.amd.com (165.204.77.1) by DM3PR12CA0086.namprd12.prod.outlook.com (2603:10b6:0:57::30) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3261.19 via Frontend Transport; Fri, 7 Aug 2020 19:45:01 +0000 X-Originating-IP: [165.204.77.1] X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-HT: Tenant X-MS-Office365-Filtering-Correlation-Id: 90619f95-2cd3-4abb-6c01-08d83b0a6030 X-MS-TrafficTypeDiagnostic: CY4PR12MB1541: X-MS-Exchange-Transport-Forked: True X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:10000; X-MS-Exchange-SenderADCheck: 1 X-Microsoft-Antispam-Message-Info: u9svf8U8Bl5fTx6qbWokNIH+8v3Z7vgfnj8GEwfIm/ceOqU/qb3RsFQwgjPaIOPf6E5U0HNsXBIGPlSAygkZ8MkiSb3jK3SDg7Ra3itAmECMPzfdIDhU1dMujtBf32fbA+tIVVsvKsuQfVaEkW+MEjh7IBJwFqRrvzPwKMWzfX1WdWm6sSyZMDjm9smc/g6NtqKm4GHJCZx0JgaaVgFBA7SzBKFTqaQWVW4j/VLormJbhSz/YNtNVy6+Bo3snC/XKMgY72tAbMy6GhdlR+i18LiJbVjeYFuPqi/JvdfpDTuLthlAhHT0XV/M8AGY4FkhmiZS03SE25DKj3g4mi/wP+u4QbnbLNgZ9M6YsoF3otUuxHVQ5jSNfvdkbI9KMKbwVpR4Ar/YXO4yXX60jIN58bG5OlmzwecDcYxkXjuCXJNMu1dBUYwhZHiJeqLtK2Miaa7TqycA+ybzv1albF7sXo9sptSNut8zHVszlZgYolncdHFYulYVaOga7U565/uc X-MS-Exchange-AntiSpam-MessageData: TyUBUkrzEguuAIZ4T796l9+CmyttaFoywSVOfp8VnQqwQQXgzmOEMHUCFN3Lfu9hUXYpYGvMI1PoOGkhsrMu2gQbdGHJaGSGP9HFKN7iXhyEHaM/o/QXw7z/HPu3qzq0BTOApEVmMI9L9c13nSJnqTF7DHmojH9IW0I4uRwC629I5F/E3KpotUujkUP/+OBUNNWNl9ltetFWeJ15TqqMmE3my2T+n8dBvXQnfkzrUOW8VYpPV33Qzl5mOKCUBABA1AlsssT/YtWcfX+TrCUXeB1BXdGdiVYCfnT8VAk22wf/XivGaC6x5+ZffECdYMs3rdjvNp2ZxVtdBJOvchJqqoGdtRlw0AmoalEDW0JrKHeejw+S57RuJjJTXnYf+PBoyfYLmQbmwO+vPr5slxL38omyhsbumWkx+joB0psDj+KyXPM9cvAvABzhN7PCcdCwNJDjLRCSeX1dMfKtTdH6rY0bvXndRTPgaPSnMQ/4+VxhPKOFEVUUfB81j5kIQ2HUQVSrLKkNI7oux/4compGI3irrsXYXCgsgPcmDIuoZuO/YHTGFHdEVOTkn+e8zdlwoEkcbb+5y+NhP9gMNCwu0p8bkp6IWKG7cLxPtxg3Wh1GVmav5PXSDlmHN+gp503gbJQxA/fLAwFXJRHcunoZ3g== X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-Network-Message-Id: 90619f95-2cd3-4abb-6c01-08d83b0a6030 X-MS-Exchange-CrossTenant-AuthSource: CY4PR12MB1352.namprd12.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 07 Aug 2020 19:45:02.4502 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: KQpjdM0NMCyKPecoeM1+2pcz80J13841KfciJaf5y25iPv5rPassbqlhLuEq+rDJH7Zp78g6khvmkj0fDUnIPQ== X-MS-Exchange-Transport-CrossTenantHeadersStamped: CY4PR12MB1541 Precedence: Bulk List-Unsubscribe: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,thomas.lendacky@amd.com X-Gm-Message-State: gPNHkxrro3OlcWs3U6feHVesx1787277AA= Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1596829505; bh=XohkpoSAKonrGqIAuVKxpIZZ1Vdt44M+Qsm3fQ4d/jM=; h=CC:Content-Type:Date:From:Reply-To:Subject:To; b=cSz5T1VPcoa1rwaAkY/Tfhoof1/lGZc+/duzmUKPEIcSz8a5eE1PCnmTpnW3DYNrRe0 iRRe8hS4DVLd5ynLDGq2gb5rZvMgWkPvA8/gcbXFrTqjfnpVKYpBL8JC+4Evi1ZhD0fL8 EkXCZIu1Lsg5Fls+WNdg5qEBJWWer+bga4k= X-ZohoMail-DKIM: pass (identity @groups.io) Content-Type: text/plain; charset="utf-8" From: Tom Lendacky BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=3D2198 The flash detection routine will attempt to determine how the flash device behaves (e.g. ROM, RAM, Flash). But when SEV-ES is enabled and the flash device behaves as a ROM device (meaning it is marked read-only by the hypervisor), this check may result in an infinite nested page fault because of the attempted write. Since the instruction cannot be emulated when SEV-ES is enabled, the RIP is never advanced, resulting in repeated nested page faults. When SEV-ES is enabled, exit the flash detection early and assume that the FD behaves as Flash. This will result in QemuFlashWrite() being called to store EFI variables, which will also result in an infinite nested page fault when the write is performed. In this case, update QemuFlashWrite() to use the VMGEXIT MMIO write support to have the hypervisor perform the write without having to emulate the instruction. Cc: Jordan Justen Cc: Laszlo Ersek Cc: Ard Biesheuvel Reviewed-by: Laszlo Ersek Signed-off-by: Tom Lendacky --- .../FvbServicesRuntimeDxe.inf | 2 + .../QemuFlash.h | 13 ++++++ .../QemuFlash.c | 23 +++++++++-- .../QemuFlashDxe.c | 40 +++++++++++++++++++ .../QemuFlashSmm.c | 16 ++++++++ 5 files changed, 91 insertions(+), 3 deletions(-) diff --git a/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesRuntimeDxe.i= nf b/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf index 72cabba4357d..8bb2325157ea 100644 --- a/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf +++ b/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf @@ -38,6 +38,7 @@ [Sources] [Packages] MdePkg/MdePkg.dec MdeModulePkg/MdeModulePkg.dec + UefiCpuPkg/UefiCpuPkg.dec OvmfPkg/OvmfPkg.dec =20 [LibraryClasses] @@ -52,6 +53,7 @@ [LibraryClasses] UefiBootServicesTableLib UefiDriverEntryPoint UefiRuntimeLib + VmgExitLib =20 [Guids] gEfiEventVirtualAddressChangeGuid # ALWAYS_CONSUMED diff --git a/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/QemuFlash.h b/OvmfPkg/Q= emuFlashFvbServicesRuntimeDxe/QemuFlash.h index f1afabcbe6ae..219d0d6e83cf 100644 --- a/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/QemuFlash.h +++ b/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/QemuFlash.h @@ -89,5 +89,18 @@ QemuFlashBeforeProbe ( IN UINTN FdBlockCount ); =20 +/** + Write to QEMU Flash + + @param[in] Ptr Pointer to the location to write. + @param[in] Value The value to write. + +**/ +VOID +QemuFlashPtrWrite ( + IN volatile UINT8 *Ptr, + IN UINT8 Value + ); + #endif =20 diff --git a/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/QemuFlash.c b/OvmfPkg/Q= emuFlashFvbServicesRuntimeDxe/QemuFlash.c index 1b0d6c053f1a..0d29bf701aca 100644 --- a/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/QemuFlash.c +++ b/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/QemuFlash.c @@ -9,6 +9,7 @@ =20 #include #include +#include #include =20 #include "QemuFlash.h" @@ -80,6 +81,21 @@ QemuFlashDetected ( =20 DEBUG ((DEBUG_INFO, "QEMU Flash: Attempting flash detection at %p\n", Pt= r)); =20 + if (MemEncryptSevEsIsEnabled ()) { + // + // When SEV-ES is enabled, the check below can result in an infinite + // loop with respect to a nested page fault. When the memslot is mapped + // read-only, the nested page table entry is read-only. The check below + // will cause a nested page fault that cannot be emulated, causing + // the instruction to retried over and over. For SEV-ES, acknowledge t= hat + // the FD appears as ROM and not as FLASH, but report FLASH anyway bec= ause + // FLASH behavior can be simulated using VMGEXIT. + // + DEBUG ((DEBUG_INFO, + "QEMU Flash: SEV-ES enabled, assuming FD behaves as FLASH\n")); + return TRUE; + } + OriginalUint8 =3D *Ptr; *Ptr =3D CLEAR_STATUS_CMD; ProbeUint8 =3D *Ptr; @@ -181,8 +197,9 @@ QemuFlashWrite ( // Ptr =3D QemuFlashPtr (Lba, Offset); for (Loop =3D 0; Loop < *NumBytes; Loop++) { - *Ptr =3D WRITE_BYTE_CMD; - *Ptr =3D Buffer[Loop]; + QemuFlashPtrWrite (Ptr, WRITE_BYTE_CMD); + QemuFlashPtrWrite (Ptr, Buffer[Loop]); + Ptr++; } =20 @@ -190,7 +207,7 @@ QemuFlashWrite ( // Restore flash to read mode // if (*NumBytes > 0) { - *(Ptr - 1) =3D READ_ARRAY_CMD; + QemuFlashPtrWrite (Ptr - 1, READ_ARRAY_CMD); } =20 return EFI_SUCCESS; diff --git a/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/QemuFlashDxe.c b/OvmfPk= g/QemuFlashFvbServicesRuntimeDxe/QemuFlashDxe.c index 5aabe9d7b59c..565383ee26d2 100644 --- a/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/QemuFlashDxe.c +++ b/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/QemuFlashDxe.c @@ -10,6 +10,9 @@ **/ =20 #include +#include +#include +#include =20 #include "QemuFlash.h" =20 @@ -32,3 +35,40 @@ QemuFlashBeforeProbe ( // Do nothing // } + +/** + Write to QEMU Flash + + @param[in] Ptr Pointer to the location to write. + @param[in] Value The value to write. + +**/ +VOID +QemuFlashPtrWrite ( + IN volatile UINT8 *Ptr, + IN UINT8 Value + ) +{ + if (MemEncryptSevEsIsEnabled ()) { + MSR_SEV_ES_GHCB_REGISTER Msr; + GHCB *Ghcb; + + Msr.GhcbPhysicalAddress =3D AsmReadMsr64 (MSR_SEV_ES_GHCB); + Ghcb =3D Msr.Ghcb; + + // + // Writing to flash is emulated by the hypervisor through the use of w= rite + // protection. This won't work for an SEV-ES guest because the write w= on't + // be recognized as a true MMIO write, which would result in the requi= red + // #VC exception. Instead, use the the VMGEXIT MMIO write support dire= ctly + // to perform the update. + // + VmgInit (Ghcb); + Ghcb->SharedBuffer[0] =3D Value; + Ghcb->SaveArea.SwScratch =3D (UINT64) (UINTN) Ghcb->SharedBuffer; + VmgExit (Ghcb, SVM_EXIT_MMIO_WRITE, (UINT64) (UINTN) Ptr, 1); + VmgDone (Ghcb); + } else { + *Ptr =3D Value; + } +} diff --git a/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/QemuFlashSmm.c b/OvmfPk= g/QemuFlashFvbServicesRuntimeDxe/QemuFlashSmm.c index 7eb426e03855..7eb80bfeffae 100644 --- a/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/QemuFlashSmm.c +++ b/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/QemuFlashSmm.c @@ -46,3 +46,19 @@ QemuFlashBeforeProbe ( ); ASSERT_EFI_ERROR (Status); } + +/** + Write to QEMU Flash + + @param[in] Ptr Pointer to the location to write. + @param[in] Value The value to write. + +**/ +VOID +QemuFlashPtrWrite ( + IN volatile UINT8 *Ptr, + IN UINT8 Value + ) +{ + *Ptr =3D Value; +} --=20 2.27.0 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#63881): https://edk2.groups.io/g/devel/message/63881 Mute This Topic: https://groups.io/mt/76056597/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-