mirror of https://github.com/acidanthera/audk.git
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>
This commit is contained in:
parent
d2b998fbdc
commit
a19b648952
|
@ -19,9 +19,90 @@
|
|||
#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);
|
||||
|
||||
//
|
||||
|
|
Loading…
Reference in New Issue