]> git.proxmox.com Git - mirror_edk2.git/commitdiff
OvmfPkg/PlatformPei: register GHCB gpa for the SEV-SNP guest
authorBrijesh Singh <brijesh.singh@amd.com>
Thu, 9 Dec 2021 03:27:40 +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 SEV-SNP guest requires that GHCB GPA must be registered before using.
See the GHCB specification section 2.3.2 for more details.

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/PlatformPei/AmdSev.c

index 3991edfd1e82b1edfe4f6e1a59f6eeeaec778227..f66e0a7f4a10f2fb619d58a39c85e377b3543129 100644 (file)
 #include <PiPei.h>\r
 #include <Register/Amd/Msr.h>\r
 #include <Register/Intel/SmramSaveStateMap.h>\r
+#include <Library/VmgExitLib.h>\r
 \r
 #include "Platform.h"\r
 \r
+/**\r
+  Handle an SEV-SNP/GHCB protocol check failure.\r
+\r
+  Notify the hypervisor using the VMGEXIT instruction that the SEV-SNP guest\r
+  wishes to be terminated.\r
+\r
+  @param[in] ReasonCode  Reason code to provide to the hypervisor for the\r
+                         termination request.\r
+\r
+**/\r
+STATIC\r
+VOID\r
+SevEsProtocolFailure (\r
+  IN UINT8  ReasonCode\r
+  )\r
+{\r
+  MSR_SEV_ES_GHCB_REGISTER  Msr;\r
+\r
+  //\r
+  // Use the GHCB MSR Protocol to request termination by the hypervisor\r
+  //\r
+  Msr.GhcbPhysicalAddress         = 0;\r
+  Msr.GhcbTerminate.Function      = GHCB_INFO_TERMINATE_REQUEST;\r
+  Msr.GhcbTerminate.ReasonCodeSet = GHCB_TERMINATE_GHCB;\r
+  Msr.GhcbTerminate.ReasonCode    = ReasonCode;\r
+  AsmWriteMsr64 (MSR_SEV_ES_GHCB, Msr.GhcbPhysicalAddress);\r
+\r
+  AsmVmgExit ();\r
+\r
+  ASSERT (FALSE);\r
+  CpuDeadLoop ();\r
+}\r
+\r
+/**\r
+\r
+  This function can be used to register the GHCB GPA.\r
+\r
+  @param[in]  Address           The physical address to be registered.\r
+\r
+**/\r
+STATIC\r
+VOID\r
+GhcbRegister (\r
+  IN  EFI_PHYSICAL_ADDRESS  Address\r
+  )\r
+{\r
+  MSR_SEV_ES_GHCB_REGISTER  Msr;\r
+  MSR_SEV_ES_GHCB_REGISTER  CurrentMsr;\r
+\r
+  //\r
+  // Save the current MSR Value\r
+  //\r
+  CurrentMsr.GhcbPhysicalAddress = AsmReadMsr64 (MSR_SEV_ES_GHCB);\r
+\r
+  //\r
+  // Use the GHCB MSR Protocol to request to register the GPA.\r
+  //\r
+  Msr.GhcbPhysicalAddress      = Address & ~EFI_PAGE_MASK;\r
+  Msr.GhcbGpaRegister.Function = GHCB_INFO_GHCB_GPA_REGISTER_REQUEST;\r
+  AsmWriteMsr64 (MSR_SEV_ES_GHCB, Msr.GhcbPhysicalAddress);\r
+\r
+  AsmVmgExit ();\r
+\r
+  Msr.GhcbPhysicalAddress = AsmReadMsr64 (MSR_SEV_ES_GHCB);\r
+\r
+  //\r
+  // If hypervisor responded with a different GPA than requested then fail.\r
+  //\r
+  if ((Msr.GhcbGpaRegister.Function != GHCB_INFO_GHCB_GPA_REGISTER_RESPONSE) ||\r
+      ((Msr.GhcbPhysicalAddress & ~EFI_PAGE_MASK) != Address))\r
+  {\r
+    SevEsProtocolFailure (GHCB_TERMINATE_GHCB_GENERAL);\r
+  }\r
+\r
+  //\r
+  // Restore the MSR\r
+  //\r
+  AsmWriteMsr64 (MSR_SEV_ES_GHCB, CurrentMsr.GhcbPhysicalAddress);\r
+}\r
+\r
 /**\r
 \r
   Initialize SEV-ES support if running as an SEV-ES guest.\r
@@ -115,6 +196,13 @@ AmdSevEsInitialize (
     GhcbBackupBase\r
     ));\r
 \r
+  //\r
+  // SEV-SNP guest requires that GHCB GPA must be registered before using it.\r
+  //\r
+  if (MemEncryptSevSnpIsEnabled ()) {\r
+    GhcbRegister (GhcbBasePa);\r
+  }\r
+\r
   AsmWriteMsr64 (MSR_SEV_ES_GHCB, GhcbBasePa);\r
 \r
   //\r