mirror of https://github.com/acidanthera/audk.git
OvmfPkg/SecMain: 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
d9822304ce
commit
7c3b2892ea
|
@ -48,6 +48,104 @@ SevEsProtocolFailure (
|
|||
CpuDeadLoop ();
|
||||
}
|
||||
|
||||
/**
|
||||
Determine if SEV-SNP is active.
|
||||
|
||||
@retval TRUE SEV-SNP is enabled
|
||||
@retval FALSE SEV-SNP is not enabled
|
||||
|
||||
**/
|
||||
STATIC
|
||||
BOOLEAN
|
||||
SevSnpIsEnabled (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
MSR_SEV_STATUS_REGISTER Msr;
|
||||
|
||||
//
|
||||
// Read the SEV_STATUS MSR to determine whether SEV-SNP is active.
|
||||
//
|
||||
Msr.Uint32 = AsmReadMsr32 (MSR_SEV_STATUS);
|
||||
|
||||
//
|
||||
// Check MSR_0xC0010131 Bit 2 (Sev-Snp Enabled)
|
||||
//
|
||||
if (Msr.Bits.SevSnpBit) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
Register the GHCB GPA
|
||||
|
||||
*/
|
||||
STATIC
|
||||
VOID
|
||||
SevSnpGhcbRegister (
|
||||
EFI_PHYSICAL_ADDRESS Address
|
||||
)
|
||||
{
|
||||
MSR_SEV_ES_GHCB_REGISTER Msr;
|
||||
|
||||
//
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Verify that Hypervisor supports the SNP feature.
|
||||
|
||||
*/
|
||||
STATIC
|
||||
BOOLEAN
|
||||
HypervisorSnpFeatureCheck (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
MSR_SEV_ES_GHCB_REGISTER Msr;
|
||||
UINT64 Features;
|
||||
|
||||
//
|
||||
// Use the GHCB MSR Protocol to query the hypervisor capabilities
|
||||
//
|
||||
Msr.GhcbPhysicalAddress = 0;
|
||||
Msr.GhcbHypervisorFeatures.Function = GHCB_HYPERVISOR_FEATURES_REQUEST;
|
||||
AsmWriteMsr64 (MSR_SEV_ES_GHCB, Msr.GhcbPhysicalAddress);
|
||||
|
||||
AsmVmgExit ();
|
||||
|
||||
Msr.GhcbPhysicalAddress = AsmReadMsr64 (MSR_SEV_ES_GHCB);
|
||||
|
||||
Features = RShiftU64 (Msr.GhcbPhysicalAddress, 12);
|
||||
|
||||
if ((Msr.GhcbHypervisorFeatures.Function != GHCB_HYPERVISOR_FEATURES_RESPONSE) ||
|
||||
(!(Features & GHCB_HV_FEATURES_SNP)))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
Validate the SEV-ES/GHCB protocol level.
|
||||
|
||||
|
@ -89,6 +187,27 @@ SevEsProtocolCheck (
|
|||
SevEsProtocolFailure (GHCB_TERMINATE_GHCB_PROTOCOL);
|
||||
}
|
||||
|
||||
//
|
||||
// We cannot use the MemEncryptSevSnpIsEnabled () because the
|
||||
// ProcessLibraryConstructorList () is not called yet.
|
||||
//
|
||||
if (SevSnpIsEnabled ()) {
|
||||
//
|
||||
// Check if hypervisor supports the SNP feature
|
||||
//
|
||||
if (!HypervisorSnpFeatureCheck ()) {
|
||||
SevEsProtocolFailure (GHCB_TERMINATE_GHCB_PROTOCOL);
|
||||
}
|
||||
|
||||
//
|
||||
// Unlike the SEV-ES guest, the SNP requires that GHCB GPA must be
|
||||
// registered with the Hypervisor before the use. This can be done
|
||||
// using the new VMGEXIT defined in the GHCB v2. Register the GPA
|
||||
// before it is used.
|
||||
//
|
||||
SevSnpGhcbRegister ((EFI_PHYSICAL_ADDRESS)(UINTN)FixedPcdGet32 (PcdOvmfSecGhcbBase));
|
||||
}
|
||||
|
||||
//
|
||||
// SEV-ES protocol checking succeeded, set the initial GHCB address
|
||||
//
|
||||
|
|
Loading…
Reference in New Issue