MdePkg: Add code to detect running as an SEV guest

Similar to Intel's Tdx, we need a mechanism to detect running as
an AMD SEV guest that will work in all phases everywhere. This
will be immediately used to prevent usage of MTRRs with SEV guests.

Signed-off-by: Richard Relph <richard.relph@amd.com>
diff --git a/MdePkg/Include/Library/BaseLib.h b/MdePkg/Include/Library/BaseLib.h
index b50a1d5..a2b5b01 100644
--- a/MdePkg/Include/Library/BaseLib.h
+++ b/MdePkg/Include/Library/BaseLib.h
@@ -5396,6 +5396,18 @@
   VOID

   );

 

+/**

+  Probe if running as some kind of SEV guest.

+

+  @return FALSE   Not running as a guest under any kind of SEV

+  @return TRUE    Running as a guest under any kind of SEV

+**/

+BOOLEAN

+EFIAPI

+SevGuestIsEnabled (

+  VOID

+  );

+

 #if defined (MDE_CPU_X64)

 //

 // The page size for the PVALIDATE instruction

diff --git a/MdePkg/Library/BaseLib/AmdSevNull.c b/MdePkg/Library/BaseLib/AmdSevNull.c
new file mode 100644
index 0000000..7610b6e
--- /dev/null
+++ b/MdePkg/Library/BaseLib/AmdSevNull.c
@@ -0,0 +1,26 @@
+/** @file

+

+  Null stub of SevLib

+

+  Copyright (c) 2025, Advanced Micro Devices, Inc. All rights reserved.<BR>

+  SPDX-License-Identifier: BSD-2-Clause-Patent

+

+**/

+

+#include <Library/BaseLib.h>

+#include <Uefi/UefiBaseType.h>

+

+/**

+  Probe if running as some kind of SEV guest.

+

+  @return FALSE   Not running as a guest under any kind of SEV

+  @return TRUE    Running as a guest under any kind of SEV

+**/

+BOOLEAN

+EFIAPI

+SevGuestIsEnabled (

+  VOID

+  )

+{

+  return FALSE;

+}

diff --git a/MdePkg/Library/BaseLib/BaseLib.inf b/MdePkg/Library/BaseLib/BaseLib.inf
index 7925d8c..aa067a7 100644
--- a/MdePkg/Library/BaseLib/BaseLib.inf
+++ b/MdePkg/Library/BaseLib/BaseLib.inf
@@ -213,6 +213,7 @@
   X86PatchInstruction.c

   X86SpeculationBarrier.c

   IntelTdxNull.c

+  X64/SevProbe.c

 

 [Sources.X64]

   X64/Thunk16.nasm

@@ -299,6 +300,7 @@
   X64/TdCall.nasm

   X64/TdVmcall.nasm

   X64/TdProbe.c

+  X64/SevProbe.c

 

   X64/Non-existing.c

   Math64.c

@@ -340,6 +342,7 @@
   Unaligned.c

   Math64.c

   IntelTdxNull.c

+  AmdSevNull.c

 

 [Sources.AARCH64]

   AArch64/InternalSwitchStack.c

@@ -368,6 +371,7 @@
   AArch64/ArmReadCntPctReg.asm      | MSFT

   AArch64/ArmReadIdAA64Isar0Reg.asm     | MSFT

   IntelTdxNull.c

+  AmdSevNull.c

 

 [Sources.RISCV64]

   Math64.c

@@ -390,6 +394,7 @@
   RiscV64/RiscVMmu.S                | GCC

   RiscV64/SpeculationBarrier.S      | GCC

   IntelTdxNull.c

+  AmdSevNull.c

 

 [Sources.LOONGARCH64]

   Math64.c

@@ -411,6 +416,7 @@
   LoongArch64/Cpucfg.S              | GCC

   LoongArch64/ReadStableCounter.S   | GCC

   IntelTdxNull.c

+  AmdSevNull.c

 

 [Packages]

   MdePkg/MdePkg.dec

diff --git a/MdePkg/Library/BaseLib/UnitTestHostBaseLib.inf b/MdePkg/Library/BaseLib/UnitTestHostBaseLib.inf
index 190e3b6..776c7cc 100644
--- a/MdePkg/Library/BaseLib/UnitTestHostBaseLib.inf
+++ b/MdePkg/Library/BaseLib/UnitTestHostBaseLib.inf
@@ -130,6 +130,7 @@
   X86SpeculationBarrier.c

   X86UnitTestHost.c

   IntelTdxNull.c

+  AmdSevNull.c

 

 [Sources.X64]

   X64/LongJump.nasm

@@ -170,6 +171,7 @@
   X64/RdRand.nasm

   X86UnitTestHost.c

   IntelTdxNull.c

+  AmdSevNull.c

 

 [Sources.EBC]

   Ebc/CpuBreakpoint.c

diff --git a/MdePkg/Library/BaseLib/X64/SevProbe.c b/MdePkg/Library/BaseLib/X64/SevProbe.c
new file mode 100644
index 0000000..2d1ab01
--- /dev/null
+++ b/MdePkg/Library/BaseLib/X64/SevProbe.c
@@ -0,0 +1,45 @@
+/** @file

+

+  Copyright (c) 2025, Advanced Micro Devices, Inc. All rights reserved.<BR>

+  SPDX-License-Identifier: BSD-2-Clause-Patent

+

+**/

+

+#include <Library/BaseLib.h>

+#include <Register/Amd/Cpuid.h>

+#include <Register/Amd/SevSnpMsr.h>

+#include <Register/Intel/Cpuid.h>

+

+/**

+  Probe if running as some kind of SEV guest.

+

+  @return FALSE   Not running as a guest under any kind of SEV

+  @return TRUE    Running as a guest under any kind of SEV

+**/

+BOOLEAN

+EFIAPI

+SevGuestIsEnabled (

+  VOID

+  )

+{

+  UINT32                            MaxExtendedLeaf;

+  MSR_SEV_STATUS_REGISTER           SevStatus;

+  CPUID_MEMORY_ENCRYPTION_INFO_EAX  MemoryEncryptionInfoEax;

+

+  // Check max extended CPUID leaf

+  AsmCpuid (CPUID_EXTENDED_FUNCTION, &MaxExtendedLeaf, NULL, NULL, NULL);

+  if (MaxExtendedLeaf < CPUID_MEMORY_ENCRYPTION_INFO) {

+    return FALSE;

+  }

+

+  // Check SEV support

+  AsmCpuid (CPUID_MEMORY_ENCRYPTION_INFO, &MemoryEncryptionInfoEax.Uint32, NULL, NULL, NULL);

+  if (MemoryEncryptionInfoEax.Bits.SevBit == 0) {

+    return FALSE;

+  }

+

+  // Read SEV_STATUS MSR

+  SevStatus.Uint64 = AsmReadMsr64 (MSR_SEV_STATUS);

+

+  return (SevStatus.Bits.SevBit | SevStatus.Bits.SevEsBit | SevStatus.Bits.SevSnpBit) ? TRUE : FALSE;

+}