From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from NAM10-BN7-obe.outbound.protection.outlook.com (NAM10-BN7-obe.outbound.protection.outlook.com []) by mx.groups.io with SMTP id smtpd.web11.1675.1580857385855360254 for ; Tue, 04 Feb 2020 15:03:08 -0800 Authentication-Results: mx.groups.io; dkim=pass header.i=@amdcloud.onmicrosoft.com header.s=selector2-amdcloud-onmicrosoft-com header.b=Aek7HjFV; spf=none, err=SPF record not found (domain: amd.com, ip: , mailfrom: thomas.lendacky@amd.com) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=KwaqKhuy83KObgIV93R1wtCTmjv5UmdHClYhawgWpxohzka/AbU5LGZLVzf7k++8vSembkY0ZI1APOj37Uxma2H/JkAG7eumyWYMsDZgYVMJye2SllvV6wBDSiPRfY++yZJTosrnN7nfWkW1SS20EvluNwgUzqKCzcYRKNE2Elw2W9bPii5rVsf31gbymTP/AR2yWc0uDVpGaN0IAmJEnNu1F3Yk37tljthPb8bnoWsT3HNKD3xwH20clKpCm6i2/ekpgPEphAT1lesNZ8metJvp2Uxy48K5U6WG83vMqnoECkWtVTNePbvBY/mD5VsTvoyZIoffce91qSw/tSaGSA== 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=FgGDMsSknsN+X6CJW2+8XkNkOWIiELrvkzZBqfcQ9aA=; b=Pt6Fe/qlxFIKrqkHvPNMusTwEU0e0A0Y6kIGjrKyYxP8GTf+pPB9CzeHsvjj10S+adWFofYvQvrIKtcFz0pfOnkZxvKgJnIBS7PMG81lNo2uUmR8jGf0I562Im6K5O0C225jqP/PVsIcqQ7v/umgeci1WGr1uAM1sUwT8qjcTvXv3rVzrvkC/pPjJwuxCUyiAIK7K/fFN49txw0dHOx1ZzgDt1VPhLj/AIs1HirvickK7tcNFsf1Bda2VNksERCbln6rKx/Iuh5tDLfHXnjygnztDqjBoIWw+il0FgQ2HqtfsXLhDVQXyU2Zh6hHGX08rdz0aq+/YLjpEGHVZbPWgA== 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 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amdcloud.onmicrosoft.com; s=selector2-amdcloud-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=FgGDMsSknsN+X6CJW2+8XkNkOWIiELrvkzZBqfcQ9aA=; b=Aek7HjFVp6XqJ2Wfspy+Ie6yOWPL002qN5XgGGzWxWIsaYO8wxqkEqgduBQyOxLBOmQPdXs6iq4VJDtISHM+1fwguBOUxEGbYIhU2ZvNcukWY1QOHDWrA87mPXdp1ZKMpFdOkQDnh17UX4UsK6V9aqsYU9DeT7abW/q+fUTOCvs= Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=Thomas.Lendacky@amd.com; Received: from DM6PR12MB3163.namprd12.prod.outlook.com (20.179.71.154) by DM6PR12MB3930.namprd12.prod.outlook.com (10.255.174.19) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.2686.29; Tue, 4 Feb 2020 23:03:06 +0000 Received: from DM6PR12MB3163.namprd12.prod.outlook.com ([fe80::a0cd:463:f444:c270]) by DM6PR12MB3163.namprd12.prod.outlook.com ([fe80::a0cd:463:f444:c270%7]) with mapi id 15.20.2707.020; Tue, 4 Feb 2020 23:03:06 +0000 From: "Lendacky, Thomas" To: devel@edk2.groups.io Cc: Jordan Justen , Laszlo Ersek , Ard Biesheuvel , Michael D Kinney , Liming Gao , Eric Dong , Ray Ni , Brijesh Singh Subject: [PATCH v4 34/40] OvmfPkg/QemuFlashFvbServicesRuntimeDxe: Bypass flash detection with SEV-ES is enabled Date: Tue, 4 Feb 2020 17:01:38 -0600 Message-Id: X-Mailer: git-send-email 2.17.1 In-Reply-To: References: X-ClientProxiedBy: SN6PR16CA0062.namprd16.prod.outlook.com (2603:10b6:805:ca::39) To DM6PR12MB3163.namprd12.prod.outlook.com (2603:10b6:5:15e::26) Return-Path: thomas.lendacky@amd.com MIME-Version: 1.0 Received: from tlendack-t1.amd.com (165.204.77.1) by SN6PR16CA0062.namprd16.prod.outlook.com (2603:10b6:805:ca::39) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.2686.32 via Frontend Transport; Tue, 4 Feb 2020 23:02:38 +0000 X-Mailer: git-send-email 2.17.1 X-Originating-IP: [165.204.77.1] X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-HT: Tenant X-MS-Office365-Filtering-Correlation-Id: c89fd06b-b1bf-4165-38d5-08d7a9c654bc X-MS-TrafficTypeDiagnostic: DM6PR12MB3930:|DM6PR12MB3930: X-MS-Exchange-Transport-Forked: True X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:10000; X-Forefront-PRVS: 03030B9493 X-Forefront-Antispam-Report: SFV:NSPM;SFS:(10009020)(4636009)(39860400002)(366004)(376002)(136003)(396003)(346002)(199004)(189003)(4326008)(478600001)(6916009)(81156014)(2616005)(956004)(81166006)(8676002)(966005)(316002)(54906003)(19627235002)(2906002)(6486002)(66476007)(66556008)(52116002)(7696005)(186003)(26005)(16526019)(5660300002)(86362001)(36756003)(66946007)(8936002)(213903007);DIR:OUT;SFP:1101;SCL:1;SRVR:DM6PR12MB3930;H:DM6PR12MB3163.namprd12.prod.outlook.com;FPR:;SPF:None;LANG:en;PTR:InfoNoRecords;A:1;MX:1; Received-SPF: None (protection.outlook.com: amd.com does not designate permitted sender hosts) X-MS-Exchange-SenderADCheck: 1 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: 1K2Q6tW+4rwjNaQ2wVbLV3hRy4MaggdyoY4RHzYfrMOdXF4cLc4IIzZ7Qw2q+Krk7BjSE7VaWyd/5+65rPuRRSWOvowl7KY1spMGUuDkHN+8uS6ZiPTqUQYx6Sz8+aI2bCxQqJeqCe844dQaP+sa9X5GzZs6wHAuJHG9/RFWJC2TWcFcULF+R3Gfarl1TsQS1v3cr3Qgv5sRbiktbygz6vCcMjD52KM4BzmdxbCJSW+E+o6fDfBJsilrBh8ZNSuIZYUt57uCEUBLZyNZfnqX1gWe/a3mHkQTpzFp5SATN/NVbd6PWybXVnWucpINhJBLvLDiuRo3VzT1/sQ61xa7Qc5ZWudfThrT8AVxZoFGpvkOVmyWHja2gz7IViu94EwaMF4IHFEzLR9SHFvcY0lXfwN2Q+H2M3BGwoKJlfmN0TEM04pVt8SkPZHp4kfmHXlkNgKnQZh4egHpWEX3IOSoMx4bB6cYWOfWLk3QXafiSLGyeEnAIijcE/niubS9w7/B82K2Ev2vZwfaZUv2net0tOij8zWRN0rASCtCusbDkGbhbNQUfdV8d+gf/PQGk4Hu X-MS-Exchange-AntiSpam-MessageData: W4Hk4Hx/4EDdI3YRN7owbS2Z8aYjhHQ5JURQjzLlLr63t6hwmtNCrup9t5EYj1wzDSkruo9uU/usMTrTHAikKDKGQrt2L2BZmHlxX65UbTnE1IvBL7jk5D1pRS6fclq7uB1IMq3s0SzmF5+qwboa/Q== X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-Network-Message-Id: c89fd06b-b1bf-4165-38d5-08d7a9c654bc X-MS-Exchange-CrossTenant-OriginalArrivalTime: 04 Feb 2020 23:02:38.9123 (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: vDMHVTtzqZ0chnCs9ixOYidQLmGzysTL9uL0w6xGinfU7jXXEcBai7v4LzYArXhS4Wer+J9DkLr1q2LZwrwRPw== X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM6PR12MB3930 Content-Type: text/plain BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198 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 VmgMmioWrite function from the VmgExitLib library 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 --- OvmfPkg/OvmfPkgIa32.dsc | 1 + OvmfPkg/OvmfPkgIa32X64.dsc | 1 + OvmfPkg/OvmfPkgX64.dsc | 1 + .../FvbServicesRuntimeDxe.inf | 2 ++ .../QemuFlash.h | 6 +++++ .../QemuFlash.c | 23 ++++++++++++++++--- .../QemuFlashDxe.c | 15 ++++++++++++ .../QemuFlashSmm.c | 9 ++++++++ 8 files changed, 55 insertions(+), 3 deletions(-) diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc index c364da521579..ac67fc1bd8b8 100644 --- a/OvmfPkg/OvmfPkgIa32.dsc +++ b/OvmfPkg/OvmfPkgIa32.dsc @@ -320,6 +320,7 @@ [LibraryClasses.common.DXE_RUNTIME_DRIVER] BaseCryptLib|CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf PciLib|OvmfPkg/Library/DxePciLibI440FxQ35/DxePciLibI440FxQ35.inf QemuFwCfgS3Lib|OvmfPkg/Library/QemuFwCfgS3Lib/DxeQemuFwCfgS3LibFwCfg.inf + VmgExitLib|UefiCpuPkg/Library/VmgExitLib/VmgExitLib.inf [LibraryClasses.common.UEFI_DRIVER] PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc index 0adae1e0be30..ecf5c2ad54a3 100644 --- a/OvmfPkg/OvmfPkgIa32X64.dsc +++ b/OvmfPkg/OvmfPkgIa32X64.dsc @@ -325,6 +325,7 @@ [LibraryClasses.common.DXE_RUNTIME_DRIVER] BaseCryptLib|CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf PciLib|OvmfPkg/Library/DxePciLibI440FxQ35/DxePciLibI440FxQ35.inf QemuFwCfgS3Lib|OvmfPkg/Library/QemuFwCfgS3Lib/DxeQemuFwCfgS3LibFwCfg.inf + VmgExitLib|UefiCpuPkg/Library/VmgExitLib/VmgExitLib.inf [LibraryClasses.common.UEFI_DRIVER] PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc index 4b5e96a32b0b..33f7571d4df0 100644 --- a/OvmfPkg/OvmfPkgX64.dsc +++ b/OvmfPkg/OvmfPkgX64.dsc @@ -325,6 +325,7 @@ [LibraryClasses.common.DXE_RUNTIME_DRIVER] BaseCryptLib|CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf PciLib|OvmfPkg/Library/DxePciLibI440FxQ35/DxePciLibI440FxQ35.inf QemuFwCfgS3Lib|OvmfPkg/Library/QemuFwCfgS3Lib/DxeQemuFwCfgS3LibFwCfg.inf + VmgExitLib|UefiCpuPkg/Library/VmgExitLib/VmgExitLib.inf [LibraryClasses.common.UEFI_DRIVER] PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf diff --git a/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf b/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf index ca6326e833ed..0b7741ac07f8 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 [LibraryClasses] @@ -52,6 +53,7 @@ [LibraryClasses] UefiBootServicesTableLib UefiDriverEntryPoint UefiRuntimeLib + VmgExitLib [Guids] gEfiEventVirtualAddressChangeGuid # ALWAYS_CONSUMED diff --git a/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/QemuFlash.h b/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/QemuFlash.h index f1afabcbe6ae..19ac1f733279 100644 --- a/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/QemuFlash.h +++ b/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/QemuFlash.h @@ -89,5 +89,11 @@ QemuFlashBeforeProbe ( IN UINTN FdBlockCount ); +VOID +QemuFlashPtrWrite ( + IN volatile UINT8 *Ptr, + IN UINT8 Value + ); + #endif diff --git a/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/QemuFlash.c b/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/QemuFlash.c index c81c58972bf2..ccf5ad7f7afb 100644 --- a/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/QemuFlash.c +++ b/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/QemuFlash.c @@ -9,6 +9,7 @@ #include #include +#include #include #include "QemuFlash.h" @@ -80,6 +81,21 @@ QemuFlashDetected ( DEBUG ((EFI_D_INFO, "QEMU Flash: Attempting flash detection at %p\n", Ptr)); + 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 that + // the FD appears as ROM and not as FLASH, but report FLASH anyway because + // FLASH behavior can be simulated using VMGEXIT. + // + DEBUG ((DEBUG_INFO, + "QEMU Flash: SEV-ES enabled, assuming FD behaves as FLASH\n")); + return TRUE; + } + OriginalUint8 = *Ptr; *Ptr = CLEAR_STATUS_CMD; ProbeUint8 = *Ptr; @@ -181,8 +197,9 @@ QemuFlashWrite ( // Ptr = QemuFlashPtr (Lba, Offset); for (Loop = 0; Loop < *NumBytes; Loop++) { - *Ptr = WRITE_BYTE_CMD; - *Ptr = Buffer[Loop]; + QemuFlashPtrWrite (Ptr, WRITE_BYTE_CMD); + QemuFlashPtrWrite (Ptr, Buffer[Loop]); + Ptr++; } @@ -190,7 +207,7 @@ QemuFlashWrite ( // Restore flash to read mode // if (*NumBytes > 0) { - *(Ptr - 1) = READ_ARRAY_CMD; + QemuFlashPtrWrite (Ptr - 1, READ_ARRAY_CMD); } return EFI_SUCCESS; diff --git a/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/QemuFlashDxe.c b/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/QemuFlashDxe.c index 5aabe9d7b59c..939463a8e17c 100644 --- a/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/QemuFlashDxe.c +++ b/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/QemuFlashDxe.c @@ -10,6 +10,8 @@ **/ #include +#include +#include #include "QemuFlash.h" @@ -32,3 +34,16 @@ QemuFlashBeforeProbe ( // Do nothing // } + +VOID +QemuFlashPtrWrite ( + IN volatile UINT8 *Ptr, + IN UINT8 Value + ) +{ + if (MemEncryptSevEsIsEnabled()) { + VmgMmioWrite ((UINT8 *) Ptr, &Value, 1); + } else { + *Ptr = Value; + } +} diff --git a/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/QemuFlashSmm.c b/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/QemuFlashSmm.c index 7eb426e03855..eff40ae28032 100644 --- a/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/QemuFlashSmm.c +++ b/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/QemuFlashSmm.c @@ -46,3 +46,12 @@ QemuFlashBeforeProbe ( ); ASSERT_EFI_ERROR (Status); } + +VOID +QemuFlashPtrWrite ( + IN volatile UINT8 *Ptr, + IN UINT8 Value + ) +{ + *Ptr = Value; +} -- 2.17.1