\r
#include "SnpPageStateChange.h"\r
\r
+typedef struct {\r
+ UINT64 StartAddress;\r
+ UINT64 EndAddress;\r
+} SNP_PRE_VALIDATED_RANGE;\r
+\r
+STATIC SNP_PRE_VALIDATED_RANGE mPreValidatedRange[] = {\r
+ // The below address range was part of the SEV OVMF metadata, and range\r
+ // should be pre-validated by the Hypervisor.\r
+ {\r
+ FixedPcdGet32 (PcdOvmfSecPageTablesBase),\r
+ FixedPcdGet32 (PcdOvmfPeiMemFvBase),\r
+ },\r
+};\r
+\r
+STATIC\r
+BOOLEAN\r
+DetectPreValidatedOverLap (\r
+ IN PHYSICAL_ADDRESS StartAddress,\r
+ IN PHYSICAL_ADDRESS EndAddress,\r
+ OUT SNP_PRE_VALIDATED_RANGE *OverlapRange\r
+ )\r
+{\r
+ UINTN i;\r
+\r
+ //\r
+ // Check if the specified address range exist in pre-validated array.\r
+ //\r
+ for (i = 0; i < ARRAY_SIZE (mPreValidatedRange); i++) {\r
+ if ((mPreValidatedRange[i].StartAddress < EndAddress) &&\r
+ (StartAddress < mPreValidatedRange[i].EndAddress))\r
+ {\r
+ OverlapRange->StartAddress = mPreValidatedRange[i].StartAddress;\r
+ OverlapRange->EndAddress = mPreValidatedRange[i].EndAddress;\r
+ return TRUE;\r
+ }\r
+ }\r
+\r
+ return FALSE;\r
+}\r
+\r
/**\r
Pre-validate the system RAM when SEV-SNP is enabled in the guest VM.\r
\r
IN UINTN NumPages\r
)\r
{\r
+ PHYSICAL_ADDRESS EndAddress;\r
+ SNP_PRE_VALIDATED_RANGE OverlapRange;\r
+\r
if (!MemEncryptSevSnpIsEnabled ()) {\r
return;\r
}\r
\r
- InternalSetPageState (BaseAddress, NumPages, SevSnpPagePrivate, TRUE);\r
+ EndAddress = BaseAddress + EFI_PAGES_TO_SIZE (NumPages);\r
+\r
+ while (BaseAddress < EndAddress) {\r
+ //\r
+ // Check if the range overlaps with the pre-validated ranges.\r
+ //\r
+ if (DetectPreValidatedOverLap (BaseAddress, EndAddress, &OverlapRange)) {\r
+ // Validate the non-overlap regions.\r
+ if (BaseAddress < OverlapRange.StartAddress) {\r
+ NumPages = EFI_SIZE_TO_PAGES (OverlapRange.StartAddress - BaseAddress);\r
+\r
+ InternalSetPageState (BaseAddress, NumPages, SevSnpPagePrivate, TRUE);\r
+ }\r
+\r
+ BaseAddress = OverlapRange.EndAddress;\r
+ continue;\r
+ }\r
+\r
+ // Validate the remaining pages.\r
+ NumPages = EFI_SIZE_TO_PAGES (EndAddress - BaseAddress);\r
+ InternalSetPageState (BaseAddress, NumPages, SevSnpPagePrivate, TRUE);\r
+ BaseAddress = EndAddress;\r
+ }\r
}\r