]> git.proxmox.com Git - mirror_edk2.git/commitdiff
OvmfPkg/MemEncryptSevLib: add function to check the VMPL0
authorBrijesh Singh via groups.io <brijesh.singh=amd.com@groups.io>
Thu, 9 Dec 2021 03:27:43 +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

Virtual Machine Privilege Level (VMPL) feature in the SEV-SNP
architecture allows a guest VM to divide its address space into four
levels. The level can be used to provide the hardware isolated
abstraction layers with a VM. The VMPL0 is the highest privilege, and
VMPL3 is the least privilege. Certain operations must be done by the
VMPL0 software, such as:

* Validate or invalidate memory range (PVALIDATE instruction)
* Allocate VMSA page (RMPADJUST instruction when VMSA=1)

The initial SEV-SNP support assumes that the guest is running on VMPL0.
Let's add function in the MemEncryptSevLib that can be used for checking
whether guest is booted under the VMPL0.

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: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
OvmfPkg/Library/BaseMemEncryptSevLib/X64/SecSnpSystemRamValidate.c
OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChange.h
OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChangeInternal.c

index bc891c2636d6f3da7b016f0704432bd18b0bcd6c..7797febb8ac6bf1d93580685ea3292fadfae85f8 100644 (file)
 \r
 #include "SnpPageStateChange.h"\r
 \r
+//\r
+// The variable used for the VMPL check.\r
+//\r
+STATIC UINT8  gVmpl0Data[4096];\r
+\r
+/**\r
+ The function checks whether SEV-SNP guest is booted under VMPL0.\r
+\r
+ @retval  TRUE      The guest is booted under VMPL0\r
+ @retval  FALSE     The guest is not booted under VMPL0\r
+ **/\r
+STATIC\r
+BOOLEAN\r
+SevSnpIsVmpl0 (\r
+  VOID\r
+  )\r
+{\r
+  UINT64      Rdx;\r
+  EFI_STATUS  Status;\r
+\r
+  //\r
+  // There is no straightforward way to query the current VMPL level.\r
+  // The simplest method is to use the RMPADJUST instruction to change\r
+  // a page permission to a VMPL level-1, and if the guest kernel is\r
+  // launched at a level <= 1, then RMPADJUST instruction will return\r
+  // an error.\r
+  //\r
+  Rdx = 1;\r
+\r
+  Status = AsmRmpAdjust ((UINT64)gVmpl0Data, 0, Rdx);\r
+  if (EFI_ERROR (Status)) {\r
+    return FALSE;\r
+  }\r
+\r
+  return TRUE;\r
+}\r
+\r
 /**\r
   Pre-validate the system RAM when SEV-SNP is enabled in the guest VM.\r
 \r
@@ -32,5 +69,14 @@ MemEncryptSevSnpPreValidateSystemRam (
     return;\r
   }\r
 \r
+  //\r
+  // The page state change uses the PVALIDATE instruction. The instruction\r
+  // can be run on VMPL-0 only. If its not VMPL-0 guest then terminate\r
+  // the boot.\r
+  //\r
+  if (!SevSnpIsVmpl0 ()) {\r
+    SnpPageStateFailureTerminate ();\r
+  }\r
+\r
   InternalSetPageState (BaseAddress, NumPages, SevSnpPagePrivate, TRUE);\r
 }\r
index b396f0ffbd7557fbfb802960a84b963409a399ab..43319cc9ed172b7fa405a7ee6962b4b70613f0b2 100644 (file)
@@ -27,4 +27,9 @@ InternalSetPageState (
   IN BOOLEAN               UseLargeEntry\r
   );\r
 \r
+VOID\r
+SnpPageStateFailureTerminate (\r
+  VOID\r
+  );\r
+\r
 #endif\r
index 9c552ef5c7b18b993dd682a687313907896d52cb..d11aafae84727ba8e1b0031e74b28db7dd7c14e2 100644 (file)
@@ -42,7 +42,6 @@ MemoryStateToGhcbOp (
   return Cmd;\r
 }\r
 \r
-STATIC\r
 VOID\r
 SnpPageStateFailureTerminate (\r
   VOID\r