summaryrefslogtreecommitdiffstats
path: root/OvmfPkg
diff options
context:
space:
mode:
authorBrijesh Singh via groups.io <brijesh.singh=amd.com@groups.io>2021-12-09 11:27:56 +0800
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>2021-12-09 06:28:10 +0000
commitb928eb44d5bfcf93895a3e488f15696e59ca127d (patch)
tree273d8b32efc4c20cc88fb383cb3830ca7542d2f6 /OvmfPkg
parentd4d7c9ad5fe531bbb69422ce833c67ef87d19087 (diff)
downloadedk2-b928eb44d5bfcf93895a3e488f15696e59ca127d.tar.gz
edk2-b928eb44d5bfcf93895a3e488f15696e59ca127d.tar.bz2
edk2-b928eb44d5bfcf93895a3e488f15696e59ca127d.zip
OvmfPkg/MemEncryptSevLib: change the page state in the RMP table
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>
Diffstat (limited to 'OvmfPkg')
-rw-r--r--OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c34
1 files changed, 34 insertions, 0 deletions
diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c
index f1485722f7..814f814035 100644
--- a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c
@@ -17,6 +17,7 @@
#include <Register/Cpuid.h>
#include "VirtualMemory.h"
+#include "SnpPageStateChange.h"
STATIC BOOLEAN mAddressEncMaskChecked = FALSE;
STATIC UINT64 mAddressEncMask;
@@ -693,10 +694,12 @@ SetMemoryEncDec (
PAGE_MAP_AND_DIRECTORY_POINTER *PageDirectoryPointerEntry;
PAGE_TABLE_1G_ENTRY *PageDirectory1GEntry;
PAGE_TABLE_ENTRY *PageDirectory2MEntry;
+ PHYSICAL_ADDRESS OrigPhysicalAddress;
PAGE_TABLE_4K_ENTRY *PageTableEntry;
UINT64 PgTableMask;
UINT64 AddressEncMask;
BOOLEAN IsWpEnabled;
+ UINTN OrigLength;
RETURN_STATUS Status;
//
@@ -749,6 +752,22 @@ SetMemoryEncDec (
Status = EFI_SUCCESS;
+ //
+ // To maintain the security gurantees we must set the page to shared in the RMP
+ // table before clearing the memory encryption mask from the current page table.
+ //
+ // The InternalSetPageState() is used for setting the page state in the RMP table.
+ //
+ if ((Mode == ClearCBit) && MemEncryptSevSnpIsEnabled ()) {
+ InternalSetPageState (PhysicalAddress, EFI_SIZE_TO_PAGES (Length), SevSnpPageShared, FALSE);
+ }
+
+ //
+ // Save the specified length and physical address (we need it later).
+ //
+ OrigLength = Length;
+ OrigPhysicalAddress = PhysicalAddress;
+
while (Length != 0) {
//
// If Cr3BaseAddress is not specified then read the current CR3
@@ -922,6 +941,21 @@ SetMemoryEncDec (
//
CpuFlushTlb ();
+ //
+ // SEV-SNP requires that all the private pages (i.e pages mapped encrypted) must be
+ // added in the RMP table before the access.
+ //
+ // The InternalSetPageState() is used for setting the page state in the RMP table.
+ //
+ if ((Mode == SetCBit) && MemEncryptSevSnpIsEnabled ()) {
+ InternalSetPageState (
+ OrigPhysicalAddress,
+ EFI_SIZE_TO_PAGES (OrigLength),
+ SevSnpPagePrivate,
+ FALSE
+ );
+ }
+
Done:
//
// Restore page table write protection, if any.