]> git.proxmox.com Git - mirror_edk2.git/commitdiff
OvmfPkg/MemEncryptSevLib: change the page state in the RMP table
authorBrijesh Singh via groups.io <brijesh.singh=amd.com@groups.io>
Thu, 9 Dec 2021 03:27:56 +0000 (11:27 +0800)
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Thu, 9 Dec 2021 06:28:10 +0000 (06:28 +0000)
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=3275

The MemEncryptSev{Set,Clear}PageEncMask() functions are used to set or
clear the memory encryption attribute in the page table. When SEV-SNP
is active, we also need to change the page state in the RMP table so that
it is in sync with the memory encryption attribute change.

Cc: Michael Roth <michael.roth@amd.com>
Cc: James Bottomley <jejb@linux.ibm.com>
Cc: Min Xu <min.m.xu@intel.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Erdem Aktas <erdemaktas@google.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Acked-by: Jiewen Yao <Jiewen.yao@intel.com>
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c

index f1485722f7cf22abade68fd17f06393750576dfe..814f814035fa7139b617dc3825fa9dc071829293 100644 (file)
@@ -17,6 +17,7 @@
 #include <Register/Cpuid.h>\r
 \r
 #include "VirtualMemory.h"\r
+#include "SnpPageStateChange.h"\r
 \r
 STATIC BOOLEAN          mAddressEncMaskChecked = FALSE;\r
 STATIC UINT64           mAddressEncMask;\r
@@ -693,10 +694,12 @@ SetMemoryEncDec (
   PAGE_MAP_AND_DIRECTORY_POINTER  *PageDirectoryPointerEntry;\r
   PAGE_TABLE_1G_ENTRY             *PageDirectory1GEntry;\r
   PAGE_TABLE_ENTRY                *PageDirectory2MEntry;\r
+  PHYSICAL_ADDRESS                OrigPhysicalAddress;\r
   PAGE_TABLE_4K_ENTRY             *PageTableEntry;\r
   UINT64                          PgTableMask;\r
   UINT64                          AddressEncMask;\r
   BOOLEAN                         IsWpEnabled;\r
+  UINTN                           OrigLength;\r
   RETURN_STATUS                   Status;\r
 \r
   //\r
@@ -749,6 +752,22 @@ SetMemoryEncDec (
 \r
   Status = EFI_SUCCESS;\r
 \r
+  //\r
+  // To maintain the security gurantees we must set the page to shared in the RMP\r
+  // table before clearing the memory encryption mask from the current page table.\r
+  //\r
+  // The InternalSetPageState() is used for setting the page state in the RMP table.\r
+  //\r
+  if ((Mode == ClearCBit) && MemEncryptSevSnpIsEnabled ()) {\r
+    InternalSetPageState (PhysicalAddress, EFI_SIZE_TO_PAGES (Length), SevSnpPageShared, FALSE);\r
+  }\r
+\r
+  //\r
+  // Save the specified length and physical address (we need it later).\r
+  //\r
+  OrigLength          = Length;\r
+  OrigPhysicalAddress = PhysicalAddress;\r
+\r
   while (Length != 0) {\r
     //\r
     // If Cr3BaseAddress is not specified then read the current CR3\r
@@ -922,6 +941,21 @@ SetMemoryEncDec (
   //\r
   CpuFlushTlb ();\r
 \r
+  //\r
+  // SEV-SNP requires that all the private pages (i.e pages mapped encrypted) must be\r
+  // added in the RMP table before the access.\r
+  //\r
+  // The InternalSetPageState() is used for setting the page state in the RMP table.\r
+  //\r
+  if ((Mode == SetCBit) && MemEncryptSevSnpIsEnabled ()) {\r
+    InternalSetPageState (\r
+      OrigPhysicalAddress,\r
+      EFI_SIZE_TO_PAGES (OrigLength),\r
+      SevSnpPagePrivate,\r
+      FALSE\r
+      );\r
+  }\r
+\r
 Done:\r
   //\r
   // Restore page table write protection, if any.\r