summaryrefslogtreecommitdiffstats
path: root/OvmfPkg
diff options
context:
space:
mode:
authorBrijesh Singh <brijesh.singh@amd.com>2021-12-09 11:27:40 +0800
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>2021-12-09 06:28:10 +0000
commita19b648952c4730bf0876fa13d446fe80ebb5cc3 (patch)
treec70345773a28d1ef7f2cc4d2e35c78bda0a4d38f /OvmfPkg
parentd2b998fbdca463ddcd8dc1407039a6e82578039f (diff)
downloadedk2-a19b648952c4730bf0876fa13d446fe80ebb5cc3.tar.gz
edk2-a19b648952c4730bf0876fa13d446fe80ebb5cc3.tar.bz2
edk2-a19b648952c4730bf0876fa13d446fe80ebb5cc3.zip
OvmfPkg/PlatformPei: register GHCB gpa for the SEV-SNP guest
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.roth@amd.com> Cc: James Bottomley <jejb@linux.ibm.com> Cc: Min Xu <min.m.xu@intel.com> Cc: Jiewen Yao <jiewen.yao@intel.com> Cc: Tom Lendacky <thomas.lendacky@amd.com> Cc: Jordan Justen <jordan.l.justen@intel.com> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org> Cc: Erdem Aktas <erdemaktas@google.com> Cc: Gerd Hoffmann <kraxel@redhat.com> Acked-by: Jiewen Yao <Jiewen.yao@intel.com> Acked-by: Gerd Hoffmann <kraxel@redhat.com> Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
Diffstat (limited to 'OvmfPkg')
-rw-r--r--OvmfPkg/PlatformPei/AmdSev.c88
1 files changed, 88 insertions, 0 deletions
diff --git a/OvmfPkg/PlatformPei/AmdSev.c b/OvmfPkg/PlatformPei/AmdSev.c
index 3991edfd1e..f66e0a7f4a 100644
--- a/OvmfPkg/PlatformPei/AmdSev.c
+++ b/OvmfPkg/PlatformPei/AmdSev.c
@@ -19,10 +19,91 @@
#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.
@@ -115,6 +196,13 @@ AmdSevEsInitialize (
GhcbBackupBase
));
+ //
+ // SEV-SNP guest requires that GHCB GPA must be registered before using it.
+ //
+ if (MemEncryptSevSnpIsEnabled ()) {
+ GhcbRegister (GhcbBasePa);
+ }
+
AsmWriteMsr64 (MSR_SEV_ES_GHCB, GhcbBasePa);
//