|
@@ -16,10 +16,13 @@
|
|
|
|
|
|
**/
|
|
|
|
|
|
+#include <Library/BaseLib.h>
|
|
|
+#include <Library/BaseMemoryLib.h>
|
|
|
#include <Library/DebugLib.h>
|
|
|
#include <Library/DxeServicesTableLib.h>
|
|
|
#include <Library/MemEncryptSevLib.h>
|
|
|
#include <Library/MemoryAllocationLib.h>
|
|
|
+#include <Library/PcdLib.h>
|
|
|
|
|
|
EFI_STATUS
|
|
|
EFIAPI
|
|
@@ -68,5 +71,55 @@ AmdSevDxeEntryPoint (
|
|
|
FreePool (AllDescMap);
|
|
|
}
|
|
|
|
|
|
+ //
|
|
|
+ // When SMM is enabled, clear the C-bit from SMM Saved State Area
|
|
|
+ //
|
|
|
+ // NOTES: The SavedStateArea address cleared here is before SMBASE
|
|
|
+ // relocation. Currently, we do not clear the SavedStateArea address after
|
|
|
+ // SMBASE is relocated due to the following reasons:
|
|
|
+ //
|
|
|
+ // 1) Guest BIOS never access the relocated SavedStateArea.
|
|
|
+ //
|
|
|
+ // 2) The C-bit works on page-aligned address, but the SavedStateArea
|
|
|
+ // address is not a page-aligned. Theoretically, we could roundup the address
|
|
|
+ // and clear the C-bit of aligned address but looking carefully we found
|
|
|
+ // that some portion of the page contains code -- which will causes a bigger
|
|
|
+ // issues for SEV guest. When SEV is enabled, all the code must be encrypted
|
|
|
+ // otherwise hardware will cause trap.
|
|
|
+ //
|
|
|
+ // We restore the C-bit for this SMM Saved State Area after SMBASE relocation
|
|
|
+ // is completed (See OvmfPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.c).
|
|
|
+ //
|
|
|
+ if (FeaturePcdGet (PcdSmmSmramRequire)) {
|
|
|
+ UINTN MapPagesBase;
|
|
|
+ UINTN MapPagesCount;
|
|
|
+
|
|
|
+ Status = MemEncryptSevLocateInitialSmramSaveStateMapPages (
|
|
|
+ &MapPagesBase,
|
|
|
+ &MapPagesCount
|
|
|
+ );
|
|
|
+ ASSERT_EFI_ERROR (Status);
|
|
|
+
|
|
|
+ //
|
|
|
+ // Although these pages were set aside (i.e., allocated) by PlatformPei, we
|
|
|
+ // could be after a warm reboot from the OS. Don't leak any stale OS data
|
|
|
+ // to the hypervisor.
|
|
|
+ //
|
|
|
+ ZeroMem ((VOID *)MapPagesBase, EFI_PAGES_TO_SIZE (MapPagesCount));
|
|
|
+
|
|
|
+ Status = MemEncryptSevClearPageEncMask (
|
|
|
+ 0, // Cr3BaseAddress -- use current CR3
|
|
|
+ MapPagesBase, // BaseAddress
|
|
|
+ MapPagesCount, // NumPages
|
|
|
+ TRUE // Flush
|
|
|
+ );
|
|
|
+ if (EFI_ERROR (Status)) {
|
|
|
+ DEBUG ((DEBUG_ERROR, "%a: MemEncryptSevClearPageEncMask(): %r\n",
|
|
|
+ __FUNCTION__, Status));
|
|
|
+ ASSERT (FALSE);
|
|
|
+ CpuDeadLoop ();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
return EFI_SUCCESS;
|
|
|
}
|