public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: "Lendacky, Thomas" <thomas.lendacky@amd.com>
To: devel@edk2.groups.io
Cc: Brijesh Singh <brijesh.singh@amd.com>,
	Ard Biesheuvel <ard.biesheuvel@arm.com>,
	Eric Dong <eric.dong@intel.com>,
	Jordan Justen <jordan.l.justen@intel.com>,
	Laszlo Ersek <lersek@redhat.com>,
	Liming Gao <liming.gao@intel.com>,
	Michael D Kinney <michael.d.kinney@intel.com>,
	Ray Ni <ray.ni@intel.com>
Subject: [PATCH v12 12/46] OvmfPkg/VmgExitLib: Implement library support for VmgExitLib in OVMF
Date: Mon, 27 Jul 2020 10:25:53 -0500	[thread overview]
Message-ID: <36211d123b5a55d7ed07246f5e2562c0eb5d4d8b.1595863587.git.thomas.lendacky@amd.com> (raw)
In-Reply-To: <cover.1595863587.git.thomas.lendacky@amd.com>

From: Tom Lendacky <thomas.lendacky@amd.com>

The base VmgExitLib library provides a default limited interface. As it
does not provide full support, create an OVMF version of this library to
begin the process of providing full support of SEV-ES within OVMF.

SEV-ES support is only provided for X64 builds, so only OvmfPkgX64.dsc is
updated to make use of the OvmfPkg version of the library.

Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
---
 OvmfPkg/OvmfPkgX64.dsc                        |   2 +-
 OvmfPkg/Library/VmgExitLib/VmgExitLib.inf     |  36 ++++
 OvmfPkg/Library/VmgExitLib/VmgExitLib.c       | 159 ++++++++++++++++++
 OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c |  81 +++++++++
 4 files changed, 277 insertions(+), 1 deletion(-)
 create mode 100644 OvmfPkg/Library/VmgExitLib/VmgExitLib.inf
 create mode 100644 OvmfPkg/Library/VmgExitLib/VmgExitLib.c
 create mode 100644 OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c

diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc
index 27f5225fc281..60be5eae3d2b 100644
--- a/OvmfPkg/OvmfPkgX64.dsc
+++ b/OvmfPkg/OvmfPkgX64.dsc
@@ -233,7 +233,7 @@ [LibraryClasses]
 
 [LibraryClasses.common]
   BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
-  VmgExitLib|UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.inf
+  VmgExitLib|OvmfPkg/Library/VmgExitLib/VmgExitLib.inf
 
 [LibraryClasses.common.SEC]
   TimerLib|OvmfPkg/Library/AcpiTimerLib/BaseRomAcpiTimerLib.inf
diff --git a/OvmfPkg/Library/VmgExitLib/VmgExitLib.inf b/OvmfPkg/Library/VmgExitLib/VmgExitLib.inf
new file mode 100644
index 000000000000..d003ac63173e
--- /dev/null
+++ b/OvmfPkg/Library/VmgExitLib/VmgExitLib.inf
@@ -0,0 +1,36 @@
+## @file
+#  VMGEXIT Support Library.
+#
+#  Copyright (C) 2020, Advanced Micro Devices, Inc. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = VmgExitLib
+  FILE_GUID                      = 0e923c25-13cd-430b-8714-ffe85652a97b
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = VmgExitLib
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = X64
+#
+
+[Sources.common]
+  VmgExitLib.c
+  VmgExitVcHandler.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  OvmfPkg/OvmfPkg.dec
+  UefiCpuPkg/UefiCpuPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  BaseMemoryLib
+  DebugLib
+
diff --git a/OvmfPkg/Library/VmgExitLib/VmgExitLib.c b/OvmfPkg/Library/VmgExitLib/VmgExitLib.c
new file mode 100644
index 000000000000..53040cc6f649
--- /dev/null
+++ b/OvmfPkg/Library/VmgExitLib/VmgExitLib.c
@@ -0,0 +1,159 @@
+/** @file
+  VMGEXIT Support Library.
+
+  Copyright (C) 2020, Advanced Micro Devices, Inc. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Base.h>
+#include <Uefi.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/VmgExitLib.h>
+#include <Register/Amd/Msr.h>
+
+/**
+  Check for VMGEXIT error
+
+  Check if the hypervisor has returned an error after completion of the VMGEXIT
+  by examining the SwExitInfo1 field of the GHCB.
+
+  @param[in]  Ghcb       A pointer to the GHCB
+
+  @retval  0             VMGEXIT succeeded.
+  @return                Exception number to be propagated, VMGEXIT processing
+                         did not succeed.
+
+**/
+STATIC
+UINT64
+VmgExitErrorCheck (
+  IN GHCB                *Ghcb
+  )
+{
+  GHCB_EVENT_INJECTION  Event;
+  GHCB_EXIT_INFO        ExitInfo;
+  UINT64                Status;
+
+  ExitInfo.Uint64 = Ghcb->SaveArea.SwExitInfo1;
+  ASSERT ((ExitInfo.Elements.Lower32Bits == 0) ||
+          (ExitInfo.Elements.Lower32Bits == 1));
+
+  Status = 0;
+  if (ExitInfo.Elements.Lower32Bits == 0) {
+    return Status;
+  }
+
+  if (ExitInfo.Elements.Lower32Bits == 1) {
+    ASSERT (Ghcb->SaveArea.SwExitInfo2 != 0);
+
+    //
+    // Check that the return event is valid
+    //
+    Event.Uint64 = Ghcb->SaveArea.SwExitInfo2;
+    if (Event.Elements.Valid &&
+        Event.Elements.Type == GHCB_EVENT_INJECTION_TYPE_EXCEPTION) {
+      switch (Event.Elements.Vector) {
+      case GP_EXCEPTION:
+      case UD_EXCEPTION:
+        //
+        // Use returned event as return code
+        //
+        Status = Event.Uint64;
+      }
+    }
+  }
+
+  if (Status == 0) {
+    GHCB_EVENT_INJECTION  GpEvent;
+
+    GpEvent.Uint64 = 0;
+    GpEvent.Elements.Vector = GP_EXCEPTION;
+    GpEvent.Elements.Type   = GHCB_EVENT_INJECTION_TYPE_EXCEPTION;
+    GpEvent.Elements.Valid  = 1;
+
+    Status = GpEvent.Uint64;
+  }
+
+  return Status;
+}
+
+/**
+  Perform VMGEXIT.
+
+  Sets the necessary fields of the GHCB, invokes the VMGEXIT instruction and
+  then handles the return actions.
+
+  @param[in, out]  Ghcb       A pointer to the GHCB
+  @param[in]       ExitCode   VMGEXIT code to be assigned to the SwExitCode
+                              field of the GHCB.
+  @param[in]       ExitInfo1  VMGEXIT information to be assigned to the
+                              SwExitInfo1 field of the GHCB.
+  @param[in]       ExitInfo2  VMGEXIT information to be assigned to the
+                              SwExitInfo2 field of the GHCB.
+
+  @retval  0                  VMGEXIT succeeded.
+  @return                     Exception number to be propagated, VMGEXIT
+                              processing did not succeed.
+
+**/
+UINT64
+EFIAPI
+VmgExit (
+  IN OUT GHCB                *Ghcb,
+  IN     UINT64              ExitCode,
+  IN     UINT64              ExitInfo1,
+  IN     UINT64              ExitInfo2
+  )
+{
+  Ghcb->SaveArea.SwExitCode = ExitCode;
+  Ghcb->SaveArea.SwExitInfo1 = ExitInfo1;
+  Ghcb->SaveArea.SwExitInfo2 = ExitInfo2;
+
+  //
+  // Guest memory is used for the guest-hypervisor communication, so fence
+  // the invocation of the VMGEXIT instruction to ensure GHCB accesses are
+  // synchronized properly.
+  //
+  MemoryFence ();
+  AsmVmgExit ();
+  MemoryFence ();
+
+  return VmgExitErrorCheck (Ghcb);
+}
+
+/**
+  Perform pre-VMGEXIT initialization/preparation.
+
+  Performs the necessary steps in preparation for invoking VMGEXIT. Must be
+  called before setting any fields within the GHCB.
+
+  @param[in, out]  Ghcb       A pointer to the GHCB
+
+**/
+VOID
+EFIAPI
+VmgInit (
+  IN OUT GHCB                *Ghcb
+  )
+{
+  SetMem (&Ghcb->SaveArea, sizeof (Ghcb->SaveArea), 0);
+}
+
+/**
+  Perform post-VMGEXIT cleanup.
+
+  Performs the necessary steps to cleanup after invoking VMGEXIT. Must be
+  called after obtaining needed fields within the GHCB.
+
+  @param[in, out]  Ghcb       A pointer to the GHCB
+
+**/
+VOID
+EFIAPI
+VmgDone (
+  IN OUT GHCB                *Ghcb
+  )
+{
+}
+
diff --git a/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c b/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c
new file mode 100644
index 000000000000..b6a955ed8088
--- /dev/null
+++ b/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c
@@ -0,0 +1,81 @@
+/** @file
+  X64 #VC Exception Handler functon.
+
+  Copyright (C) 2020, Advanced Micro Devices, Inc. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Base.h>
+#include <Uefi.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/VmgExitLib.h>
+#include <Register/Amd/Msr.h>
+
+/**
+  Handle a #VC exception.
+
+  Performs the necessary processing to handle a #VC exception.
+
+  @param[in, out]  ExceptionType  Pointer to an EFI_EXCEPTION_TYPE to be set
+                                  as value to use on error.
+  @param[in, out]  SystemContext  Pointer to EFI_SYSTEM_CONTEXT
+
+  @retval  EFI_SUCCESS            Exception handled
+  @retval  EFI_UNSUPPORTED        #VC not supported, (new) exception value to
+                                  propagate provided
+  @retval  EFI_PROTOCOL_ERROR     #VC handling failed, (new) exception value to
+                                  propagate provided
+
+**/
+EFI_STATUS
+EFIAPI
+VmgExitHandleVc (
+  IN OUT EFI_EXCEPTION_TYPE  *ExceptionType,
+  IN OUT EFI_SYSTEM_CONTEXT  SystemContext
+  )
+{
+  MSR_SEV_ES_GHCB_REGISTER  Msr;
+  EFI_SYSTEM_CONTEXT_X64    *Regs;
+  GHCB                      *Ghcb;
+  UINT64                    ExitCode, Status;
+  EFI_STATUS                VcRet;
+
+  VcRet = EFI_SUCCESS;
+
+  Msr.GhcbPhysicalAddress = AsmReadMsr64 (MSR_SEV_ES_GHCB);
+  ASSERT (Msr.GhcbInfo.Function == 0);
+  ASSERT (Msr.Ghcb != 0);
+
+  Regs = SystemContext.SystemContextX64;
+  Ghcb = Msr.Ghcb;
+
+  VmgInit (Ghcb);
+
+  ExitCode = Regs->ExceptionData;
+  switch (ExitCode) {
+  default:
+    Status = VmgExit (Ghcb, SVM_EXIT_UNSUPPORTED, ExitCode, 0);
+    if (Status == 0) {
+      Regs->ExceptionData = 0;
+      *ExceptionType = GP_EXCEPTION;
+    } else {
+      GHCB_EVENT_INJECTION  Event;
+
+      Event.Uint64 = Status;
+      if (Event.Elements.ErrorCodeValid != 0) {
+        Regs->ExceptionData = Event.Elements.ErrorCode;
+      } else {
+        Regs->ExceptionData = 0;
+      }
+
+      *ExceptionType = Event.Elements.Vector;
+    }
+
+    VcRet = EFI_PROTOCOL_ERROR;
+  }
+
+  VmgDone (Ghcb);
+
+  return VcRet;
+}
-- 
2.27.0


  parent reply	other threads:[~2020-07-27 15:28 UTC|newest]

Thread overview: 61+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-07-27 15:25 [PATCH v12 00/46] SEV-ES guest support Lendacky, Thomas
2020-07-27 15:25 ` [PATCH v12 01/46] MdeModulePkg: Create PCDs to be used in support of SEV-ES Lendacky, Thomas
2020-07-27 15:25 ` [PATCH v12 02/46] UefiCpuPkg: Create PCD " Lendacky, Thomas
2020-07-27 15:25 ` [PATCH v12 03/46] MdePkg: Add the MSR definition for the GHCB register Lendacky, Thomas
2020-07-27 15:25 ` [PATCH v12 04/46] MdePkg: Add a structure definition for the GHCB Lendacky, Thomas
2020-07-27 15:25 ` [PATCH v12 05/46] MdeModulePkg/DxeIplPeim: Support GHCB pages when creating page tables Lendacky, Thomas
2020-07-27 15:25 ` [PATCH v12 06/46] MdePkg/BaseLib: Add support for the XGETBV instruction Lendacky, Thomas
2020-07-27 15:25 ` [PATCH v12 07/46] MdePkg/BaseLib: Add support for the VMGEXIT instruction Lendacky, Thomas
2020-07-28  1:34   ` Liming Gao
2020-07-28  4:07     ` Lendacky, Thomas
2020-07-28  7:39       ` Liming Gao
2020-07-28 12:04         ` Laszlo Ersek
2020-07-28 13:44           ` Liming Gao
2020-07-28 14:13           ` Lendacky, Thomas
2020-07-28 15:19             ` Laszlo Ersek
2020-07-29  1:13               ` Liming Gao
2020-07-27 15:25 ` [PATCH v12 08/46] UefiCpuPkg: Implement library support for VMGEXIT Lendacky, Thomas
2020-07-27 15:25 ` [PATCH v12 09/46] OvmfPkg: Prepare OvmfPkg to use the VmgExitLib library Lendacky, Thomas
2020-07-27 15:25 ` [PATCH v12 10/46] UefiPayloadPkg: Prepare UefiPayloadPkg " Lendacky, Thomas
2020-07-27 15:25 ` [PATCH v12 11/46] UefiCpuPkg/CpuExceptionHandler: Add base support for the #VC exception Lendacky, Thomas
2020-07-27 15:25 ` Lendacky, Thomas [this message]
2020-07-27 15:25 ` [PATCH v12 13/46] OvmfPkg/VmgExitLib: Add support for IOIO_PROT NAE events Lendacky, Thomas
2020-07-27 15:25 ` [PATCH v12 14/46] OvmfPkg/VmgExitLib: Support string IO " Lendacky, Thomas
2020-07-27 15:25 ` [PATCH v12 15/46] OvmfPkg/VmgExitLib: Add support for CPUID " Lendacky, Thomas
2020-07-27 15:25 ` [PATCH v12 16/46] OvmfPkg/VmgExitLib: Add support for MSR_PROT " Lendacky, Thomas
2020-07-27 15:25 ` [PATCH v12 17/46] OvmfPkg/VmgExitLib: Add support for NPF NAE events (MMIO) Lendacky, Thomas
2020-07-27 15:25 ` [PATCH v12 18/46] OvmfPkg/VmgExitLib: Add support for WBINVD NAE events Lendacky, Thomas
2020-07-27 15:26 ` [PATCH v12 19/46] OvmfPkg/VmgExitLib: Add support for RDTSC " Lendacky, Thomas
2020-07-27 15:26 ` [PATCH v12 20/46] OvmfPkg/VmgExitLib: Add support for RDPMC " Lendacky, Thomas
2020-07-27 15:26 ` [PATCH v12 21/46] OvmfPkg/VmgExitLib: Add support for INVD " Lendacky, Thomas
2020-07-27 15:26 ` [PATCH v12 22/46] OvmfPkg/VmgExitLib: Add support for VMMCALL " Lendacky, Thomas
2020-07-27 15:26 ` [PATCH v12 23/46] OvmfPkg/VmgExitLib: Add support for RDTSCP " Lendacky, Thomas
2020-07-27 15:26 ` [PATCH v12 24/46] OvmfPkg/VmgExitLib: Add support for MONITOR/MONITORX " Lendacky, Thomas
2020-07-27 15:26 ` [PATCH v12 25/46] OvmfPkg/VmgExitLib: Add support for MWAIT/MWAITX " Lendacky, Thomas
2020-07-27 15:26 ` [PATCH v12 26/46] OvmfPkg/VmgExitLib: Add support for DR7 Read/Write " Lendacky, Thomas
2020-07-27 15:26 ` [PATCH v12 27/46] OvmfPkg/MemEncryptSevLib: Add an SEV-ES guest indicator function Lendacky, Thomas
2020-07-27 15:26 ` [PATCH v12 28/46] OvmfPkg: Add support to perform SEV-ES initialization Lendacky, Thomas
2020-07-27 15:26 ` [PATCH v12 29/46] OvmfPkg: Create a GHCB page for use during Sec phase Lendacky, Thomas
2020-07-27 15:26 ` [PATCH v12 30/46] OvmfPkg/PlatformPei: Reserve GHCB-related areas if S3 is supported Lendacky, Thomas
2020-07-27 15:26 ` [PATCH v12 31/46] OvmfPkg: Create GHCB pages for use during Pei and Dxe phase Lendacky, Thomas
2020-07-27 15:26 ` [PATCH v12 32/46] OvmfPkg/PlatformPei: Move early GDT into ram when SEV-ES is enabled Lendacky, Thomas
2020-07-27 15:26 ` [PATCH v12 33/46] UefiCpuPkg: Create an SEV-ES workarea PCD Lendacky, Thomas
2020-07-27 15:26 ` [PATCH v12 34/46] OvmfPkg: Reserve a page in memory for the SEV-ES usage Lendacky, Thomas
2020-07-27 15:26 ` [PATCH v12 35/46] OvmfPkg/PlatformPei: Reserve SEV-ES work area if S3 is supported Lendacky, Thomas
2020-07-27 15:26 ` [PATCH v12 36/46] OvmfPkg/ResetVector: Add support for a 32-bit SEV check Lendacky, Thomas
2020-07-27 15:26 ` [PATCH v12 37/46] OvmfPkg/Sec: Add #VC exception handling for Sec phase Lendacky, Thomas
2020-07-27 15:26 ` [PATCH v12 38/46] OvmfPkg/Sec: Enable cache early to speed up booting Lendacky, Thomas
2020-07-27 15:26 ` [PATCH v12 39/46] OvmfPkg/QemuFlashFvbServicesRuntimeDxe: Bypass flash detection with SEV-ES Lendacky, Thomas
2020-07-27 17:41 ` [edk2-devel] [PATCH v12 00/46] SEV-ES guest support Laszlo Ersek
2020-07-27 17:43   ` Laszlo Ersek
2020-07-27 17:49     ` Lendacky, Thomas
2020-07-28 10:07       ` Laszlo Ersek
2020-07-28 12:52         ` Lendacky, Thomas
2020-07-28 13:59           ` Laszlo Ersek
2020-07-27 18:43 ` [PATCH v12 40/46] UefiCpuPkg: Add a 16-bit protected mode code segment descriptor Lendacky, Thomas
2020-07-27 18:43 ` [PATCH v12 41/46] UefiCpuPkg/MpInitLib: Add CPU MP data flag to indicate if SEV-ES is enabled Lendacky, Thomas
2020-07-27 18:43 ` [PATCH v12 42/46] UefiCpuPkg: Allow AP booting under SEV-ES Lendacky, Thomas
2020-07-27 18:43 ` [PATCH v12 43/46] OvmfPkg: Use the SEV-ES work area for the SEV-ES AP reset vector Lendacky, Thomas
2020-07-27 18:43 ` [PATCH v12 44/46] OvmfPkg: Move the GHCB allocations into reserved memory Lendacky, Thomas
2020-07-27 18:43 ` [PATCH v12 45/46] UefiCpuPkg/MpInitLib: Prepare SEV-ES guest APs for OS use Lendacky, Thomas
2020-07-27 18:43 ` [PATCH v12 46/46] Maintainers.txt: Add reviewers for the OvmfPkg SEV-related files Lendacky, Thomas

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=36211d123b5a55d7ed07246f5e2562c0eb5d4d8b.1595863587.git.thomas.lendacky@amd.com \
    --to=devel@edk2.groups.io \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox