#include <Library/UefiBootServicesTableLib.h>\r
#include <Guid/ConfidentialComputingSevSnpBlob.h>\r
#include <Library/PcdLib.h>\r
+#include <Protocol/MemoryAccept.h>\r
\r
STATIC CONFIDENTIAL_COMPUTING_SNP_BLOB_LOCATION mSnpBootDxeTable = {\r
SIGNATURE_32 ('A', 'M', 'D', 'E'),\r
FixedPcdGet32 (PcdOvmfCpuidSize),\r
};\r
\r
+STATIC EFI_HANDLE mAmdSevDxeHandle = NULL;\r
+\r
+#define IS_ALIGNED(x, y) ((((x) & ((y) - 1)) == 0))\r
+\r
+STATIC\r
+EFI_STATUS\r
+EFIAPI\r
+AmdSevMemoryAccept (\r
+ IN EDKII_MEMORY_ACCEPT_PROTOCOL *This,\r
+ IN EFI_PHYSICAL_ADDRESS StartAddress,\r
+ IN UINTN Size\r
+ )\r
+{\r
+ //\r
+ // The StartAddress must be page-aligned, and the Size must be a positive\r
+ // multiple of SIZE_4KB. Use an assert instead of returning an erros since\r
+ // this is an EDK2-internal protocol.\r
+ //\r
+ ASSERT (IS_ALIGNED (StartAddress, SIZE_4KB));\r
+ ASSERT (IS_ALIGNED (Size, SIZE_4KB));\r
+ ASSERT (Size != 0);\r
+\r
+ MemEncryptSevSnpPreValidateSystemRam (\r
+ StartAddress,\r
+ EFI_SIZE_TO_PAGES (Size)\r
+ );\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+STATIC EDKII_MEMORY_ACCEPT_PROTOCOL mMemoryAcceptProtocol = {\r
+ AmdSevMemoryAccept\r
+};\r
+\r
EFI_STATUS\r
EFIAPI\r
AmdSevDxeEntryPoint (\r
}\r
}\r
\r
- //\r
- // If its SEV-SNP active guest then install the CONFIDENTIAL_COMPUTING_SEV_SNP_BLOB.\r
- // It contains the location for both the Secrets and CPUID page.\r
- //\r
if (MemEncryptSevSnpIsEnabled ()) {\r
+ //\r
+ // Memory acceptance began being required in SEV-SNP, so install the\r
+ // memory accept protocol implementation for a SEV-SNP active guest.\r
+ //\r
+ Status = gBS->InstallProtocolInterface (\r
+ &mAmdSevDxeHandle,\r
+ &gEdkiiMemoryAcceptProtocolGuid,\r
+ EFI_NATIVE_INTERFACE,\r
+ &mMemoryAcceptProtocol\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ //\r
+ // If its SEV-SNP active guest then install the CONFIDENTIAL_COMPUTING_SEV_SNP_BLOB.\r
+ // It contains the location for both the Secrets and CPUID page.\r
+ //\r
return gBS->InstallConfigurationTable (\r
&gConfidentialComputingSevSnpBlobGuid,\r
&mSnpBootDxeTable\r
#include <Library/MemEncryptSevLib.h>\r
\r
#include "SnpPageStateChange.h"\r
+#include "VirtualMemory.h"\r
\r
/**\r
Pre-validate the system RAM when SEV-SNP is enabled in the guest VM.\r
IN UINTN NumPages\r
)\r
{\r
+ EFI_STATUS Status;\r
+\r
if (!MemEncryptSevSnpIsEnabled ()) {\r
return;\r
}\r
\r
- //\r
- // All the pre-validation must be completed in the PEI phase.\r
- //\r
- ASSERT (FALSE);\r
+ // DXE pre-validation may happen with the memory accept protocol.\r
+ // The protocol should only be called outside the prevalidated ranges\r
+ // that the PEI stage code explicitly skips. Specifically, only memory\r
+ // ranges that are classified as unaccepted.\r
+ if (BaseAddress >= SIZE_4GB) {\r
+ Status = InternalMemEncryptSevCreateIdentityMap1G (\r
+ 0,\r
+ BaseAddress,\r
+ EFI_PAGES_TO_SIZE (NumPages)\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ ASSERT (FALSE);\r
+ CpuDeadLoop ();\r
+ }\r
+ }\r
+\r
+ InternalSetPageState (BaseAddress, NumPages, SevSnpPagePrivate, TRUE);\r
}\r