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