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>,
	James Bottomley <jejb@linux.ibm.com>,
	Jordan Justen <jordan.l.justen@intel.com>,
	Laszlo Ersek <lersek@redhat.com>,
	Ard Biesheuvel <ard.biesheuvel@arm.com>
Subject: [PATCH v2 11/15] OvmfPkg/MemEncryptSevLib: Make the MemEncryptSevLib available for SEC
Date: Wed,  6 Jan 2021 15:21:37 -0600	[thread overview]
Message-ID: <5a3cac5933e29eaf3bfdd1e7406335784cbb8d6d.1609968101.git.thomas.lendacky@amd.com> (raw)
In-Reply-To: <cover.1609968101.git.thomas.lendacky@amd.com>

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

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

In preparation for a new interface to be added to the MemEncryptSevLib
library that will be used in SEC, create an SEC version of the library.

This requires the creation of SEC specific files.

Some of the current MemEncryptSevLib functions perform memory allocations
which cannot be performed in SEC, so these interfaces will return an error
during SEC. Also, the current MemEncryptSevLib library uses some static
variables to optimize access to variables, which cannot be used in SEC.

Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Cc: Brijesh Singh <brijesh.singh@amd.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
---
 OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf                                          |   4 +-
 OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLib.inf                                          |   4 +-
 OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLib.inf                                          |  50 +++++++
 OvmfPkg/Library/BaseMemEncryptSevLib/{MemEncryptSevLibInternal.c => PeiDxeMemEncryptSevLibInternal.c} |   0
 OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLibInternal.c                                    | 155 ++++++++++++++++++++
 OvmfPkg/Library/BaseMemEncryptSevLib/X64/{VirtualMemory.c => PeiDxeVirtualMemory.c}                   |   0
 OvmfPkg/Library/BaseMemEncryptSevLib/X64/SecVirtualMemory.c                                           |  80 ++++++++++
 7 files changed, 289 insertions(+), 4 deletions(-)

diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf b/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf
index 837db0876184..4480e4cc7c89 100644
--- a/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf
@@ -31,11 +31,11 @@ [Packages]
 
 [Sources]
   DxeMemEncryptSevLibInternal.c
-  MemEncryptSevLibInternal.c
+  PeiDxeMemEncryptSevLibInternal.c
 
 [Sources.X64]
   X64/MemEncryptSevLib.c
-  X64/VirtualMemory.c
+  X64/PeiDxeVirtualMemory.c
   X64/VirtualMemory.h
 
 [Sources.IA32]
diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLib.inf b/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLib.inf
index 7c29d14039d6..faabd234e393 100644
--- a/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLib.inf
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLib.inf
@@ -31,11 +31,11 @@ [Packages]
 
 [Sources]
   PeiMemEncryptSevLibInternal.c
-  MemEncryptSevLibInternal.c
+  PeiDxeMemEncryptSevLibInternal.c
 
 [Sources.X64]
   X64/MemEncryptSevLib.c
-  X64/VirtualMemory.c
+  X64/PeiDxeVirtualMemory.c
   X64/VirtualMemory.h
 
 [Sources.IA32]
diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLib.inf b/OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLib.inf
new file mode 100644
index 000000000000..7cd0111fe47b
--- /dev/null
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLib.inf
@@ -0,0 +1,50 @@
+## @file
+#  Library provides the helper functions for SEV guest
+#
+# Copyright (c) 2020 Advanced Micro Devices. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+  INF_VERSION                    = 1.25
+  BASE_NAME                      = SecMemEncryptSevLib
+  FILE_GUID                      = 046388b4-430e-4e61-88f6-51ea21db2632
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = MemEncryptSevLib|SEC
+
+#
+# The following information is for reference only and not required by the build
+# tools.
+#
+# VALID_ARCHITECTURES           = IA32 X64
+#
+
+[Packages]
+  MdeModulePkg/MdeModulePkg.dec
+  MdePkg/MdePkg.dec
+  OvmfPkg/OvmfPkg.dec
+  UefiCpuPkg/UefiCpuPkg.dec
+
+[Sources]
+  SecMemEncryptSevLibInternal.c
+
+[Sources.X64]
+  X64/MemEncryptSevLib.c
+  X64/SecVirtualMemory.c
+  X64/VirtualMemory.h
+
+[Sources.IA32]
+  Ia32/MemEncryptSevLib.c
+
+[LibraryClasses]
+  BaseLib
+  CpuLib
+  DebugLib
+  PcdLib
+
+[FixedPcd]
+  gUefiCpuPkgTokenSpaceGuid.PcdSevEsWorkAreaBase
diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/MemEncryptSevLibInternal.c b/OvmfPkg/Library/BaseMemEncryptSevLib/PeiDxeMemEncryptSevLibInternal.c
similarity index 100%
rename from OvmfPkg/Library/BaseMemEncryptSevLib/MemEncryptSevLibInternal.c
rename to OvmfPkg/Library/BaseMemEncryptSevLib/PeiDxeMemEncryptSevLibInternal.c
diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLibInternal.c b/OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLibInternal.c
new file mode 100644
index 000000000000..56d8f3f3183f
--- /dev/null
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLibInternal.c
@@ -0,0 +1,155 @@
+/** @file
+
+  Secure Encrypted Virtualization (SEV) library helper function
+
+  Copyright (c) 2020, Advanced Micro Devices, Inc. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemEncryptSevLib.h>
+#include <Library/PcdLib.h>
+#include <Register/Amd/Cpuid.h>
+#include <Register/Amd/Msr.h>
+#include <Register/Cpuid.h>
+#include <Uefi/UefiBaseType.h>
+
+/**
+  Reads and sets the status of SEV features.
+
+  **/
+STATIC
+UINT32
+EFIAPI
+InternalMemEncryptSevStatus (
+  VOID
+  )
+{
+  UINT32                            RegEax;
+  CPUID_MEMORY_ENCRYPTION_INFO_EAX  Eax;
+  BOOLEAN                           ReadSevMsr;
+  SEC_SEV_ES_WORK_AREA              *SevEsWorkArea;
+
+  ReadSevMsr = FALSE;
+
+  SevEsWorkArea = (SEC_SEV_ES_WORK_AREA *) FixedPcdGet32 (PcdSevEsWorkAreaBase);
+  if (SevEsWorkArea != NULL && SevEsWorkArea->EncryptionMask != 0) {
+    //
+    // The MSR has been read before, so it is safe to read it again and avoid
+    // having to validate the CPUID information.
+    //
+    ReadSevMsr = TRUE;
+  } else {
+    //
+    // Check if memory encryption leaf exist
+    //
+    AsmCpuid (CPUID_EXTENDED_FUNCTION, &RegEax, NULL, NULL, NULL);
+    if (RegEax >= CPUID_MEMORY_ENCRYPTION_INFO) {
+      //
+      // CPUID Fn8000_001F[EAX] Bit 1 (Sev supported)
+      //
+      AsmCpuid (CPUID_MEMORY_ENCRYPTION_INFO, &Eax.Uint32, NULL, NULL, NULL);
+
+      if (Eax.Bits.SevBit) {
+        ReadSevMsr = TRUE;
+      }
+    }
+  }
+
+  return ReadSevMsr ? AsmReadMsr32 (MSR_SEV_STATUS) : 0;
+}
+
+/**
+  Returns a boolean to indicate whether SEV-ES is enabled.
+
+  @retval TRUE           SEV-ES is enabled
+  @retval FALSE          SEV-ES is not enabled
+**/
+BOOLEAN
+EFIAPI
+MemEncryptSevEsIsEnabled (
+  VOID
+  )
+{
+  MSR_SEV_STATUS_REGISTER           Msr;
+
+  Msr.Uint32 = InternalMemEncryptSevStatus ();
+
+  return Msr.Bits.SevEsBit ? TRUE : FALSE;
+}
+
+/**
+  Returns a boolean to indicate whether SEV is enabled.
+
+  @retval TRUE           SEV is enabled
+  @retval FALSE          SEV is not enabled
+**/
+BOOLEAN
+EFIAPI
+MemEncryptSevIsEnabled (
+  VOID
+  )
+{
+  MSR_SEV_STATUS_REGISTER           Msr;
+
+  Msr.Uint32 = InternalMemEncryptSevStatus ();
+
+  return Msr.Bits.SevBit ? TRUE : FALSE;
+}
+
+/**
+  Returns the SEV encryption mask.
+
+  @return  The SEV pagtable encryption mask
+**/
+UINT64
+EFIAPI
+MemEncryptSevGetEncryptionMask (
+  VOID
+  )
+{
+  CPUID_MEMORY_ENCRYPTION_INFO_EBX  Ebx;
+  SEC_SEV_ES_WORK_AREA              *SevEsWorkArea;
+  UINT64                            EncryptionMask;
+
+  SevEsWorkArea = (SEC_SEV_ES_WORK_AREA *) FixedPcdGet32 (PcdSevEsWorkAreaBase);
+  if (SevEsWorkArea != NULL) {
+    EncryptionMask = SevEsWorkArea->EncryptionMask;
+  } else {
+    //
+    // CPUID Fn8000_001F[EBX] Bit 0:5 (memory encryption bit position)
+    //
+    AsmCpuid (CPUID_MEMORY_ENCRYPTION_INFO, NULL, &Ebx.Uint32, NULL, NULL);
+    EncryptionMask = LShiftU64 (1, Ebx.Bits.PtePosBits);
+  }
+
+  return EncryptionMask;
+}
+
+/**
+  Locate the page range that covers the initial (pre-SMBASE-relocation) SMRAM
+  Save State Map.
+
+  @param[out] BaseAddress     The base address of the lowest-address page that
+                              covers the initial SMRAM Save State Map.
+
+  @param[out] NumberOfPages   The number of pages in the page range that covers
+                              the initial SMRAM Save State Map.
+
+  @retval RETURN_SUCCESS      BaseAddress and NumberOfPages have been set on
+                              output.
+
+  @retval RETURN_UNSUPPORTED  SMM is unavailable.
+**/
+RETURN_STATUS
+EFIAPI
+MemEncryptSevLocateInitialSmramSaveStateMapPages (
+  OUT UINTN *BaseAddress,
+  OUT UINTN *NumberOfPages
+  )
+{
+  return RETURN_UNSUPPORTED;
+}
diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/VirtualMemory.c b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c
similarity index 100%
rename from OvmfPkg/Library/BaseMemEncryptSevLib/X64/VirtualMemory.c
rename to OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c
diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SecVirtualMemory.c b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SecVirtualMemory.c
new file mode 100644
index 000000000000..5c337ea0b820
--- /dev/null
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SecVirtualMemory.c
@@ -0,0 +1,80 @@
+/** @file
+
+  Virtual Memory Management Services to set or clear the memory encryption bit
+
+  Copyright (c) 2020, AMD Incorporated. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Library/CpuLib.h>
+#include <Library/MemEncryptSevLib.h>
+
+#include "VirtualMemory.h"
+
+/**
+  This function clears memory encryption bit for the memory region specified by
+  PhysicalAddress and Length from the current page table context.
+
+  @param[in]  Cr3BaseAddress          Cr3 Base Address (if zero then use
+                                      current CR3)
+  @param[in]  PhysicalAddress         The physical address that is the start
+                                      address of a memory region.
+  @param[in]  Length                  The length of memory region
+  @param[in]  Flush                   Flush the caches before applying the
+                                      encryption mask
+
+  @retval RETURN_SUCCESS              The attributes were cleared for the
+                                      memory region.
+  @retval RETURN_INVALID_PARAMETER    Number of pages is zero.
+  @retval RETURN_UNSUPPORTED          Clearing the memory encyrption attribute
+                                      is not supported
+**/
+RETURN_STATUS
+EFIAPI
+InternalMemEncryptSevSetMemoryDecrypted (
+  IN  PHYSICAL_ADDRESS        Cr3BaseAddress,
+  IN  PHYSICAL_ADDRESS        PhysicalAddress,
+  IN  UINTN                   Length,
+  IN  BOOLEAN                 Flush
+  )
+{
+  //
+  // This function is not available during SEC.
+  //
+  return RETURN_UNSUPPORTED;
+}
+
+/**
+  This function sets memory encryption bit for the memory region specified by
+  PhysicalAddress and Length from the current page table context.
+
+  @param[in]  Cr3BaseAddress          Cr3 Base Address (if zero then use
+                                      current CR3)
+  @param[in]  PhysicalAddress         The physical address that is the start
+                                      address of a memory region.
+  @param[in]  Length                  The length of memory region
+  @param[in]  Flush                   Flush the caches before applying the
+                                      encryption mask
+
+  @retval RETURN_SUCCESS              The attributes were set for the memory
+                                      region.
+  @retval RETURN_INVALID_PARAMETER    Number of pages is zero.
+  @retval RETURN_UNSUPPORTED          Setting the memory encyrption attribute
+                                      is not supported
+**/
+RETURN_STATUS
+EFIAPI
+InternalMemEncryptSevSetMemoryEncrypted (
+  IN  PHYSICAL_ADDRESS        Cr3BaseAddress,
+  IN  PHYSICAL_ADDRESS        PhysicalAddress,
+  IN  UINTN                   Length,
+  IN  BOOLEAN                 Flush
+  )
+{
+  //
+  // This function is not available during SEC.
+  //
+  return RETURN_UNSUPPORTED;
+}
-- 
2.30.0


  parent reply	other threads:[~2021-01-06 21:23 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-01-06 21:21 [PATCH v2 00/15] SEV-ES security mitigations Lendacky, Thomas
2021-01-06 21:21 ` [PATCH v2 01/15] Ovmf/ResetVector: Simplify and consolidate the SEV features checks Lendacky, Thomas
2021-01-06 21:21 ` [PATCH v2 02/15] OvmfPkg/Sec: Move SEV-ES SEC workarea definition to common header file Lendacky, Thomas
2021-01-06 21:21 ` [PATCH v2 03/15] OvmfPkg/ResetVector: Validate the encryption bit position for SEV/SEV-ES Lendacky, Thomas
2021-01-07 14:43   ` [edk2-devel] " Laszlo Ersek
2021-01-06 21:21 ` [PATCH v2 04/15] OvmfPkg/ResetVector: Perform a simple SEV-ES sanity check Lendacky, Thomas
2021-01-07 14:44   ` [edk2-devel] " Laszlo Ersek
2021-01-06 21:21 ` [PATCH v2 05/15] OvmfPkg/MemEncryptSevLib: Save the encryption mask at boot time Lendacky, Thomas
2021-01-07 14:52   ` [edk2-devel] " Laszlo Ersek
2021-01-06 21:21 ` [PATCH v2 06/15] OvmfPkg/MemEncryptSevLib: Add an interface to retrieve the encryption mask Lendacky, Thomas
2021-01-07 15:50   ` [edk2-devel] " Laszlo Ersek
2021-01-06 21:21 ` [PATCH v2 07/15] OvmfPkg/MemEncryptSevLib: Obtain encryption mask using the new interface Lendacky, Thomas
2021-01-07 15:56   ` [edk2-devel] " Laszlo Ersek
2021-01-06 21:21 ` [PATCH v2 08/15] OvmfPkg/AmdSevDxe: Clear encryption bit on PCIe MMCONFIG range Lendacky, Thomas
2021-01-07 17:11   ` [edk2-devel] " Laszlo Ersek
2021-01-06 21:21 ` [PATCH v2 09/15] OvmfPkg/VmgExitLib: Check for an explicit DR7 cached value Lendacky, Thomas
2021-01-06 21:21 ` [PATCH v2 10/15] OvmfPkg/MemEncryptSevLib: Coding style fixes in prep for SEC library Lendacky, Thomas
2021-01-07 17:12   ` [edk2-devel] " Laszlo Ersek
2021-01-06 21:21 ` Lendacky, Thomas [this message]
2021-01-07 17:22   ` [edk2-devel] [PATCH v2 11/15] OvmfPkg/MemEncryptSevLib: Make the MemEncryptSevLib available for SEC Laszlo Ersek
2021-01-06 21:21 ` [PATCH v2 12/15] OvmfPkg/MemEncryptSevLib: Address range encryption state interface Lendacky, Thomas
2021-01-06 21:21 ` [PATCH v2 13/15] OvmfPkg/VmgExitLib: Support nested #VCs Lendacky, Thomas
2021-01-06 21:21 ` [PATCH v2 14/15] OvmfPkg/PlatformPei: Reserve GHCB backup pages if S3 is supported Lendacky, Thomas
2021-01-07 17:25   ` [edk2-devel] " Laszlo Ersek
2021-01-06 21:21 ` [PATCH v2 15/15] OvfmPkg/VmgExitLib: Validate #VC MMIO is to un-encrypted memory Lendacky, Thomas
2021-01-07 17:27   ` [edk2-devel] " Laszlo Ersek
2021-01-07 17:33     ` Lendacky, Thomas
2021-01-07 17:48       ` Laszlo Ersek
2021-01-07 18:37         ` 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=5a3cac5933e29eaf3bfdd1e7406335784cbb8d6d.1609968101.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