BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4654 An SVSM requires a calling area page whose address (CAA) is used by the SVSM to communicate and process the SVSM request. Add a pre-defined page area to the OvmfPkg and AmdSev packages and define corresponding PCDs used to communicate the location and size of the area. Keep the AmdSev package in sync with the OvmfPkg and adjust the AmdSev launch and hash area memory locations. Cc: Ard Biesheuvel <ardb+tianocore@kernel.org> Cc: Erdem Aktas <erdemaktas@google.com> Cc: Gerd Hoffmann <kraxel@redhat.com> Cc: Jiewen Yao <jiewen.yao@intel.com> Cc: Laszlo Ersek <lersek@redhat.com> Cc: Michael Roth <michael.roth@amd.com> Cc: Min Xu <min.m.xu@intel.com> Acked-by: Gerd Hoffmann <kraxel@redhat.com> Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
571 lines
16 KiB
C
571 lines
16 KiB
C
/**@file
|
|
Initialize Secure Encrypted Virtualization (SEV) support
|
|
|
|
Copyright (c) 2017 - 2024, Advanced Micro Devices. All rights reserved.<BR>
|
|
|
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
|
|
|
**/
|
|
//
|
|
// The package level header files this module uses
|
|
//
|
|
#include <Guid/GhcbApicIds.h>
|
|
#include <IndustryStandard/Q35MchIch9.h>
|
|
#include <Library/BaseMemoryLib.h>
|
|
#include <Library/DebugLib.h>
|
|
#include <Library/HobLib.h>
|
|
#include <Library/MemEncryptSevLib.h>
|
|
#include <Library/MemoryAllocationLib.h>
|
|
#include <Library/PcdLib.h>
|
|
#include <Pi/PrePiHob.h>
|
|
#include <PiPei.h>
|
|
#include <Register/Amd/Msr.h>
|
|
#include <Register/Intel/SmramSaveStateMap.h>
|
|
#include <Library/CcExitLib.h>
|
|
#include <ConfidentialComputingGuestAttr.h>
|
|
|
|
#include "Platform.h"
|
|
|
|
STATIC
|
|
UINT64
|
|
GetHypervisorFeature (
|
|
VOID
|
|
);
|
|
|
|
/**
|
|
Retrieve APIC IDs from the hypervisor.
|
|
|
|
**/
|
|
STATIC
|
|
VOID
|
|
AmdSevSnpGetApicIds (
|
|
VOID
|
|
)
|
|
{
|
|
MSR_SEV_ES_GHCB_REGISTER Msr;
|
|
GHCB *Ghcb;
|
|
BOOLEAN InterruptState;
|
|
UINT64 VmgExitStatus;
|
|
UINT64 PageCount;
|
|
BOOLEAN PageCountValid;
|
|
VOID *ApicIds;
|
|
RETURN_STATUS Status;
|
|
UINT64 GuidData;
|
|
|
|
Msr.GhcbPhysicalAddress = AsmReadMsr64 (MSR_SEV_ES_GHCB);
|
|
Ghcb = Msr.Ghcb;
|
|
|
|
PageCount = 0;
|
|
PageCountValid = FALSE;
|
|
|
|
CcExitVmgInit (Ghcb, &InterruptState);
|
|
Ghcb->SaveArea.Rax = PageCount;
|
|
CcExitVmgSetOffsetValid (Ghcb, GhcbRax);
|
|
VmgExitStatus = CcExitVmgExit (Ghcb, SVM_EXIT_GET_APIC_IDS, 0, 0);
|
|
if (CcExitVmgIsOffsetValid (Ghcb, GhcbRax)) {
|
|
PageCount = Ghcb->SaveArea.Rax;
|
|
PageCountValid = TRUE;
|
|
}
|
|
|
|
CcExitVmgDone (Ghcb, InterruptState);
|
|
|
|
ASSERT (VmgExitStatus == 0);
|
|
ASSERT (PageCountValid);
|
|
if ((VmgExitStatus != 0) || !PageCountValid) {
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Allocate the memory for the APIC IDs
|
|
//
|
|
ApicIds = AllocateReservedPages ((UINTN)PageCount);
|
|
ASSERT (ApicIds != NULL);
|
|
|
|
Status = MemEncryptSevClearPageEncMask (
|
|
0,
|
|
(UINTN)ApicIds,
|
|
(UINTN)PageCount
|
|
);
|
|
ASSERT_RETURN_ERROR (Status);
|
|
|
|
ZeroMem (ApicIds, EFI_PAGES_TO_SIZE ((UINTN)PageCount));
|
|
|
|
PageCountValid = FALSE;
|
|
|
|
CcExitVmgInit (Ghcb, &InterruptState);
|
|
Ghcb->SaveArea.Rax = PageCount;
|
|
CcExitVmgSetOffsetValid (Ghcb, GhcbRax);
|
|
VmgExitStatus = CcExitVmgExit (Ghcb, SVM_EXIT_GET_APIC_IDS, (UINTN)ApicIds, 0);
|
|
if (CcExitVmgIsOffsetValid (Ghcb, GhcbRax) && (Ghcb->SaveArea.Rax == PageCount)) {
|
|
PageCountValid = TRUE;
|
|
}
|
|
|
|
CcExitVmgDone (Ghcb, InterruptState);
|
|
|
|
ASSERT (VmgExitStatus == 0);
|
|
ASSERT (PageCountValid);
|
|
if ((VmgExitStatus != 0) || !PageCountValid) {
|
|
FreePages (ApicIds, (UINTN)PageCount);
|
|
return;
|
|
}
|
|
|
|
GuidData = (UINT64)(UINTN)ApicIds;
|
|
BuildGuidDataHob (&gGhcbApicIdsGuid, &GuidData, sizeof (GuidData));
|
|
}
|
|
|
|
/**
|
|
Initialize SEV-SNP support if running as an SEV-SNP guest.
|
|
|
|
**/
|
|
STATIC
|
|
VOID
|
|
AmdSevSnpInitialize (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_PEI_HOB_POINTERS Hob;
|
|
EFI_HOB_RESOURCE_DESCRIPTOR *ResourceHob;
|
|
UINT64 HvFeatures;
|
|
EFI_STATUS PcdStatus;
|
|
|
|
if (!MemEncryptSevSnpIsEnabled ()) {
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Query the hypervisor feature using the CcExitVmgExit and set the value in the
|
|
// hypervisor features PCD.
|
|
//
|
|
HvFeatures = GetHypervisorFeature ();
|
|
PcdStatus = PcdSet64S (PcdGhcbHypervisorFeatures, HvFeatures);
|
|
ASSERT_RETURN_ERROR (PcdStatus);
|
|
|
|
//
|
|
// Iterate through the system RAM and validate it.
|
|
//
|
|
for (Hob.Raw = GetHobList (); !END_OF_HOB_LIST (Hob); Hob.Raw = GET_NEXT_HOB (Hob)) {
|
|
if ((Hob.Raw != NULL) && (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR)) {
|
|
ResourceHob = Hob.ResourceDescriptor;
|
|
|
|
if (ResourceHob->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) {
|
|
if (ResourceHob->PhysicalStart >= SIZE_4GB) {
|
|
ResourceHob->ResourceType = BZ3937_EFI_RESOURCE_MEMORY_UNACCEPTED;
|
|
continue;
|
|
}
|
|
|
|
MemEncryptSevSnpPreValidateSystemRam (
|
|
ResourceHob->PhysicalStart,
|
|
EFI_SIZE_TO_PAGES ((UINTN)ResourceHob->ResourceLength)
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Retrieve the APIC IDs if the hypervisor supports it. These will be used
|
|
// to always start APs using SNP AP Create.
|
|
//
|
|
if ((HvFeatures & GHCB_HV_FEATURES_APIC_ID_LIST) == GHCB_HV_FEATURES_APIC_ID_LIST) {
|
|
AmdSevSnpGetApicIds ();
|
|
}
|
|
}
|
|
|
|
/**
|
|
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 ();
|
|
}
|
|
|
|
/**
|
|
Get the hypervisor features bitmap
|
|
|
|
**/
|
|
STATIC
|
|
UINT64
|
|
GetHypervisorFeature (
|
|
VOID
|
|
)
|
|
{
|
|
UINT64 Status;
|
|
GHCB *Ghcb;
|
|
MSR_SEV_ES_GHCB_REGISTER Msr;
|
|
BOOLEAN InterruptState;
|
|
UINT64 Features;
|
|
|
|
Msr.GhcbPhysicalAddress = AsmReadMsr64 (MSR_SEV_ES_GHCB);
|
|
Ghcb = Msr.Ghcb;
|
|
|
|
//
|
|
// Initialize the GHCB
|
|
//
|
|
CcExitVmgInit (Ghcb, &InterruptState);
|
|
|
|
//
|
|
// Query the Hypervisor Features.
|
|
//
|
|
Status = CcExitVmgExit (Ghcb, SVM_EXIT_HYPERVISOR_FEATURES, 0, 0);
|
|
if ((Status != 0)) {
|
|
SevEsProtocolFailure (GHCB_TERMINATE_GHCB_GENERAL);
|
|
}
|
|
|
|
Features = Ghcb->SaveArea.SwExitInfo2;
|
|
|
|
CcExitVmgDone (Ghcb, InterruptState);
|
|
|
|
return Features;
|
|
}
|
|
|
|
/**
|
|
|
|
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.
|
|
|
|
**/
|
|
STATIC
|
|
VOID
|
|
AmdSevEsInitialize (
|
|
IN EFI_HOB_PLATFORM_INFO *PlatformInfoHob
|
|
)
|
|
{
|
|
UINT8 *GhcbBase;
|
|
PHYSICAL_ADDRESS GhcbBasePa;
|
|
UINTN GhcbPageCount;
|
|
UINT8 *GhcbBackupBase;
|
|
UINT8 *GhcbBackupPages;
|
|
UINTN GhcbBackupPageCount;
|
|
SEV_ES_PER_CPU_DATA *SevEsData;
|
|
UINTN PageCount;
|
|
RETURN_STATUS Status;
|
|
IA32_DESCRIPTOR Gdtr;
|
|
VOID *Gdt;
|
|
|
|
if (!MemEncryptSevEsIsEnabled ()) {
|
|
return;
|
|
}
|
|
|
|
Status = PcdSetBoolS (PcdSevEsIsEnabled, TRUE);
|
|
ASSERT_RETURN_ERROR (Status);
|
|
|
|
//
|
|
// Allocate GHCB and per-CPU variable pages.
|
|
// Since the pages must survive across the UEFI to OS transition
|
|
// make them reserved.
|
|
//
|
|
GhcbPageCount = PlatformInfoHob->PcdCpuMaxLogicalProcessorNumber * 2;
|
|
GhcbBase = AllocateReservedPages (GhcbPageCount);
|
|
ASSERT (GhcbBase != NULL);
|
|
|
|
GhcbBasePa = (PHYSICAL_ADDRESS)(UINTN)GhcbBase;
|
|
|
|
//
|
|
// Each vCPU gets two consecutive pages, the first is the GHCB and the
|
|
// second is the per-CPU variable page. Loop through the allocation and
|
|
// only clear the encryption mask for the GHCB pages.
|
|
//
|
|
for (PageCount = 0; PageCount < GhcbPageCount; PageCount += 2) {
|
|
Status = MemEncryptSevClearPageEncMask (
|
|
0,
|
|
GhcbBasePa + EFI_PAGES_TO_SIZE (PageCount),
|
|
1
|
|
);
|
|
ASSERT_RETURN_ERROR (Status);
|
|
}
|
|
|
|
ZeroMem (GhcbBase, EFI_PAGES_TO_SIZE (GhcbPageCount));
|
|
|
|
Status = PcdSet64S (PcdGhcbBase, GhcbBasePa);
|
|
ASSERT_RETURN_ERROR (Status);
|
|
Status = PcdSet64S (PcdGhcbSize, EFI_PAGES_TO_SIZE (GhcbPageCount));
|
|
ASSERT_RETURN_ERROR (Status);
|
|
|
|
DEBUG ((
|
|
DEBUG_INFO,
|
|
"SEV-ES is enabled, %lu GHCB pages allocated starting at 0x%p\n",
|
|
(UINT64)GhcbPageCount,
|
|
GhcbBase
|
|
));
|
|
|
|
//
|
|
// Allocate #VC recursion backup pages. The number of backup pages needed is
|
|
// one less than the maximum VC count.
|
|
//
|
|
GhcbBackupPageCount = PlatformInfoHob->PcdCpuMaxLogicalProcessorNumber * (VMGEXIT_MAXIMUM_VC_COUNT - 1);
|
|
GhcbBackupBase = AllocatePages (GhcbBackupPageCount);
|
|
ASSERT (GhcbBackupBase != NULL);
|
|
|
|
GhcbBackupPages = GhcbBackupBase;
|
|
for (PageCount = 1; PageCount < GhcbPageCount; PageCount += 2) {
|
|
SevEsData =
|
|
(SEV_ES_PER_CPU_DATA *)(GhcbBase + EFI_PAGES_TO_SIZE (PageCount));
|
|
SevEsData->GhcbBackupPages = GhcbBackupPages;
|
|
|
|
GhcbBackupPages += EFI_PAGE_SIZE * (VMGEXIT_MAXIMUM_VC_COUNT - 1);
|
|
}
|
|
|
|
DEBUG ((
|
|
DEBUG_INFO,
|
|
"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);
|
|
|
|
//
|
|
// Now that the PEI GHCB is set up, the SEC GHCB page is no longer necessary
|
|
// to keep shared. Later, it is exposed to the OS as EfiConventionalMemory, so
|
|
// it needs to be marked private. The size of the region is hardcoded in
|
|
// OvmfPkg/ResetVector/ResetVector.nasmb in the definition of
|
|
// SNP_SEC_MEM_BASE_DESC_2.
|
|
//
|
|
Status = MemEncryptSevSetPageEncMask (
|
|
0, // Cr3 -- use system Cr3
|
|
FixedPcdGet32 (PcdOvmfSecGhcbBase), // BaseAddress
|
|
1 // NumPages
|
|
);
|
|
ASSERT_RETURN_ERROR (Status);
|
|
|
|
//
|
|
// The SEV support will clear the C-bit from non-RAM areas. The early GDT
|
|
// lives in a non-RAM area, so when an exception occurs (like a #VC) the GDT
|
|
// will be read as un-encrypted even though it was created before the C-bit
|
|
// was cleared (encrypted). This will result in a failure to be able to
|
|
// handle the exception.
|
|
//
|
|
AsmReadGdtr (&Gdtr);
|
|
|
|
Gdt = AllocatePages (EFI_SIZE_TO_PAGES ((UINTN)Gdtr.Limit + 1));
|
|
ASSERT (Gdt != NULL);
|
|
|
|
CopyMem (Gdt, (VOID *)Gdtr.Base, Gdtr.Limit + 1);
|
|
Gdtr.Base = (UINTN)Gdt;
|
|
AsmWriteGdtr (&Gdtr);
|
|
}
|
|
|
|
/**
|
|
|
|
Function checks if SEV support is available, if present then it sets
|
|
the dynamic PcdPteMemoryEncryptionAddressOrMask with memory encryption mask.
|
|
|
|
**/
|
|
VOID
|
|
AmdSevInitialize (
|
|
IN OUT EFI_HOB_PLATFORM_INFO *PlatformInfoHob
|
|
)
|
|
{
|
|
UINT64 EncryptionMask;
|
|
RETURN_STATUS PcdStatus;
|
|
|
|
//
|
|
// Check if SEV is enabled
|
|
//
|
|
if (!MemEncryptSevIsEnabled ()) {
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Check and perform SEV-SNP initialization if required. This need to be
|
|
// done before the GHCB page is made shared in the AmdSevEsInitialize(). This
|
|
// is because the system RAM must be validated before it is made shared.
|
|
// The AmdSevSnpInitialize() validates the system RAM.
|
|
//
|
|
AmdSevSnpInitialize ();
|
|
|
|
//
|
|
// Set Memory Encryption Mask PCD
|
|
//
|
|
EncryptionMask = MemEncryptSevGetEncryptionMask ();
|
|
PcdStatus = PcdSet64S (PcdPteMemoryEncryptionAddressOrMask, EncryptionMask);
|
|
ASSERT_RETURN_ERROR (PcdStatus);
|
|
|
|
DEBUG ((DEBUG_INFO, "SEV is enabled (mask 0x%lx)\n", EncryptionMask));
|
|
|
|
//
|
|
// Set Pcd to Deny the execution of option ROM when security
|
|
// violation.
|
|
//
|
|
PcdStatus = PcdSet32S (PcdOptionRomImageVerificationPolicy, 0x4);
|
|
ASSERT_RETURN_ERROR (PcdStatus);
|
|
|
|
//
|
|
// When SMM is required, cover the pages containing the initial SMRAM Save
|
|
// State Map with a memory allocation HOB:
|
|
//
|
|
// There's going to be a time interval between our decrypting those pages for
|
|
// SMBASE relocation and re-encrypting the same pages after SMBASE
|
|
// relocation. We shall ensure that the DXE phase stay away from those pages
|
|
// until after re-encryption, in order to prevent an information leak to the
|
|
// hypervisor.
|
|
//
|
|
if (PlatformInfoHob->SmmSmramRequire && (PlatformInfoHob->BootMode != BOOT_ON_S3_RESUME)) {
|
|
RETURN_STATUS LocateMapStatus;
|
|
UINTN MapPagesBase;
|
|
UINTN MapPagesCount;
|
|
|
|
LocateMapStatus = MemEncryptSevLocateInitialSmramSaveStateMapPages (
|
|
&MapPagesBase,
|
|
&MapPagesCount
|
|
);
|
|
ASSERT_RETURN_ERROR (LocateMapStatus);
|
|
|
|
if (PlatformInfoHob->Q35SmramAtDefaultSmbase) {
|
|
//
|
|
// The initial SMRAM Save State Map has been covered as part of a larger
|
|
// reserved memory allocation in InitializeRamRegions().
|
|
//
|
|
ASSERT (SMM_DEFAULT_SMBASE <= MapPagesBase);
|
|
ASSERT (
|
|
(MapPagesBase + EFI_PAGES_TO_SIZE (MapPagesCount) <=
|
|
SMM_DEFAULT_SMBASE + MCH_DEFAULT_SMBASE_SIZE)
|
|
);
|
|
} else {
|
|
BuildMemoryAllocationHob (
|
|
MapPagesBase, // BaseAddress
|
|
EFI_PAGES_TO_SIZE (MapPagesCount), // Length
|
|
EfiBootServicesData // MemoryType
|
|
);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Check and perform SEV-ES initialization if required.
|
|
//
|
|
AmdSevEsInitialize (PlatformInfoHob);
|
|
|
|
//
|
|
// Set the Confidential computing attr PCD to communicate which SEV
|
|
// technology is active.
|
|
//
|
|
if (MemEncryptSevSnpIsEnabled ()) {
|
|
PcdStatus = PcdSet64S (PcdConfidentialComputingGuestAttr, CCAttrAmdSevSnp);
|
|
} else if (MemEncryptSevEsIsEnabled ()) {
|
|
PcdStatus = PcdSet64S (PcdConfidentialComputingGuestAttr, CCAttrAmdSevEs);
|
|
} else {
|
|
PcdStatus = PcdSet64S (PcdConfidentialComputingGuestAttr, CCAttrAmdSev);
|
|
}
|
|
|
|
ASSERT_RETURN_ERROR (PcdStatus);
|
|
}
|
|
|
|
/**
|
|
The function performs SEV specific region initialization.
|
|
|
|
**/
|
|
VOID
|
|
SevInitializeRam (
|
|
VOID
|
|
)
|
|
{
|
|
if (MemEncryptSevSnpIsEnabled ()) {
|
|
//
|
|
// If SEV-SNP is enabled, reserve the Secrets and CPUID memory area.
|
|
//
|
|
// This memory range is given to the PSP by the hypervisor to populate
|
|
// the information used during the SNP VM boots, and it need to persist
|
|
// across the kexec boots. Mark it as EfiReservedMemoryType so that
|
|
// the guest firmware and OS does not use it as a system memory.
|
|
//
|
|
BuildMemoryAllocationHob (
|
|
(EFI_PHYSICAL_ADDRESS)(UINTN)PcdGet32 (PcdOvmfSnpSecretsBase),
|
|
(UINT64)(UINTN)PcdGet32 (PcdOvmfSnpSecretsSize),
|
|
EfiReservedMemoryType
|
|
);
|
|
BuildMemoryAllocationHob (
|
|
(EFI_PHYSICAL_ADDRESS)(UINTN)PcdGet32 (PcdOvmfCpuidBase),
|
|
(UINT64)(UINTN)PcdGet32 (PcdOvmfCpuidSize),
|
|
EfiReservedMemoryType
|
|
);
|
|
|
|
//
|
|
// The calling area memory needs to be protected until the OS can create
|
|
// its own calling area. Mark it as EfiReservedMemoryType so that the
|
|
// guest firmware and OS do not use it as a system memory.
|
|
//
|
|
BuildMemoryAllocationHob (
|
|
(EFI_PHYSICAL_ADDRESS)(UINTN)PcdGet32 (PcdOvmfSecSvsmCaaBase),
|
|
(UINT64)(UINTN)PcdGet32 (PcdOvmfSecSvsmCaaSize),
|
|
EfiReservedMemoryType
|
|
);
|
|
}
|
|
}
|