BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=3275
The SEV-SNP guest requires that GHCB GPA must be registered before using. See the GHCB specification section 2.3.2 for more details. Cc: Michael Roth <michael.r...@amd.com> Cc: James Bottomley <j...@linux.ibm.com> Cc: Min Xu <min.m...@intel.com> Cc: Jiewen Yao <jiewen....@intel.com> Cc: Tom Lendacky <thomas.lenda...@amd.com> Cc: Jordan Justen <jordan.l.jus...@intel.com> Cc: Ard Biesheuvel <ardb+tianoc...@kernel.org> Cc: Erdem Aktas <erdemak...@google.com> Cc: Gerd Hoffmann <kra...@redhat.com> Acked-by: Jiewen Yao <jiewen....@intel.com> Acked-by: Gerd Hoffmann <kra...@redhat.com> Signed-off-by: Brijesh Singh <brijesh.si...@amd.com> --- OvmfPkg/PlatformPei/AmdSev.c | 87 ++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) diff --git a/OvmfPkg/PlatformPei/AmdSev.c b/OvmfPkg/PlatformPei/AmdSev.c index a8bf610022ba..ba69f581893b 100644 --- a/OvmfPkg/PlatformPei/AmdSev.c +++ b/OvmfPkg/PlatformPei/AmdSev.c @@ -19,9 +19,89 @@ #include <PiPei.h> #include <Register/Amd/Msr.h> #include <Register/Intel/SmramSaveStateMap.h> +#include <Library/VmgExitLib.h> #include "Platform.h" +/** + Handle an SEV-SNP/GHCB protocol check failure. + + Notify the hypervisor using the VMGEXIT instruction that the SEV-SNP guest + wishes to be terminated. + + @param[in] ReasonCode Reason code to provide to the hypervisor for the + termination request. + +**/ +STATIC +VOID +SevEsProtocolFailure ( + IN UINT8 ReasonCode + ) +{ + MSR_SEV_ES_GHCB_REGISTER Msr; + + // + // Use the GHCB MSR Protocol to request termination by the hypervisor + // + Msr.GhcbPhysicalAddress = 0; + Msr.GhcbTerminate.Function = GHCB_INFO_TERMINATE_REQUEST; + Msr.GhcbTerminate.ReasonCodeSet = GHCB_TERMINATE_GHCB; + Msr.GhcbTerminate.ReasonCode = ReasonCode; + AsmWriteMsr64 (MSR_SEV_ES_GHCB, Msr.GhcbPhysicalAddress); + + AsmVmgExit (); + + ASSERT (FALSE); + CpuDeadLoop (); +} + +/** + + This function can be used to register the GHCB GPA. + + @param[in] Address The physical address to be registered. + +**/ +STATIC +VOID +GhcbRegister ( + IN EFI_PHYSICAL_ADDRESS Address + ) +{ + MSR_SEV_ES_GHCB_REGISTER Msr; + MSR_SEV_ES_GHCB_REGISTER CurrentMsr; + + // + // Save the current MSR Value + // + CurrentMsr.GhcbPhysicalAddress = AsmReadMsr64 (MSR_SEV_ES_GHCB); + + // + // Use the GHCB MSR Protocol to request to register the GPA. + // + Msr.GhcbPhysicalAddress = Address & ~EFI_PAGE_MASK; + Msr.GhcbGpaRegister.Function = GHCB_INFO_GHCB_GPA_REGISTER_REQUEST; + AsmWriteMsr64 (MSR_SEV_ES_GHCB, Msr.GhcbPhysicalAddress); + + AsmVmgExit (); + + Msr.GhcbPhysicalAddress = AsmReadMsr64 (MSR_SEV_ES_GHCB); + + // + // If hypervisor responded with a different GPA than requested then fail. + // + if ((Msr.GhcbGpaRegister.Function != GHCB_INFO_GHCB_GPA_REGISTER_RESPONSE) || + ((Msr.GhcbPhysicalAddress & ~EFI_PAGE_MASK) != Address)) { + SevEsProtocolFailure (GHCB_TERMINATE_GHCB_GENERAL); + } + + // + // Restore the MSR + // + AsmWriteMsr64 (MSR_SEV_ES_GHCB, CurrentMsr.GhcbPhysicalAddress); +} + /** Initialize SEV-ES support if running as an SEV-ES guest. @@ -109,6 +189,13 @@ AmdSevEsInitialize ( "SEV-ES is enabled, %lu GHCB backup pages allocated starting at 0x%p\n", (UINT64)GhcbBackupPageCount, GhcbBackupBase)); + // + // SEV-SNP guest requires that GHCB GPA must be registered before using it. + // + if (MemEncryptSevSnpIsEnabled ()) { + GhcbRegister (GhcbBasePa); + } + AsmWriteMsr64 (MSR_SEV_ES_GHCB, GhcbBasePa); // -- 2.25.1 -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#83587): https://edk2.groups.io/g/devel/message/83587 Mute This Topic: https://groups.io/mt/86969136/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-