]> git.proxmox.com Git - mirror_edk2.git/commitdiff
OvmfPkg/TpmMmioSevDecryptPei: Mark TPM MMIO range as unencrypted for SEV-ES
authorLendacky, Thomas <thomas.lendacky@amd.com>
Thu, 29 Apr 2021 17:12:13 +0000 (12:12 -0500)
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Fri, 30 Apr 2021 18:35:50 +0000 (18:35 +0000)
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=3345

During PEI, the MMIO range for the TPM is marked as encrypted when running
as an SEV guest. While this isn't an issue for an SEV guest because of
the way the nested page fault is handled, it does result in an SEV-ES
guest terminating because of a mitigation check in the #VC handler to
prevent MMIO to an encrypted address. For an SEV-ES guest, this range
must be marked as unencrypted.

Create a new x86 PEIM for TPM support that will map the TPM MMIO range as
unencrypted when SEV-ES is active. The gOvmfTpmMmioAccessiblePpiGuid PPI
will be unconditionally installed before exiting. The PEIM will exit with
the EFI_ABORTED status so that the PEIM does not stay resident. This new
PEIM will depend on the installation of the permanent PEI RAM, by
PlatformPei, so that in case page table splitting is required during the
clearing of the encryption bit, the new page table(s) will be allocated
from permanent PEI RAM.

Update all OVMF Ia32 and X64 build packages to include this new PEIM.

Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Brijesh Singh <brijesh.singh@amd.com>
Cc: Erdem Aktas <erdemaktas@google.com>
Cc: James Bottomley <jejb@linux.ibm.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Min Xu <min.m.xu@intel.com>
Cc: Marc-André Lureau <marcandre.lureau@redhat.com>
Cc: Stefan Berger <stefanb@linux.ibm.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
Message-Id: <42794cec1f9d5bc24cbfb9dcdbe5e281ef259ef5.1619716333.git.thomas.lendacky@amd.com>
[lersek@redhat.com: refresh subject line]
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
OvmfPkg/AmdSev/AmdSevX64.dsc
OvmfPkg/AmdSev/AmdSevX64.fdf
OvmfPkg/OvmfPkgIa32.dsc
OvmfPkg/OvmfPkgIa32.fdf
OvmfPkg/OvmfPkgIa32X64.dsc
OvmfPkg/OvmfPkgIa32X64.fdf
OvmfPkg/OvmfPkgX64.dsc
OvmfPkg/OvmfPkgX64.fdf
OvmfPkg/Tcg/TpmMmioSevDecryptPei/TpmMmioSevDecryptPei.inf [new file with mode: 0644]
OvmfPkg/Tcg/TpmMmioSevDecryptPei/TpmMmioSevDecryptPeim.c [new file with mode: 0644]

index cdb29d53142df3422e3d9d50386e7d7030ee3bf4..66bbbc80cd18e8f3ef90fbb9cc854c2dee8d4ed9 100644 (file)
   OvmfPkg/AmdSev/SecretPei/SecretPei.inf\r
 \r
 !if $(TPM_ENABLE) == TRUE\r
+  OvmfPkg/Tcg/TpmMmioSevDecryptPei/TpmMmioSevDecryptPei.inf\r
   OvmfPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf\r
   SecurityPkg/Tcg/TcgPei/TcgPei.inf\r
   SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.inf {\r
index c0098502aa9085d27ec99b3218f148b088faf7b2..dd0030dbf18934f71bbd33da373685354ef761a1 100644 (file)
@@ -147,6 +147,7 @@ INF  UefiCpuPkg/CpuMpPei/CpuMpPei.inf
 INF  OvmfPkg/AmdSev/SecretPei/SecretPei.inf\r
 \r
 !if $(TPM_ENABLE) == TRUE\r
+INF  OvmfPkg/Tcg/TpmMmioSevDecryptPei/TpmMmioSevDecryptPei.inf\r
 INF  OvmfPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf\r
 INF  SecurityPkg/Tcg/TcgPei/TcgPei.inf\r
 INF  SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.inf\r
index 1730b6558b5cf896be419579189e8fde8d6b73d8..33fbd767903e07e92bcc0ad6920caf5a7203765a 100644 (file)
   UefiCpuPkg/CpuMpPei/CpuMpPei.inf\r
 \r
 !if $(TPM_ENABLE) == TRUE\r
+  OvmfPkg/Tcg/TpmMmioSevDecryptPei/TpmMmioSevDecryptPei.inf\r
   OvmfPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf\r
   SecurityPkg/Tcg/TcgPei/TcgPei.inf\r
   SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.inf {\r
index f400c845b9c9c279d49c1a21c9b5c21dd3c1c6a6..b3c8b56f3b60e896a75c5e0754c4e027ef791f3a 100644 (file)
@@ -162,6 +162,7 @@ INF  OvmfPkg/SmmAccess/SmmAccessPei.inf
 INF  UefiCpuPkg/CpuMpPei/CpuMpPei.inf\r
 \r
 !if $(TPM_ENABLE) == TRUE\r
+INF  OvmfPkg/Tcg/TpmMmioSevDecryptPei/TpmMmioSevDecryptPei.inf\r
 INF  OvmfPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf\r
 INF  SecurityPkg/Tcg/TcgPei/TcgPei.inf\r
 INF  SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.inf\r
index 78a559da0d0be3ea65eedfaee10d48b99b0c0773..b13e5cfd9047f604ff761a74512a1418d305ee31 100644 (file)
   UefiCpuPkg/CpuMpPei/CpuMpPei.inf\r
 \r
 !if $(TPM_ENABLE) == TRUE\r
+  OvmfPkg/Tcg/TpmMmioSevDecryptPei/TpmMmioSevDecryptPei.inf\r
   OvmfPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf\r
   SecurityPkg/Tcg/TcgPei/TcgPei.inf\r
   SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.inf {\r
index d055552fd09fd6ba60f5a2175c8f6726c2930cbf..86592c2364a357c0470ee582f6a604aeb5513023 100644 (file)
@@ -162,6 +162,7 @@ INF  OvmfPkg/SmmAccess/SmmAccessPei.inf
 INF  UefiCpuPkg/CpuMpPei/CpuMpPei.inf\r
 \r
 !if $(TPM_ENABLE) == TRUE\r
+INF  OvmfPkg/Tcg/TpmMmioSevDecryptPei/TpmMmioSevDecryptPei.inf\r
 INF  OvmfPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf\r
 INF  SecurityPkg/Tcg/TcgPei/TcgPei.inf\r
 INF  SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.inf\r
index a7d747f6b4aba3811a819b2aa8788565e1c74f7c..999738dc39cd479e115ae89a7b06543fa757a80a 100644 (file)
   UefiCpuPkg/CpuMpPei/CpuMpPei.inf\r
 \r
 !if $(TPM_ENABLE) == TRUE\r
+  OvmfPkg/Tcg/TpmMmioSevDecryptPei/TpmMmioSevDecryptPei.inf\r
   OvmfPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf\r
   SecurityPkg/Tcg/TcgPei/TcgPei.inf\r
   SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.inf {\r
index d519f85328227e67ceebf038f13687b378b44689..d6be798fcadd9d153debdb3fced759680dfa30aa 100644 (file)
@@ -174,6 +174,7 @@ INF  OvmfPkg/SmmAccess/SmmAccessPei.inf
 INF  UefiCpuPkg/CpuMpPei/CpuMpPei.inf\r
 \r
 !if $(TPM_ENABLE) == TRUE\r
+INF  OvmfPkg/Tcg/TpmMmioSevDecryptPei/TpmMmioSevDecryptPei.inf\r
 INF  OvmfPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf\r
 INF  SecurityPkg/Tcg/TcgPei/TcgPei.inf\r
 INF  SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.inf\r
diff --git a/OvmfPkg/Tcg/TpmMmioSevDecryptPei/TpmMmioSevDecryptPei.inf b/OvmfPkg/Tcg/TpmMmioSevDecryptPei/TpmMmioSevDecryptPei.inf
new file mode 100644 (file)
index 0000000..51ad6d0
--- /dev/null
@@ -0,0 +1,40 @@
+## @file\r
+# Map TPM MMIO range unencrypted when SEV-ES is active.\r
+# Install gOvmfTpmMmioAccessiblePpiGuid unconditionally.\r
+#\r
+# Copyright (C) 2021, Advanced Micro Devices, Inc.\r
+#\r
+# SPDX-License-Identifier: BSD-2-Clause-Patent\r
+##\r
+\r
+[Defines]\r
+  INF_VERSION                    = 1.29\r
+  BASE_NAME                      = TpmMmioSevDecryptPei\r
+  FILE_GUID                      = F12F698A-E506-4A1B-B32E-6920E55DA1C4\r
+  MODULE_TYPE                    = PEIM\r
+  VERSION_STRING                 = 1.0\r
+  ENTRY_POINT                    = TpmMmioSevDecryptPeimEntryPoint\r
+\r
+[Sources]\r
+  TpmMmioSevDecryptPeim.c\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  OvmfPkg/OvmfPkg.dec\r
+  SecurityPkg/SecurityPkg.dec\r
+\r
+[LibraryClasses]\r
+  DebugLib\r
+  MemEncryptSevLib\r
+  PcdLib\r
+  PeimEntryPoint\r
+  PeiServicesLib\r
+\r
+[Ppis]\r
+  gOvmfTpmMmioAccessiblePpiGuid                      ## PRODUCES\r
+\r
+[FixedPcd]\r
+  gEfiSecurityPkgTokenSpaceGuid.PcdTpmBaseAddress    ## CONSUMES\r
+\r
+[Depex]\r
+  gEfiPeiMemoryDiscoveredPpiGuid\r
diff --git a/OvmfPkg/Tcg/TpmMmioSevDecryptPei/TpmMmioSevDecryptPeim.c b/OvmfPkg/Tcg/TpmMmioSevDecryptPei/TpmMmioSevDecryptPeim.c
new file mode 100644 (file)
index 0000000..df2ad62
--- /dev/null
@@ -0,0 +1,87 @@
+/** @file\r
+  Map TPM MMIO range unencrypted when SEV-ES is active.\r
+  Install gOvmfTpmMmioAccessiblePpiGuid unconditionally.\r
+\r
+  Copyright (C) 2021, Advanced Micro Devices, Inc.\r
+\r
+  SPDX-License-Identifier: BSD-2-Clause-Patent\r
+**/\r
+\r
+\r
+#include <PiPei.h>\r
+\r
+#include <Library/DebugLib.h>\r
+#include <Library/MemEncryptSevLib.h>\r
+#include <Library/PcdLib.h>\r
+#include <Library/PeiServicesLib.h>\r
+\r
+STATIC CONST EFI_PEI_PPI_DESCRIPTOR  mTpmMmioRangeAccessible = {\r
+  EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,\r
+  &gOvmfTpmMmioAccessiblePpiGuid,\r
+  NULL\r
+};\r
+\r
+/**\r
+  The entry point for TPM MMIO range mapping driver.\r
+\r
+  @param[in]  FileHandle   Handle of the file being invoked.\r
+  @param[in]  PeiServices  Describes the list of possible PEI Services.\r
+\r
+  @retval  EFI_ABORTED  No need to keep this PEIM resident\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+TpmMmioSevDecryptPeimEntryPoint (\r
+  IN       EFI_PEI_FILE_HANDLE  FileHandle,\r
+  IN CONST EFI_PEI_SERVICES     **PeiServices\r
+  )\r
+{\r
+  RETURN_STATUS                   DecryptStatus;\r
+  EFI_STATUS                      Status;\r
+\r
+  DEBUG ((DEBUG_INFO, "%a\n", __FUNCTION__));\r
+\r
+  //\r
+  // If SEV is active, MMIO succeeds against an encrypted physical address\r
+  // because the nested page fault (NPF) that occurs on access does not\r
+  // include the encryption bit in the guest physical address provided to the\r
+  // hypervisor.\r
+  //\r
+  // If SEV-ES is active, MMIO would succeed against an encrypted physical\r
+  // address because the #VC handler uses the virtual address (which is an\r
+  // identity mapped physical address without the encryption bit) as the guest\r
+  // physical address of the MMIO target in the VMGEXIT.\r
+  //\r
+  // However, if SEV-ES is active, before performing the actual MMIO, an\r
+  // additional MMIO mitigation check is performed in the #VC handler to ensure\r
+  // that MMIO is being done to/from an unencrypted address. To prevent guest\r
+  // termination in this scenario, mark the range unencrypted ahead of access.\r
+  //\r
+  if (MemEncryptSevEsIsEnabled ()) {\r
+    DEBUG ((DEBUG_INFO,\r
+      "%a: mapping TPM MMIO address range unencrypted\n",\r
+      __FUNCTION__));\r
+\r
+    DecryptStatus = MemEncryptSevClearPageEncMask (\r
+                      0,\r
+                      FixedPcdGet64 (PcdTpmBaseAddress),\r
+                      EFI_SIZE_TO_PAGES ((UINTN) 0x5000),\r
+                      FALSE\r
+                      );\r
+\r
+    if (RETURN_ERROR (DecryptStatus)) {\r
+      DEBUG ((DEBUG_ERROR,\r
+        "%a: failed to map TPM MMIO address range unencrypted\n",\r
+        __FUNCTION__));\r
+      ASSERT_RETURN_ERROR (DecryptStatus);\r
+    }\r
+  }\r
+\r
+  //\r
+  // MMIO range available\r
+  //\r
+  Status = PeiServicesInstallPpi (&mTpmMmioRangeAccessible);\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  return EFI_ABORTED;\r
+}\r