public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: "Lendacky, Thomas" <thomas.lendacky@amd.com>
To: devel@edk2.groups.io
Cc: "Joerg Roedel" <joro@8bytes.org>,
	"Borislav Petkov" <bp@alien8.de>,
	"Laszlo Ersek" <lersek@redhat.com>,
	"Ard Biesheuvel" <ardb+tianocore@kernel.org>,
	"Jordan Justen" <jordan.l.justen@intel.com>,
	"Brijesh Singh" <brijesh.singh@amd.com>,
	"Erdem Aktas" <erdemaktas@google.com>,
	"James Bottomley" <jejb@linux.ibm.com>,
	"Jiewen Yao" <jiewen.yao@intel.com>,
	"Min Xu" <min.m.xu@intel.com>,
	"Marc-André Lureau" <marcandre.lureau@redhat.com>,
	"Stefan Berger" <stefanb@linux.ibm.com>
Subject: [PATCH v2 4/4] OvmfPkg/Tcg2ConfigPei: Mark TPM MMIO range as unencrypted for SEV-ES
Date: Tue, 27 Apr 2021 11:21:10 -0500	[thread overview]
Message-ID: <00ff47c80f180b5b9054890de0ce5e1975fe2b1f.1619540470.git.thomas.lendacky@amd.com> (raw)
In-Reply-To: <cover.1619540470.git.thomas.lendacky@amd.com>

From: Tom Lendacky <thomas.lendacky@amd.com>

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.

The OVMF Tcg2Config PEIM will add the gOvmfTpmMmioAccessiblePpiGuid as a
Depex for IA32 and X64 builds so that the MMIO range is properly mapped
for SEV-ES before the Tcg2Config PEIM is loaded.

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>
---
 OvmfPkg/AmdSev/AmdSevX64.dsc                              |  1 +
 OvmfPkg/OvmfPkgIa32.dsc                                   |  1 +
 OvmfPkg/OvmfPkgIa32X64.dsc                                |  1 +
 OvmfPkg/OvmfPkgX64.dsc                                    |  1 +
 OvmfPkg/AmdSev/AmdSevX64.fdf                              |  1 +
 OvmfPkg/OvmfPkgIa32.fdf                                   |  1 +
 OvmfPkg/OvmfPkgIa32X64.fdf                                |  1 +
 OvmfPkg/OvmfPkgX64.fdf                                    |  1 +
 OvmfPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf                  |  2 +-
 OvmfPkg/Tcg/TpmMmioSevDecryptPei/TpmMmioSevDecryptPei.inf | 40 +++++++++++
 OvmfPkg/Tcg/TpmMmioSevDecryptPei/TpmMmioSevDecryptPeim.c  | 76 ++++++++++++++++++++
 11 files changed, 125 insertions(+), 1 deletion(-)

diff --git a/OvmfPkg/AmdSev/AmdSevX64.dsc b/OvmfPkg/AmdSev/AmdSevX64.dsc
index cdb29d53142d..5a5246c64bf7 100644
--- a/OvmfPkg/AmdSev/AmdSevX64.dsc
+++ b/OvmfPkg/AmdSev/AmdSevX64.dsc
@@ -627,6 +627,7 @@ [Components]
 
 !if $(TPM_ENABLE) == TRUE
   OvmfPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf
+  OvmfPkg/Tcg/TpmMmioSevDecryptPei/TpmMmioSevDecryptPei.inf
   SecurityPkg/Tcg/TcgPei/TcgPei.inf
   SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.inf {
     <LibraryClasses>
diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc
index 1730b6558b5c..a33c14c673a0 100644
--- a/OvmfPkg/OvmfPkgIa32.dsc
+++ b/OvmfPkg/OvmfPkgIa32.dsc
@@ -707,6 +707,7 @@ [Components]
 
 !if $(TPM_ENABLE) == TRUE
   OvmfPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf
+  OvmfPkg/Tcg/TpmMmioSevDecryptPei/TpmMmioSevDecryptPei.inf
   SecurityPkg/Tcg/TcgPei/TcgPei.inf
   SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.inf {
     <LibraryClasses>
diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc
index 78a559da0d0b..a4ff7ed44705 100644
--- a/OvmfPkg/OvmfPkgIa32X64.dsc
+++ b/OvmfPkg/OvmfPkgIa32X64.dsc
@@ -720,6 +720,7 @@ [Components.IA32]
 
 !if $(TPM_ENABLE) == TRUE
   OvmfPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf
+  OvmfPkg/Tcg/TpmMmioSevDecryptPei/TpmMmioSevDecryptPei.inf
   SecurityPkg/Tcg/TcgPei/TcgPei.inf
   SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.inf {
     <LibraryClasses>
diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc
index a7d747f6b4ab..3fb56b3f9ff9 100644
--- a/OvmfPkg/OvmfPkgX64.dsc
+++ b/OvmfPkg/OvmfPkgX64.dsc
@@ -719,6 +719,7 @@ [Components]
 
 !if $(TPM_ENABLE) == TRUE
   OvmfPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf
+  OvmfPkg/Tcg/TpmMmioSevDecryptPei/TpmMmioSevDecryptPei.inf
   SecurityPkg/Tcg/TcgPei/TcgPei.inf
   SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.inf {
     <LibraryClasses>
diff --git a/OvmfPkg/AmdSev/AmdSevX64.fdf b/OvmfPkg/AmdSev/AmdSevX64.fdf
index c0098502aa90..ab58a9c0b4da 100644
--- a/OvmfPkg/AmdSev/AmdSevX64.fdf
+++ b/OvmfPkg/AmdSev/AmdSevX64.fdf
@@ -148,6 +148,7 @@ [FV.PEIFV]
 
 !if $(TPM_ENABLE) == TRUE
 INF  OvmfPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf
+INF  OvmfPkg/Tcg/TpmMmioSevDecryptPei/TpmMmioSevDecryptPei.inf
 INF  SecurityPkg/Tcg/TcgPei/TcgPei.inf
 INF  SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.inf
 !endif
diff --git a/OvmfPkg/OvmfPkgIa32.fdf b/OvmfPkg/OvmfPkgIa32.fdf
index f400c845b9c9..fc0ae1f280df 100644
--- a/OvmfPkg/OvmfPkgIa32.fdf
+++ b/OvmfPkg/OvmfPkgIa32.fdf
@@ -163,6 +163,7 @@ [FV.PEIFV]
 
 !if $(TPM_ENABLE) == TRUE
 INF  OvmfPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf
+INF  OvmfPkg/Tcg/TpmMmioSevDecryptPei/TpmMmioSevDecryptPei.inf
 INF  SecurityPkg/Tcg/TcgPei/TcgPei.inf
 INF  SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.inf
 !endif
diff --git a/OvmfPkg/OvmfPkgIa32X64.fdf b/OvmfPkg/OvmfPkgIa32X64.fdf
index d055552fd09f..306fc5a9b60d 100644
--- a/OvmfPkg/OvmfPkgIa32X64.fdf
+++ b/OvmfPkg/OvmfPkgIa32X64.fdf
@@ -163,6 +163,7 @@ [FV.PEIFV]
 
 !if $(TPM_ENABLE) == TRUE
 INF  OvmfPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf
+INF  OvmfPkg/Tcg/TpmMmioSevDecryptPei/TpmMmioSevDecryptPei.inf
 INF  SecurityPkg/Tcg/TcgPei/TcgPei.inf
 INF  SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.inf
 !endif
diff --git a/OvmfPkg/OvmfPkgX64.fdf b/OvmfPkg/OvmfPkgX64.fdf
index d519f8532822..22c8664427d6 100644
--- a/OvmfPkg/OvmfPkgX64.fdf
+++ b/OvmfPkg/OvmfPkgX64.fdf
@@ -175,6 +175,7 @@ [FV.PEIFV]
 
 !if $(TPM_ENABLE) == TRUE
 INF  OvmfPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf
+INF  OvmfPkg/Tcg/TpmMmioSevDecryptPei/TpmMmioSevDecryptPei.inf
 INF  SecurityPkg/Tcg/TcgPei/TcgPei.inf
 INF  SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.inf
 !endif
diff --git a/OvmfPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf b/OvmfPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf
index 6776ec931ce0..39d1deeed16b 100644
--- a/OvmfPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf
+++ b/OvmfPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf
@@ -57,7 +57,7 @@ [Pcd]
   gEfiSecurityPkgTokenSpaceGuid.PcdTpmInstanceGuid                 ## PRODUCES
 
 [Depex.IA32, Depex.X64]
-  TRUE
+  gOvmfTpmMmioAccessiblePpiGuid
 
 [Depex.ARM, Depex.AARCH64]
   gOvmfTpmDiscoveredPpiGuid
diff --git a/OvmfPkg/Tcg/TpmMmioSevDecryptPei/TpmMmioSevDecryptPei.inf b/OvmfPkg/Tcg/TpmMmioSevDecryptPei/TpmMmioSevDecryptPei.inf
new file mode 100644
index 000000000000..926113b8ffb0
--- /dev/null
+++ b/OvmfPkg/Tcg/TpmMmioSevDecryptPei/TpmMmioSevDecryptPei.inf
@@ -0,0 +1,40 @@
+## @file
+# Map TPM MMIO range unencrypted when SEV is active
+#
+# Copyright (C) 2021, Advanced Micro Devices, Inc.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = TpmMmioSevDecryptPei
+  FILE_GUID                      = F12F698A-E506-4A1B-B32E-6920E55DA1C4
+  MODULE_TYPE                    = PEIM
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = TpmMmioSevDecryptPeimEntryPoint
+
+[Sources]
+  TpmMmioSevDecryptPeim.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  OvmfPkg/OvmfPkg.dec
+  SecurityPkg/SecurityPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  DebugLib
+  MemEncryptSevLib
+  PeimEntryPoint
+  PeiServicesLib
+
+[Ppis]
+  gOvmfTpmMmioAccessiblePpiGuid                      ## PRODUCES
+
+[FixedPcd]
+  gEfiSecurityPkgTokenSpaceGuid.PcdTpmBaseAddress    ## CONSUMES
+
+[Depex]
+  gEfiPeiMemoryDiscoveredPpiGuid
diff --git a/OvmfPkg/Tcg/TpmMmioSevDecryptPei/TpmMmioSevDecryptPeim.c b/OvmfPkg/Tcg/TpmMmioSevDecryptPei/TpmMmioSevDecryptPeim.c
new file mode 100644
index 000000000000..dd1f1a80b5b0
--- /dev/null
+++ b/OvmfPkg/Tcg/TpmMmioSevDecryptPei/TpmMmioSevDecryptPeim.c
@@ -0,0 +1,76 @@
+/** @file
+  Map TPM MMIO range unencrypted when SEV is active
+
+  Copyright (C) 2021, Advanced Micro Devices, Inc.
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+
+#include <PiPei.h>
+
+#include <Library/DebugLib.h>
+#include <Library/MemEncryptSevLib.h>
+#include <Library/PeiServicesLib.h>
+
+STATIC CONST EFI_PEI_PPI_DESCRIPTOR  mTpmMmioRangeAccessible = {
+  EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+  &gOvmfTpmMmioAccessiblePpiGuid,
+  NULL
+};
+
+/**
+  The entry point for TPM MMIO range mapping driver.
+
+  @param[in]  FileHandle   Handle of the file being invoked.
+  @param[in]  PeiServices  Describes the list of possible PEI Services.
+
+  @retval  EFI_ABORTED  No need to keep this PEIM resident
+**/
+EFI_STATUS
+EFIAPI
+TpmMmioSevDecryptPeimEntryPoint (
+  IN       EFI_PEI_FILE_HANDLE  FileHandle,
+  IN CONST EFI_PEI_SERVICES     **PeiServices
+  )
+{
+  RETURN_STATUS                   DecryptStatus;
+  EFI_STATUS                      Status;
+
+  DEBUG ((DEBUG_INFO, "%a\n", __FUNCTION__));
+
+  //
+  // If SEV or SEV-ES is active, MMIO succeeds against an encrypted physical
+  // address because the nested page fault (NPF) that occurs on access does not
+  // include the encryption bit in the guest physical address provided to the
+  // hypervisor.
+  //
+  // However, if SEV-ES is active, before performing the actual MMIO, an
+  // additional MMIO mitigation check is performed in the #VC handler to ensure
+  // that MMIO is being done to an unencrypted address. To prevent guest
+  // termination in this scenario, mark the range unencrypted ahead of access.
+  //
+  if (MemEncryptSevEsIsEnabled ()) {
+    DEBUG ((DEBUG_INFO, "%a: mapping TPM MMIO address range unencrypted\n", __FUNCTION__));
+
+    DecryptStatus = MemEncryptSevClearPageEncMask (
+                      0,
+                      PcdGet64 (PcdTpmBaseAddress),
+                      EFI_SIZE_TO_PAGES ((UINTN) 0x5000),
+                      FALSE
+                      );
+
+    if (RETURN_ERROR (DecryptStatus)) {
+      DEBUG ((DEBUG_INFO, "%a: failed to map TPM MMIO address range unencrypted\n", __FUNCTION__));
+      ASSERT_RETURN_ERROR (DecryptStatus);
+    }
+  }
+
+  //
+  // MMIO range available
+  //
+  Status = PeiServicesInstallPpi (&mTpmMmioRangeAccessible);
+  ASSERT_EFI_ERROR (Status);
+
+  return EFI_ABORTED;
+}
-- 
2.31.0


  parent reply	other threads:[~2021-04-27 16:22 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-04-27 16:21 [PATCH v2 0/4] SEV-ES TPM enablement fixes Lendacky, Thomas
2021-04-27 16:21 ` [PATCH v2 1/4] OvfmPkg/VmgExitLib: Properly decode MMIO MOVZX and MOVSX opcodes Lendacky, Thomas
2021-04-28 17:04   ` [edk2-devel] " Laszlo Ersek
2021-04-27 16:21 ` [PATCH v2 2/4] OvmfPkg/VmgExitLib: Add support for new MMIO MOV opcodes Lendacky, Thomas
2021-04-28 17:09   ` [edk2-devel] " Laszlo Ersek
2021-04-27 16:21 ` [PATCH v2 3/4] OvmfPkg: Define a new PPI GUID to signal TPM MMIO accessability Lendacky, Thomas
2021-04-28 17:12   ` [edk2-devel] " Laszlo Ersek
2021-04-28 17:15     ` Laszlo Ersek
2021-04-28 19:25       ` Lendacky, Thomas
2021-04-27 16:21 ` Lendacky, Thomas [this message]
2021-04-28 17:51   ` [edk2-devel] [PATCH v2 4/4] OvmfPkg/Tcg2ConfigPei: Mark TPM MMIO range as unencrypted for SEV-ES Laszlo Ersek
2021-04-28 19:43     ` Lendacky, Thomas
2021-04-29  1:33       ` Lendacky, Thomas
2021-04-30 15:48       ` Laszlo Ersek
2021-04-30 17:57         ` Lendacky, Thomas

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=00ff47c80f180b5b9054890de0ce5e1975fe2b1f.1619540470.git.thomas.lendacky@amd.com \
    --to=devel@edk2.groups.io \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox