From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [216.205.24.124]) by mx.groups.io with SMTP id smtpd.web08.352.1619802115983325602 for ; Fri, 30 Apr 2021 10:01:56 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=f0rIpFRA; spf=pass (domain: redhat.com, ip: 216.205.24.124, mailfrom: lersek@redhat.com) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1619802115; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=tMJ22y17AUSXH2r9iMCgzLm5aGepUVAyeVlpqpP6XCA=; b=f0rIpFRAZcHJfc1evRqITkQuUQDHfvpaFKYQytdJGVabNJ9WOb1QjCFZFH/hgajTymveIE sZ8C+WMLhaa+sVtkQpR9gJxsduyuwiLgcMDCRyl5sYAJc/1IImXRBcrpzOMXW1r9RH9LYJ k/2biXpnWZZCmOdun5ynjqw4XxGeoD0= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-9-dL7yExLWPryPeZoYuM7MzQ-1; Fri, 30 Apr 2021 13:01:51 -0400 X-MC-Unique: dL7yExLWPryPeZoYuM7MzQ-1 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id E20C41008063; Fri, 30 Apr 2021 17:01:48 +0000 (UTC) Received: from lacos-laptop-7.usersys.redhat.com (ovpn-112-248.ams2.redhat.com [10.36.112.248]) by smtp.corp.redhat.com (Postfix) with ESMTP id 540A019C66; Fri, 30 Apr 2021 17:01:42 +0000 (UTC) Subject: Re: [edk2-devel] [PATCH v3 4/5] OvmfPkg/Tcg2ConfigPei: Mark TPM MMIO range as unencrypted for SEV-ES To: devel@edk2.groups.io, thomas.lendacky@amd.com Cc: Joerg Roedel , Borislav Petkov , Ard Biesheuvel , Jordan Justen , Brijesh Singh , Erdem Aktas , James Bottomley , Jiewen Yao , Min Xu , =?UTF-8?Q?Marc-Andr=c3=a9_Lureau?= , Stefan Berger References: <42794cec1f9d5bc24cbfb9dcdbe5e281ef259ef5.1619716333.git.thomas.lendacky@amd.com> From: "Laszlo Ersek" Message-ID: <82d61943-eb51-f426-a3a8-43eaec7df6d5@redhat.com> Date: Fri, 30 Apr 2021 19:01:41 +0200 MIME-Version: 1.0 In-Reply-To: <42794cec1f9d5bc24cbfb9dcdbe5e281ef259ef5.1619716333.git.thomas.lendacky@amd.com> X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=lersek@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset=utf-8 Content-Language: en-US Content-Transfer-Encoding: 8bit On 04/29/21 19:12, Lendacky, Thomas wrote: > 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 > Cc: Ard Biesheuvel > Cc: Jordan Justen > Cc: Brijesh Singh > Cc: Erdem Aktas > Cc: James Bottomley > Cc: Jiewen Yao > Cc: Min Xu > Cc: Marc-André Lureau > Cc: Stefan Berger > Signed-off-by: Tom Lendacky > --- > 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/TpmMmioSevDecryptPei/TpmMmioSevDecryptPei.inf | 40 +++++++++ > OvmfPkg/Tcg/TpmMmioSevDecryptPei/TpmMmioSevDecryptPeim.c | 87 ++++++++++++++++++++ > 10 files changed, 135 insertions(+) > > diff --git a/OvmfPkg/AmdSev/AmdSevX64.dsc b/OvmfPkg/AmdSev/AmdSevX64.dsc > index cdb29d53142d..66bbbc80cd18 100644 > --- a/OvmfPkg/AmdSev/AmdSevX64.dsc > +++ b/OvmfPkg/AmdSev/AmdSevX64.dsc > @@ -626,6 +626,7 @@ [Components] > OvmfPkg/AmdSev/SecretPei/SecretPei.inf > > !if $(TPM_ENABLE) == TRUE > + OvmfPkg/Tcg/TpmMmioSevDecryptPei/TpmMmioSevDecryptPei.inf > OvmfPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf > SecurityPkg/Tcg/TcgPei/TcgPei.inf > SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.inf { > diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc > index 1730b6558b5c..33fbd767903e 100644 > --- a/OvmfPkg/OvmfPkgIa32.dsc > +++ b/OvmfPkg/OvmfPkgIa32.dsc > @@ -706,6 +706,7 @@ [Components] > UefiCpuPkg/CpuMpPei/CpuMpPei.inf > > !if $(TPM_ENABLE) == TRUE > + OvmfPkg/Tcg/TpmMmioSevDecryptPei/TpmMmioSevDecryptPei.inf > OvmfPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf > SecurityPkg/Tcg/TcgPei/TcgPei.inf > SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.inf { > diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc > index 78a559da0d0b..b13e5cfd9047 100644 > --- a/OvmfPkg/OvmfPkgIa32X64.dsc > +++ b/OvmfPkg/OvmfPkgIa32X64.dsc > @@ -719,6 +719,7 @@ [Components.IA32] > UefiCpuPkg/CpuMpPei/CpuMpPei.inf > > !if $(TPM_ENABLE) == TRUE > + OvmfPkg/Tcg/TpmMmioSevDecryptPei/TpmMmioSevDecryptPei.inf > OvmfPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf > SecurityPkg/Tcg/TcgPei/TcgPei.inf > SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.inf { > diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc > index a7d747f6b4ab..999738dc39cd 100644 > --- a/OvmfPkg/OvmfPkgX64.dsc > +++ b/OvmfPkg/OvmfPkgX64.dsc > @@ -718,6 +718,7 @@ [Components] > UefiCpuPkg/CpuMpPei/CpuMpPei.inf > > !if $(TPM_ENABLE) == TRUE > + OvmfPkg/Tcg/TpmMmioSevDecryptPei/TpmMmioSevDecryptPei.inf > OvmfPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf > SecurityPkg/Tcg/TcgPei/TcgPei.inf > SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.inf { > diff --git a/OvmfPkg/AmdSev/AmdSevX64.fdf b/OvmfPkg/AmdSev/AmdSevX64.fdf > index c0098502aa90..dd0030dbf189 100644 > --- a/OvmfPkg/AmdSev/AmdSevX64.fdf > +++ b/OvmfPkg/AmdSev/AmdSevX64.fdf > @@ -147,6 +147,7 @@ [FV.PEIFV] > INF OvmfPkg/AmdSev/SecretPei/SecretPei.inf > > !if $(TPM_ENABLE) == TRUE > +INF OvmfPkg/Tcg/TpmMmioSevDecryptPei/TpmMmioSevDecryptPei.inf > INF OvmfPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf > INF SecurityPkg/Tcg/TcgPei/TcgPei.inf > INF SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.inf > diff --git a/OvmfPkg/OvmfPkgIa32.fdf b/OvmfPkg/OvmfPkgIa32.fdf > index f400c845b9c9..b3c8b56f3b60 100644 > --- a/OvmfPkg/OvmfPkgIa32.fdf > +++ b/OvmfPkg/OvmfPkgIa32.fdf > @@ -162,6 +162,7 @@ [FV.PEIFV] > INF UefiCpuPkg/CpuMpPei/CpuMpPei.inf > > !if $(TPM_ENABLE) == TRUE > +INF OvmfPkg/Tcg/TpmMmioSevDecryptPei/TpmMmioSevDecryptPei.inf > INF OvmfPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf > INF SecurityPkg/Tcg/TcgPei/TcgPei.inf > INF SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.inf > diff --git a/OvmfPkg/OvmfPkgIa32X64.fdf b/OvmfPkg/OvmfPkgIa32X64.fdf > index d055552fd09f..86592c2364a3 100644 > --- a/OvmfPkg/OvmfPkgIa32X64.fdf > +++ b/OvmfPkg/OvmfPkgIa32X64.fdf > @@ -162,6 +162,7 @@ [FV.PEIFV] > INF UefiCpuPkg/CpuMpPei/CpuMpPei.inf > > !if $(TPM_ENABLE) == TRUE > +INF OvmfPkg/Tcg/TpmMmioSevDecryptPei/TpmMmioSevDecryptPei.inf > INF OvmfPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf > INF SecurityPkg/Tcg/TcgPei/TcgPei.inf > INF SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.inf > diff --git a/OvmfPkg/OvmfPkgX64.fdf b/OvmfPkg/OvmfPkgX64.fdf > index d519f8532822..d6be798fcadd 100644 > --- a/OvmfPkg/OvmfPkgX64.fdf > +++ b/OvmfPkg/OvmfPkgX64.fdf > @@ -174,6 +174,7 @@ [FV.PEIFV] > INF UefiCpuPkg/CpuMpPei/CpuMpPei.inf > > !if $(TPM_ENABLE) == TRUE > +INF OvmfPkg/Tcg/TpmMmioSevDecryptPei/TpmMmioSevDecryptPei.inf > INF OvmfPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf > INF SecurityPkg/Tcg/TcgPei/TcgPei.inf > INF SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.inf > diff --git a/OvmfPkg/Tcg/TpmMmioSevDecryptPei/TpmMmioSevDecryptPei.inf b/OvmfPkg/Tcg/TpmMmioSevDecryptPei/TpmMmioSevDecryptPei.inf > new file mode 100644 > index 000000000000..51ad6d0d055d > --- /dev/null > +++ b/OvmfPkg/Tcg/TpmMmioSevDecryptPei/TpmMmioSevDecryptPei.inf > @@ -0,0 +1,40 @@ > +## @file > +# Map TPM MMIO range unencrypted when SEV-ES is active. > +# Install gOvmfTpmMmioAccessiblePpiGuid unconditionally. > +# > +# Copyright (C) 2021, Advanced Micro Devices, Inc. > +# > +# SPDX-License-Identifier: BSD-2-Clause-Patent > +## > + > +[Defines] > + INF_VERSION = 1.29 > + 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 > + OvmfPkg/OvmfPkg.dec > + SecurityPkg/SecurityPkg.dec > + > +[LibraryClasses] > + DebugLib > + MemEncryptSevLib > + PcdLib > + 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..df2ad623308d > --- /dev/null > +++ b/OvmfPkg/Tcg/TpmMmioSevDecryptPei/TpmMmioSevDecryptPeim.c > @@ -0,0 +1,87 @@ > +/** @file > + Map TPM MMIO range unencrypted when SEV-ES is active. > + Install gOvmfTpmMmioAccessiblePpiGuid unconditionally. > + > + Copyright (C) 2021, Advanced Micro Devices, Inc. > + > + SPDX-License-Identifier: BSD-2-Clause-Patent > +**/ > + > + > +#include > + > +#include > +#include > +#include > +#include > + > +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 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. > + // > + // If SEV-ES is active, MMIO would succeed against an encrypted physical > + // address because the #VC handler uses the virtual address (which is an > + // identity mapped physical address without the encryption bit) as the guest > + // physical address of the MMIO target in the VMGEXIT. > + // > + // 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/from 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, > + FixedPcdGet64 (PcdTpmBaseAddress), > + EFI_SIZE_TO_PAGES ((UINTN) 0x5000), > + FALSE > + ); > + > + if (RETURN_ERROR (DecryptStatus)) { > + DEBUG ((DEBUG_ERROR, > + "%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; > +} > Reviewed-by: Laszlo Ersek