public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: "Lendacky, Thomas via groups.io" <thomas.lendacky=amd.com@groups.io>
To: <devel@edk2.groups.io>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>,
	Erdem Aktas <erdemaktas@google.com>,
	Gerd Hoffmann <kraxel@redhat.com>,
	Jiewen Yao <jiewen.yao@intel.com>,
	Laszlo Ersek <lersek@redhat.com>,
	Liming Gao <gaoliming@byosoft.com.cn>,
	Michael D Kinney <michael.d.kinney@intel.com>,
	Min Xu <min.m.xu@intel.com>,
	Zhiguang Liu <zhiguang.liu@intel.com>,
	"Rahul Kumar" <rahul1.kumar@intel.com>, Ray Ni <ray.ni@intel.com>,
	Michael Roth <michael.roth@amd.com>
Subject: [edk2-devel] [PATCH v2 18/23] OvmfPkg/CcSvsmLib: Add support for the SVSM_CORE_PVALIDATE call
Date: Thu, 22 Feb 2024 11:29:57 -0600	[thread overview]
Message-ID: <5ab12366a86d88ea6ae81b496a366f94dbcaa944.1708623001.git.thomas.lendacky@amd.com> (raw)
In-Reply-To: <cover.1708623001.git.thomas.lendacky@amd.com>

BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4654

The PVALIDATE instruction can only be performed at VMPL0. An SVSM will
be present when running at VMPL1 or higher.

When an SVSM is present, use the SVSM_CORE_PVALIDATE call to perform
memory validation instead of issuing the PVALIDATE instruction directly.

Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
---
 OvmfPkg/Library/CcSvsmLib/CcSvsmLib.c | 183 +++++++++++++++++++-
 1 file changed, 182 insertions(+), 1 deletion(-)

diff --git a/OvmfPkg/Library/CcSvsmLib/CcSvsmLib.c b/OvmfPkg/Library/CcSvsmLib/CcSvsmLib.c
index f45ae472783c..017ca715cee5 100644
--- a/OvmfPkg/Library/CcSvsmLib/CcSvsmLib.c
+++ b/OvmfPkg/Library/CcSvsmLib/CcSvsmLib.c
@@ -8,6 +8,7 @@
 
 #include <Base.h>
 #include <Uefi.h>
+#include <Library/BaseMemoryLib.h>
 #include <Library/CcSvsmLib.h>
 #include <Register/Amd/Msr.h>
 #include <Register/Amd/Svsm.h>
@@ -43,6 +44,78 @@ SnpTerminate (
   CpuDeadLoop ();
 }
 
+/**
+  Issue an SVSM request.
+
+  Invokes the SVSM to process a request on behalf of the guest.
+
+  @param[in,out]  SvsmCallData  Pointer to the SVSM call data
+
+  @return                       Contents of RAX upon return from VMGEXIT
+**/
+STATIC
+UINTN
+SvsmMsrProtocol (
+  IN OUT SVSM_CALL_DATA  *SvsmCallData
+  )
+{
+  MSR_SEV_ES_GHCB_REGISTER  Msr;
+  UINT64                    CurrentMsr;
+  UINT8                     Pending;
+  BOOLEAN                   InterruptState;
+  UINTN                     Ret;
+
+  do {
+    //
+    // Be sure that an interrupt can't cause a #VC while the GHCB MSR protocol
+    // is being used (#VC handler will ASSERT if lower 12-bits are not zero).
+    //
+    InterruptState = GetInterruptState ();
+    if (InterruptState) {
+      DisableInterrupts ();
+    }
+
+    Pending                   = 0;
+    SvsmCallData->CallPending = &Pending;
+
+    CurrentMsr = AsmReadMsr64 (MSR_SEV_ES_GHCB);
+
+    Msr.Uint64                  = 0;
+    Msr.SnpVmplRequest.Function = GHCB_INFO_SNP_VMPL_REQUEST;
+    Msr.SnpVmplRequest.Vmpl     = 0;
+    AsmWriteMsr64 (MSR_SEV_ES_GHCB, Msr.Uint64);
+
+    //
+    // Guest memory is used for the guest-SVSM communication, so fence the
+    // invocation of the VMGEXIT instruction to ensure VMSA accesses are
+    // synchronized properly.
+    //
+    MemoryFence ();
+    Ret = AsmVmgExitSvsm (SvsmCallData);
+    MemoryFence ();
+
+    Msr.Uint64 = AsmReadMsr64 (MSR_SEV_ES_GHCB);
+
+    AsmWriteMsr64 (MSR_SEV_ES_GHCB, CurrentMsr);
+
+    if (InterruptState) {
+      EnableInterrupts ();
+    }
+
+    if (Pending != 0) {
+      SnpTerminate ();
+    }
+
+    if ((Msr.SnpVmplResponse.Function != GHCB_INFO_SNP_VMPL_RESPONSE) ||
+        (Msr.SnpVmplResponse.ErrorCode != 0))
+    {
+      SnpTerminate ();
+    }
+  } while (Ret == SVSM_ERR_INCOMPLETE || Ret == SVSM_ERR_BUSY);
+
+  return Ret;
+}
+
 /**
   Report the presence of an Secure Virtual Services Module (SVSM).
 
@@ -109,6 +182,114 @@ CcSvsmSnpGetCaa (
   return CcSvsmIsSvsmPresent () ? SvsmInfo->SvsmCaa : 0;
 }
 
+/**
+  Issue an SVSM request to perform the PVALIDATE instruction.
+
+  Invokes the SVSM to process the PVALIDATE instruction on behalf of the
+  guest to validate or invalidate the memory range specified.
+
+  @param[in]       Info           Pointer to a page state change structure
+
+**/
+STATIC
+VOID
+SvsmPvalidate (
+  IN SNP_PAGE_STATE_CHANGE_INFO  *Info
+  )
+{
+  SVSM_CALL_DATA          SvsmCallData;
+  SVSM_CAA                *Caa;
+  SVSM_PVALIDATE_REQUEST  *Request;
+  SVSM_FUNCTION           Function;
+  BOOLEAN                 Validate;
+  UINTN                   Entry;
+  UINTN                   EntryLimit;
+  UINTN                   Index;
+  UINTN                   EndIndex;
+  UINT64                  Gfn;
+  UINT64                  GfnEnd;
+  UINTN                   Ret;
+
+  Caa = (SVSM_CAA *)CcSvsmSnpGetCaa ();
+  SetMem (Caa->SvsmBuffer, sizeof (Caa->SvsmBuffer), 0);
+
+  Function.Id.Protocol = 0;
+  Function.Id.CallId   = 1;
+
+  Request    = (SVSM_PVALIDATE_REQUEST *)Caa->SvsmBuffer;
+  EntryLimit = ((sizeof (Caa->SvsmBuffer) - sizeof (*Request)) /
+                sizeof (Request->Entry[0])) - 1;
+
+  SvsmCallData.Caa   = Caa;
+  SvsmCallData.RaxIn = Function.Uint64;
+  SvsmCallData.RcxIn = (UINT64)(UINTN)Request;
+
+  Entry    = 0;
+  Index    = Info->Header.CurrentEntry;
+  EndIndex = Info->Header.EndEntry;
+
+  while (Index <= EndIndex) {
+    Validate = Info->Entry[Index].Operation == SNP_PAGE_STATE_PRIVATE;
+
+    Request->Header.Entries++;
+    Request->Entry[Entry].Bits.PageSize = Info->Entry[Index].PageSize;
+    Request->Entry[Entry].Bits.Action   = (Validate == TRUE) ? 1 : 0;
+    Request->Entry[Entry].Bits.IgnoreCf = 0;
+    Request->Entry[Entry].Bits.Address  = Info->Entry[Index].GuestFrameNumber;
+
+    Entry++;
+    if ((Entry > EntryLimit) || (Index == EndIndex)) {
+      Ret = SvsmMsrProtocol (&SvsmCallData);
+      if ((Ret == SVSM_ERR_PVALIDATE_FAIL_SIZE_MISMATCH) &&
+          (Request->Entry[Request->Header.Next].Bits.PageSize != 0))
+      {
+        // Calculate the Index of the entry after the entry that failed
+        // before clearing the buffer so that processing can continue
+        // from that point
+        Index = Index - (Entry - Request->Header.Next) + 2;
+
+        // Obtain the failing GFN before clearing the buffer
+        Gfn = Request->Entry[Request->Header.Next].Bits.Address;
+
+        // Clear the buffer in prep for creating all new entries
+        SetMem (Caa->SvsmBuffer, sizeof (Caa->SvsmBuffer), 0);
+        Entry = 0;
+
+        GfnEnd = Gfn + PAGES_PER_2MB_ENTRY - 1;
+        for ( ; Gfn <= GfnEnd; Gfn++) {
+          Request->Header.Entries++;
+          Request->Entry[Entry].Bits.PageSize = 0;
+          Request->Entry[Entry].Bits.Action   = (Validate == TRUE) ? 1 : 0;
+          Request->Entry[Entry].Bits.IgnoreCf = 0;
+          Request->Entry[Entry].Bits.Address  = Gfn;
+
+          Entry++;
+          if ((Entry > EntryLimit) || (Gfn == GfnEnd)) {
+            Ret = SvsmMsrProtocol (&SvsmCallData);
+            if (Ret != 0) {
+              SnpTerminate ();
+            }
+
+            SetMem (Caa->SvsmBuffer, sizeof (Caa->SvsmBuffer), 0);
+            Entry = 0;
+          }
+        }
+
+        continue;
+      }
+
+      if (Ret != 0) {
+        SnpTerminate ();
+      }
+
+      SetMem (Caa->SvsmBuffer, sizeof (Caa->SvsmBuffer), 0);
+      Entry = 0;
+    }
+
+    Index++;
+  }
+}
+
 /**
   Perform a native PVALIDATE operation for the page ranges specified.
 
@@ -193,7 +374,7 @@ CcSvsmSnpPvalidate (
   IN SNP_PAGE_STATE_CHANGE_INFO  *Info
   )
 {
-  BasePvalidate (Info);
+  CcSvsmIsSvsmPresent () ? SvsmPvalidate (Info) : BasePvalidate (Info);
 }
 
 /**
-- 
2.42.0



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#115853): https://edk2.groups.io/g/devel/message/115853
Mute This Topic: https://groups.io/mt/104512972/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-



  parent reply	other threads:[~2024-02-22 17:32 UTC|newest]

Thread overview: 53+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-02-22 17:29 [edk2-devel] [PATCH v2 00/23] Provide SEV-SNP support for running under an SVSM Lendacky, Thomas via groups.io
2024-02-22 17:29 ` [edk2-devel] [PATCH v2 01/23] OvmfPkg/BaseMemEncryptLib: Fix error check from AsmRmpAdjust() Lendacky, Thomas via groups.io
2024-02-27  9:46   ` Gerd Hoffmann
2024-02-22 17:29 ` [edk2-devel] [PATCH v2 02/23] MdePkg: GHCB APIC ID retrieval support definitions Lendacky, Thomas via groups.io
2024-02-23  0:16   ` Ni, Ray
2024-02-27 10:02     ` Gerd Hoffmann
2024-02-22 17:29 ` [edk2-devel] [PATCH v2 03/23] OvmfPkg/PlatformPei: Retrieve APIC IDs from the hypervisor Lendacky, Thomas via groups.io
2024-02-27 10:03   ` Gerd Hoffmann
2024-02-22 17:29 ` [edk2-devel] [PATCH v2 04/23] UefiCpuPkg/MpInitLib: Always use AP Create if PcdSevSnpApicIds is set Lendacky, Thomas via groups.io
2024-02-27 10:11   ` Gerd Hoffmann
2024-02-22 17:29 ` [edk2-devel] [PATCH v2 05/23] OvmfPkg/BaseMemEncryptSevLib: Fix uncrustify errors Lendacky, Thomas via groups.io
2024-02-27 10:12   ` Gerd Hoffmann
2024-02-22 17:29 ` [edk2-devel] [PATCH v2 06/23] OvmfPkg/BaseMemEncryptSevLib: Calculate memory size for Page State Change Lendacky, Thomas via groups.io
2024-02-27 10:17   ` Gerd Hoffmann
2024-02-22 17:29 ` [edk2-devel] [PATCH v2 07/23] MdePkg: Avoid hardcoded value for number of Page State Change entries Lendacky, Thomas via groups.io
2024-02-27 10:18   ` Gerd Hoffmann
2024-02-27 15:52     ` Lendacky, Thomas via groups.io
2024-02-22 17:29 ` [edk2-devel] [PATCH v2 08/23] OvmfPkg/BaseMemEncryptSevLib: Re-organize page state change support Lendacky, Thomas via groups.io
2024-02-27 11:07   ` Gerd Hoffmann
2024-02-22 17:29 ` [edk2-devel] [PATCH v2 09/23] OvmfPkg/BaseMemEncryptSevLib: Maximize Page State Change efficiency Lendacky, Thomas via groups.io
2024-02-27 11:19   ` Gerd Hoffmann
2024-02-22 17:29 ` [edk2-devel] [PATCH v2 10/23] MdePkg/Register/Amd: Define the SVSM related information Lendacky, Thomas via groups.io
2024-02-22 17:29 ` [edk2-devel] [PATCH v2 11/23] MdePkg/BaseLib: Add a new VMGEXIT instruction invocation for SVSM Lendacky, Thomas via groups.io
2024-02-27 11:50   ` Gerd Hoffmann
2024-02-22 17:29 ` [edk2-devel] [PATCH v2 12/23] UefiCpuPkg/CcSvsmLib: Create the CcSvsmLib library to support an SVSM Lendacky, Thomas via groups.io
2024-02-27 11:53   ` Gerd Hoffmann
2024-02-22 17:29 ` [edk2-devel] [PATCH v2 13/23] UefiPayloadPkg: Prepare UefiPayloadPkg to use the CcSvsmLib library Lendacky, Thomas via groups.io
2024-02-27 11:54   ` Gerd Hoffmann
2024-02-22 17:29 ` [edk2-devel] [PATCH v2 14/23] Ovmfpkg/CcSvsmLib: Create CcSvsmLib to handle SVSM related services Lendacky, Thomas via groups.io
2024-02-28  8:40   ` Gerd Hoffmann
2024-02-28 15:51     ` Lendacky, Thomas via groups.io
2024-03-01 10:59       ` Gerd Hoffmann
2024-02-22 17:29 ` [edk2-devel] [PATCH v2 15/23] UefiCpuPkg/MpInitLib: Use CcSvsmSnpVmsaRmpAdjust() to set/clear VMSA Lendacky, Thomas via groups.io
2024-02-28  8:42   ` Gerd Hoffmann
2024-02-22 17:29 ` [edk2-devel] [PATCH v2 16/23] OvmfPkg/BaseMemEncryptSevLib: Use CcSvsmSnpPvalidate() to validate pages Lendacky, Thomas via groups.io
2024-02-28  8:43   ` Gerd Hoffmann
2024-02-22 17:29 ` [edk2-devel] [PATCH v2 17/23] OvmfPkg: Create a calling area used to communicate with the SVSM Lendacky, Thomas via groups.io
2024-02-28  8:44   ` Gerd Hoffmann
2024-02-22 17:29 ` Lendacky, Thomas via groups.io [this message]
2024-02-28  8:50   ` [edk2-devel] [PATCH v2 18/23] OvmfPkg/CcSvsmLib: Add support for the SVSM_CORE_PVALIDATE call Gerd Hoffmann
2024-02-28 15:58     ` Lendacky, Thomas via groups.io
2024-02-22 17:29 ` [edk2-devel] [PATCH v2 19/23] OvmfPkg/BaseMemEncryptSevLib: Maximize Page State Change efficiency Lendacky, Thomas via groups.io
2024-02-28  8:50   ` Gerd Hoffmann
2024-02-22 17:29 ` [edk2-devel] [PATCH v2 20/23] OvmfPkg/CcSvsmLib: Add support for the SVSM create/delete vCPU calls Lendacky, Thomas via groups.io
2024-02-28  8:52   ` Gerd Hoffmann
2024-02-22 17:30 ` [edk2-devel] [PATCH v2 21/23] UefiCpuPkg/MpInitLib: AP creation support under an SVSM Lendacky, Thomas via groups.io
2024-02-22 17:30 ` [edk2-devel] [PATCH v2 22/23] Ovmfpkg/CcExitLib: Provide SVSM discovery support Lendacky, Thomas via groups.io
2024-02-28  8:54   ` Gerd Hoffmann
2024-02-22 17:30 ` [edk2-devel] [PATCH v2 23/23] OvmfPkg/BaseMemEncryptLib: Check for presence of an SVSM when not at VMPL0 Lendacky, Thomas via groups.io
2024-02-28  6:14 ` [edk2-devel] [PATCH v2 00/23] Provide SEV-SNP support for running under an SVSM Yao, Jiewen
2024-02-28 16:19   ` Lendacky, Thomas via groups.io
2024-02-29 14:06     ` Yao, Jiewen
2024-02-29 14:36       ` Lendacky, Thomas via groups.io

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=5ab12366a86d88ea6ae81b496a366f94dbcaa944.1708623001.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