[edk2-devel] [PATCH v9 7/9] UefiCpuPkg: Implements MmSaveStateLib for Ovmf

Abdul Lateef Attar via groups.io posted 9 patches 2 years, 9 months ago
There is a newer version of this series
[edk2-devel] [PATCH v9 7/9] UefiCpuPkg: Implements MmSaveStateLib for Ovmf
Posted by Abdul Lateef Attar via groups.io 2 years, 9 months ago
From: Abdul Lateef Attar <AbdulLateef.Attar@amd.com>

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

Implements MmSaveStateLib library interfaces
to read and write save state
registers for Ovmf/Qemu.

Cc: Paul Grimes <paul.grimes@amd.com>
Cc: Garrett Kirkendall <garrett.kirkendall@amd.com>
Cc: Abner Chang <abner.chang@amd.com>
Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Signed-off-by: Abdul Lateef Attar <abdattar@amd.com>
---
 UefiCpuPkg/UefiCpuPkg.dsc                     |  10 +
 .../MmSaveStateLib/OvmfMmSaveStateLib.inf     |  29 +
 .../Library/MmSaveStateLib/OvmfMmSaveState.c  | 612 ++++++++++++++++++
 UefiCpuPkg/UefiCpuPkg.ci.yaml                 |   1 +
 4 files changed, 652 insertions(+)
 create mode 100644 UefiCpuPkg/Library/MmSaveStateLib/OvmfMmSaveStateLib.inf
 create mode 100644 UefiCpuPkg/Library/MmSaveStateLib/OvmfMmSaveState.c

diff --git a/UefiCpuPkg/UefiCpuPkg.dsc b/UefiCpuPkg/UefiCpuPkg.dsc
index cc681b6b5b07..8ca04968c550 100644
--- a/UefiCpuPkg/UefiCpuPkg.dsc
+++ b/UefiCpuPkg/UefiCpuPkg.dsc
@@ -179,6 +179,15 @@ [Components.IA32, Components.X64]
       SmmCpuPlatformHookLib|UefiCpuPkg/Library/SmmCpuPlatformHookLibNull/SmmCpuPlatformHookLibNull.inf
       MmSaveStateLib|UefiCpuPkg/Library/MmSaveStateLib/AmdMmSaveStateLib.inf
   }
+
+  UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf {
+    <Defines>
+      FILE_GUID = 8734325E-DEAD-4742-A582-EC6E0E1CDE2B
+    <LibraryClasses>
+      SmmCpuPlatformHookLib|UefiCpuPkg/Library/SmmCpuPlatformHookLibNull/SmmCpuPlatformHookLibNull.inf
+      MmSaveStateLib|UefiCpuPkg/Library/MmSaveStateLib/OvmfMmSaveStateLib.inf
+  }
+
   UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2Pei.inf
   UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVector.inf
   UefiCpuPkg/Library/SmmCpuRendezvousLib/SmmCpuRendezvousLib.inf
@@ -196,6 +205,7 @@ [Components.IA32, Components.X64]
   }
   UefiCpuPkg/Library/MmSaveStateLib/AmdMmSaveStateLib.inf
   UefiCpuPkg/Library/MmSaveStateLib/IntelMmSaveStateLib.inf
+  UefiCpuPkg/Library/MmSaveStateLib/OvmfMmSaveStateLib.inf
   UefiCpuPkg/Library/SmmCpuFeaturesLib/AmdSmmCpuFeaturesLib.inf
 
 [Components.X64]
diff --git a/UefiCpuPkg/Library/MmSaveStateLib/OvmfMmSaveStateLib.inf b/UefiCpuPkg/Library/MmSaveStateLib/OvmfMmSaveStateLib.inf
new file mode 100644
index 000000000000..68f5813db21e
--- /dev/null
+++ b/UefiCpuPkg/Library/MmSaveStateLib/OvmfMmSaveStateLib.inf
@@ -0,0 +1,29 @@
+## @file
+# MM Smram save state service lib.
+#
+# This is MM Smram save state service lib that provide service to read and
+# save savestate area registers.
+#
+# Copyright (C) 2023 Advanced Micro Devices, Inc. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 1.29
+  BASE_NAME                      = OvmfMmSaveStateLib
+  FILE_GUID                      = 689676f1-6da9-4169-b8bd-be4437e68c36
+  MODULE_TYPE                    = DXE_SMM_DRIVER
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = MmSaveStateLib
+
+[Sources]
+  MmSaveState.h
+  MmSaveStateCommon.c
+  OvmfMmSaveState.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  OvmfPkg/OvmfPkg.dec
+  UefiCpuPkg/UefiCpuPkg.dec
diff --git a/UefiCpuPkg/Library/MmSaveStateLib/OvmfMmSaveState.c b/UefiCpuPkg/Library/MmSaveStateLib/OvmfMmSaveState.c
new file mode 100644
index 000000000000..19b5f0399fff
--- /dev/null
+++ b/UefiCpuPkg/Library/MmSaveStateLib/OvmfMmSaveState.c
@@ -0,0 +1,612 @@
+/** @file
+Provides services to access SMRAM Save State Map
+
+Copyright (c) 2010 - 2023, Intel Corporation. All rights reserved.<BR>
+Copyright (C) 2023 Advanced Micro Devices, Inc. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "MmSaveState.h"
+#include <Register/QemuSmramSaveStateMap.h>
+#include <Library/BaseLib.h>
+
+///
+/// Macro used to simplify the lookup table entries of type
+/// CPU_MM_SAVE_STATE_LOOKUP_ENTRY
+///
+#define MM_CPU_OFFSET(Field)  OFFSET_OF (QEMU_SMRAM_SAVE_STATE_MAP, Field)
+
+///
+/// Lookup table used to retrieve the widths and offsets associated with each
+/// supported EFI_MM_SAVE_STATE_REGISTER value
+///
+CONST CPU_MM_SAVE_STATE_LOOKUP_ENTRY  mCpuWidthOffset[] = {
+  {
+    0,                                    // Width32
+    0,                                    // Width64
+    0,                                    // Offset32
+    0,                                    // Offset64Lo
+    0,                                    // Offset64Hi
+    FALSE                                 // Writeable
+  }, // Reserved
+
+  //
+  // CPU Save State registers defined in PI SMM CPU Protocol.
+  //
+  {
+    0,                                   // Width32
+    8,                                   // Width64
+    0,                                   // Offset32
+    MM_CPU_OFFSET (x64._GDTRBase),       // Offset64Lo
+    MM_CPU_OFFSET (x64._GDTRBase) + 4,   // Offset64Hi
+    FALSE                                // Writeable
+  }, // EFI_MM_SAVE_STATE_REGISTER_GDTBASE = 4
+
+  {
+    0,                                   // Width32
+    8,                                   // Width64
+    0,                                   // Offset32
+    MM_CPU_OFFSET (x64._IDTRBase),       // Offset64Lo
+    MM_CPU_OFFSET (x64._IDTRBase) + 4,   // Offset64Hi
+    FALSE                                // Writeable
+  }, // EFI_MM_SAVE_STATE_REGISTER_IDTBASE = 5
+
+  {
+    0,                                   // Width32
+    8,                                   // Width64
+    0,                                   // Offset32
+    MM_CPU_OFFSET (x64._LDTRBase),       // Offset64Lo
+    MM_CPU_OFFSET (x64._LDTRBase) + 4,   // Offset64Hi
+    FALSE                                // Writeable
+  }, // EFI_MM_SAVE_STATE_REGISTER_LDTBASE = 6
+
+  {
+    0,                                   // Width32
+    0,                                   // Width64
+    0,                                   // Offset32
+    MM_CPU_OFFSET (x64._GDTRLimit),      // Offset64Lo
+    MM_CPU_OFFSET (x64._GDTRLimit) + 4,  // Offset64Hi
+    FALSE                                // Writeable
+  }, // EFI_MM_SAVE_STATE_REGISTER_GDTLIMIT = 7
+
+  {
+    0,                                   // Width32
+    0,                                   // Width64
+    0,                                   // Offset32
+    MM_CPU_OFFSET (x64._IDTRLimit),      // Offset64Lo
+    MM_CPU_OFFSET (x64._IDTRLimit) + 4,  // Offset64Hi
+    FALSE                                // Writeable
+  }, // EFI_MM_SAVE_STATE_REGISTER_IDTLIMIT = 8
+
+  {
+    0,                                   // Width32
+    0,                                   // Width64
+    0,                                   // Offset32
+    MM_CPU_OFFSET (x64._LDTRLimit),      // Offset64Lo
+    MM_CPU_OFFSET (x64._LDTRLimit) + 4,  // Offset64Hi
+    FALSE                                // Writeable
+  }, // EFI_MM_SAVE_STATE_REGISTER_LDTLIMIT = 9
+
+  {
+    0,                                    // Width32
+    0,                                    // Width64
+    0,                                    // Offset32
+    0,                                    // Offset64Lo
+    0 + 4,                                // Offset64Hi
+    FALSE                                 // Writeable
+  }, // EFI_MM_SAVE_STATE_REGISTER_LDTINFO = 10
+
+  {
+    4,                                   // Width32
+    4,                                   // Width64
+    MM_CPU_OFFSET (x86._ES),             // Offset32
+    MM_CPU_OFFSET (x64._ES),             // Offset64Lo
+    0,                                   // Offset64Hi
+    FALSE                                // Writeable
+  }, // EFI_MM_SAVE_STATE_REGISTER_ES = 20
+
+  {
+    4,                                   // Width32
+    4,                                   // Width64
+    MM_CPU_OFFSET (x86._CS),             // Offset32
+    MM_CPU_OFFSET (x64._CS),             // Offset64Lo
+    0,                                   // Offset64Hi
+    FALSE                                // Writeable
+  }, // EFI_MM_SAVE_STATE_REGISTER_CS = 21
+
+  {
+    4,                                   // Width32
+    4,                                   // Width64
+    MM_CPU_OFFSET (x86._SS),             // Offset32
+    MM_CPU_OFFSET (x64._SS),             // Offset64Lo
+    0,                                   // Offset64Hi
+    FALSE                                // Writeable
+  }, // EFI_MM_SAVE_STATE_REGISTER_SS = 22
+
+  {
+    4,                                   // Width32
+    4,                                   // Width64
+    MM_CPU_OFFSET (x86._DS),             // Offset32
+    MM_CPU_OFFSET (x64._DS),             // Offset64Lo
+    0,                                   // Offset64Hi
+    FALSE                                // Writeable
+  }, // EFI_MM_SAVE_STATE_REGISTER_DS = 23
+
+  {
+    4,                                   // Width32
+    4,                                   // Width64
+    MM_CPU_OFFSET (x86._FS),             // Offset32
+    MM_CPU_OFFSET (x64._FS),             // Offset64Lo
+    0,                                   // Offset64Hi
+    FALSE                                // Writeable
+  }, // EFI_MM_SAVE_STATE_REGISTER_FS = 24
+
+  {
+    4,                                   // Width32
+    4,                                   // Width64
+    MM_CPU_OFFSET (x86._GS),             // Offset32
+    MM_CPU_OFFSET (x64._GS),             // Offset64Lo
+    0,                                   // Offset64Hi
+    FALSE                                // Writeable
+  }, // EFI_MM_SAVE_STATE_REGISTER_GS = 25
+
+  {
+    0,                                   // Width32
+    4,                                   // Width64
+    0,                                   // Offset32
+    MM_CPU_OFFSET (x64._LDTR),           // Offset64Lo
+    0,                                   // Offset64Hi
+    FALSE                                // Writeable
+  }, // EFI_MM_SAVE_STATE_REGISTER_LDTR_SEL = 26
+
+  {
+    4,                                   // Width32
+    4,                                   // Width64
+    MM_CPU_OFFSET (x86._TR),             // Offset32
+    MM_CPU_OFFSET (x64._TR),             // Offset64Lo
+    0,                                   // Offset64Hi
+    FALSE                                // Writeable
+  }, // EFI_MM_SAVE_STATE_REGISTER_TR_SEL = 27
+
+  {
+    4,                                   // Width32
+    8,                                   // Width64
+    MM_CPU_OFFSET (x86._DR7),            // Offset32
+    MM_CPU_OFFSET (x64._DR7),            // Offset64Lo
+    MM_CPU_OFFSET (x64._DR7) + 4,        // Offset64Hi
+    FALSE                                // Writeable
+  }, // EFI_MM_SAVE_STATE_REGISTER_DR7 = 28
+
+  {
+    4,                                   // Width32
+    8,                                   // Width64
+    MM_CPU_OFFSET (x86._DR6),            // Offset32
+    MM_CPU_OFFSET (x64._DR6),            // Offset64Lo
+    MM_CPU_OFFSET (x64._DR6) + 4,        // Offset64Hi
+    FALSE                                // Writeable
+  }, // EFI_MM_SAVE_STATE_REGISTER_DR6 = 29
+
+  {
+    0,                                   // Width32
+    8,                                   // Width64
+    0,                                   // Offset32
+    MM_CPU_OFFSET (x64._R8),             // Offset64Lo
+    MM_CPU_OFFSET (x64._R8) + 4,         // Offset64Hi
+    TRUE                                 // Writeable
+  }, // EFI_MM_SAVE_STATE_REGISTER_R8 = 30
+
+  {
+    0,                                   // Width32
+    8,                                   // Width64
+    0,                                   // Offset32
+    MM_CPU_OFFSET (x64._R9),             // Offset64Lo
+    MM_CPU_OFFSET (x64._R9) + 4,         // Offset64Hi
+    TRUE                                 // Writeable
+  }, // EFI_MM_SAVE_STATE_REGISTER_R9 = 31
+
+  {
+    0,                                   // Width32
+    8,                                   // Width64
+    0,                                   // Offset32
+    MM_CPU_OFFSET (x64._R10),            // Offset64Lo
+    MM_CPU_OFFSET (x64._R10) + 4,        // Offset64Hi
+    TRUE                                 // Writeable
+  }, // EFI_MM_SAVE_STATE_REGISTER_R10 = 32
+
+  {
+    0,                                   // Width32
+    8,                                   // Width64
+    0,                                   // Offset32
+    MM_CPU_OFFSET (x64._R11),            // Offset64Lo
+    MM_CPU_OFFSET (x64._R11) + 4,        // Offset64Hi
+    TRUE                                 // Writeable
+  }, // EFI_MM_SAVE_STATE_REGISTER_R11 = 33
+
+  {
+    0,                                   // Width32
+    8,                                   // Width64
+    0,                                   // Offset32
+    MM_CPU_OFFSET (x64._R12),            // Offset64Lo
+    MM_CPU_OFFSET (x64._R12) + 4,        // Offset64Hi
+    TRUE                                 // Writeable
+  }, // EFI_MM_SAVE_STATE_REGISTER_R12 = 34
+
+  {
+    0,                                   // Width32
+    8,                                   // Width64
+    0,                                   // Offset32
+    MM_CPU_OFFSET (x64._R13),            // Offset64Lo
+    MM_CPU_OFFSET (x64._R13) + 4,        // Offset64Hi
+    TRUE                                 // Writeable
+  }, // EFI_MM_SAVE_STATE_REGISTER_R13 = 35
+
+  {
+    0,                                   // Width32
+    8,                                   // Width64
+    0,                                   // Offset32
+    MM_CPU_OFFSET (x64._R14),            // Offset64Lo
+    MM_CPU_OFFSET (x64._R14) + 4,        // Offset64Hi
+    TRUE                                 // Writeable
+  }, // EFI_MM_SAVE_STATE_REGISTER_R14 = 36
+
+  {
+    0,                                   // Width32
+    8,                                   // Width64
+    0,                                   // Offset32
+    MM_CPU_OFFSET (x64._R15),            // Offset64Lo
+    MM_CPU_OFFSET (x64._R15) + 4,        // Offset64Hi
+    TRUE                                 // Writeable
+  }, // EFI_MM_SAVE_STATE_REGISTER_R15 = 37
+
+  {
+    4,                                   // Width32
+    8,                                   // Width64
+    MM_CPU_OFFSET (x86._EAX),            // Offset32
+    MM_CPU_OFFSET (x64._RAX),            // Offset64Lo
+    MM_CPU_OFFSET (x64._RAX) + 4,        // Offset64Hi
+    TRUE                                 // Writeable
+  }, // EFI_MM_SAVE_STATE_REGISTER_RAX = 38
+
+  {
+    4,                                   // Width32
+    8,                                   // Width64
+    MM_CPU_OFFSET (x86._EBX),            // Offset32
+    MM_CPU_OFFSET (x64._RBX),            // Offset64Lo
+    MM_CPU_OFFSET (x64._RBX) + 4,        // Offset64Hi
+    TRUE                                 // Writeable
+  }, // EFI_MM_SAVE_STATE_REGISTER_RBX = 39
+
+  {
+    4,                                   // Width32
+    8,                                   // Width64
+    MM_CPU_OFFSET (x86._ECX),            // Offset32
+    MM_CPU_OFFSET (x64._RCX),            // Offset64Lo
+    MM_CPU_OFFSET (x64._RCX) + 4,        // Offset64Hi
+    TRUE                                 // Writeable
+  }, // EFI_MM_SAVE_STATE_REGISTER_RCX = 40
+
+  {
+    4,                                   // Width32
+    8,                                   // Width64
+    MM_CPU_OFFSET (x86._EDX),            // Offset32
+    MM_CPU_OFFSET (x64._RDX),            // Offset64Lo
+    MM_CPU_OFFSET (x64._RDX) + 4,        // Offset64Hi
+    TRUE                                 // Writeable
+  }, // EFI_MM_SAVE_STATE_REGISTER_RDX = 41
+
+  {
+    4,                                   // Width32
+    8,                                   // Width64
+    MM_CPU_OFFSET (x86._ESP),            // Offset32
+    MM_CPU_OFFSET (x64._RSP),            // Offset64Lo
+    MM_CPU_OFFSET (x64._RSP) + 4,        // Offset64Hi
+    TRUE                                 // Writeable
+  }, // EFI_MM_SAVE_STATE_REGISTER_RSP = 42
+
+  {
+    4,                                   // Width32
+    8,                                   // Width64
+    MM_CPU_OFFSET (x86._EBP),            // Offset32
+    MM_CPU_OFFSET (x64._RBP),            // Offset64Lo
+    MM_CPU_OFFSET (x64._RBP) + 4,        // Offset64Hi
+    TRUE                                 // Writeable
+  }, // EFI_MM_SAVE_STATE_REGISTER_RBP = 43
+
+  {
+    4,                                   // Width32
+    8,                                   // Width64
+    MM_CPU_OFFSET (x86._ESI),            // Offset32
+    MM_CPU_OFFSET (x64._RSI),            // Offset64Lo
+    MM_CPU_OFFSET (x64._RSI) + 4,        // Offset64Hi
+    TRUE                                 // Writeable
+  }, // EFI_MM_SAVE_STATE_REGISTER_RSI = 44
+
+  {
+    4,                                   // Width32
+    8,                                   // Width64
+    MM_CPU_OFFSET (x86._EDI),            // Offset32
+    MM_CPU_OFFSET (x64._RDI),            // Offset64Lo
+    MM_CPU_OFFSET (x64._RDI) + 4,        // Offset64Hi
+    TRUE                                 // Writeable
+  }, // EFI_MM_SAVE_STATE_REGISTER_RDI = 45
+
+  {
+    4,                                   // Width32
+    8,                                   // Width64
+    MM_CPU_OFFSET (x86._EIP),            // Offset32
+    MM_CPU_OFFSET (x64._RIP),            // Offset64Lo
+    MM_CPU_OFFSET (x64._RIP) + 4,        // Offset64Hi
+    TRUE                                 // Writeable
+  }, // EFI_MM_SAVE_STATE_REGISTER_RIP = 46
+
+  {
+    4,                                   // Width32
+    8,                                   // Width64
+    MM_CPU_OFFSET (x86._EFLAGS),         // Offset32
+    MM_CPU_OFFSET (x64._RFLAGS),         // Offset64Lo
+    MM_CPU_OFFSET (x64._RFLAGS) + 4,     // Offset64Hi
+    TRUE                                 // Writeable
+  }, // EFI_MM_SAVE_STATE_REGISTER_RFLAGS = 51
+
+  {
+    4,                                   // Width32
+    8,                                   // Width64
+    MM_CPU_OFFSET (x86._CR0),            // Offset32
+    MM_CPU_OFFSET (x64._CR0),            // Offset64Lo
+    MM_CPU_OFFSET (x64._CR0) + 4,        // Offset64Hi
+    FALSE                                // Writeable
+  }, // EFI_MM_SAVE_STATE_REGISTER_CR0 = 52
+
+  {
+    4,                                   // Width32
+    8,                                   // Width64
+    MM_CPU_OFFSET (x86._CR3),            // Offset32
+    MM_CPU_OFFSET (x64._CR3),            // Offset64Lo
+    MM_CPU_OFFSET (x64._CR3) + 4,        // Offset64Hi
+    FALSE                                // Writeable
+  }, // EFI_MM_SAVE_STATE_REGISTER_CR3 = 53
+
+  {
+    0,                                   // Width32
+    4,                                   // Width64
+    0,                                   // Offset32
+    MM_CPU_OFFSET (x64._CR4),            // Offset64Lo
+    MM_CPU_OFFSET (x64._CR4) + 4,        // Offset64Hi
+    FALSE                                // Writeable
+  }, // EFI_MM_SAVE_STATE_REGISTER_CR4 = 54
+};
+
+/**
+  Read a save state register on the target processor.  If this function
+  returns EFI_UNSUPPORTED, then the caller is responsible for reading the
+  MM Save State register.
+
+  @param[in]  CpuIndex  The index of the CPU to read the Save State register.
+                        The value must be between 0 and the NumberOfCpus field in
+                        the System Management System Table (SMST).
+  @param[in]  Register  The MM Save State register to read.
+  @param[in]  Width     The number of bytes to read from the CPU save state.
+  @param[out] Buffer    Upon return, this holds the CPU register value read
+                        from the save state.
+
+  @retval EFI_SUCCESS           The register was read from Save State.
+  @retval EFI_INVALID_PARAMTER  Buffer is NULL.
+  @retval EFI_UNSUPPORTED       This function does not support reading Register.
+  @retval EFI_NOT_FOUND         If desired Register not found.
+**/
+EFI_STATUS
+EFIAPI
+MmSaveStateReadRegister (
+  IN  UINTN                       CpuIndex,
+  IN  EFI_MM_SAVE_STATE_REGISTER  Register,
+  IN  UINTN                       Width,
+  OUT VOID                        *Buffer
+  )
+{
+  UINTN                      RegisterIndex;
+  QEMU_SMRAM_SAVE_STATE_MAP  *CpuSaveState;
+
+  //
+  // Check for special EFI_MM_SAVE_STATE_REGISTER_LMA
+  //
+  if (Register == EFI_MM_SAVE_STATE_REGISTER_LMA) {
+    //
+    // Only byte access is supported for this register
+    //
+    if (Width != 1) {
+      return EFI_INVALID_PARAMETER;
+    }
+
+    CpuSaveState = (QEMU_SMRAM_SAVE_STATE_MAP *)gSmst->CpuSaveState[CpuIndex];
+
+    //
+    // Check CPU mode
+    //
+    if ((CpuSaveState->x86.SMMRevId & 0xFFFF) == 0) {
+      *(UINT8 *)Buffer = 32;
+    } else {
+      *(UINT8 *)Buffer = 64;
+    }
+
+    return EFI_SUCCESS;
+  }
+
+  //
+  // Check for special EFI_MM_SAVE_STATE_REGISTER_IO
+  //
+  if (Register == EFI_MM_SAVE_STATE_REGISTER_IO) {
+    return EFI_NOT_FOUND;
+  }
+
+  //
+  // Convert Register to a register lookup table index.  Let
+  // PiSmmCpuDxeSmm implement other special registers (currently
+  // there is only EFI_MM_SAVE_STATE_REGISTER_PROCESSOR_ID).
+  //
+  RegisterIndex = MmSaveStateGetRegisterIndex (Register);
+  if (RegisterIndex == 0) {
+    return (Register < EFI_MM_SAVE_STATE_REGISTER_IO ?
+            EFI_NOT_FOUND :
+            EFI_UNSUPPORTED);
+  }
+
+  return MmSaveStateReadRegisterByIndex (CpuIndex, RegisterIndex, Width, Buffer);
+}
+
+/**
+  Writes a save state register on the target processor.  If this function
+  returns EFI_UNSUPPORTED, then the caller is responsible for writing the
+  MM save state register.
+
+  @param[in] CpuIndex  The index of the CPU to write the MM Save State.  The
+                       value must be between 0 and the NumberOfCpus field in
+                       the System Management System Table (SMST).
+  @param[in] Register  The MM Save State register to write.
+  @param[in] Width     The number of bytes to write to the CPU save state.
+  @param[in] Buffer    Upon entry, this holds the new CPU register value.
+
+  @retval EFI_SUCCESS           The register was written to Save State.
+  @retval EFI_INVALID_PARAMTER  Buffer is NULL.
+  @retval EFI_UNSUPPORTED       This function does not support writing Register.
+  @retval EFI_NOT_FOUND         If desired Register not found.
+**/
+EFI_STATUS
+EFIAPI
+MmSaveStateWriteRegister (
+  IN UINTN                       CpuIndex,
+  IN EFI_MM_SAVE_STATE_REGISTER  Register,
+  IN UINTN                       Width,
+  IN CONST VOID                  *Buffer
+  )
+{
+  UINTN                      RegisterIndex;
+  QEMU_SMRAM_SAVE_STATE_MAP  *CpuSaveState;
+
+  //
+  // Writes to EFI_MM_SAVE_STATE_REGISTER_LMA are ignored
+  //
+  if (Register == EFI_MM_SAVE_STATE_REGISTER_LMA) {
+    return EFI_SUCCESS;
+  }
+
+  //
+  // Writes to EFI_MM_SAVE_STATE_REGISTER_IO are not supported
+  //
+  if (Register == EFI_MM_SAVE_STATE_REGISTER_IO) {
+    return EFI_NOT_FOUND;
+  }
+
+  //
+  // Convert Register to a register lookup table index.  Let
+  // PiSmmCpuDxeSmm implement other special registers (currently
+  // there is only EFI_MM_SAVE_STATE_REGISTER_PROCESSOR_ID).
+  //
+  RegisterIndex = MmSaveStateGetRegisterIndex (Register);
+  if (RegisterIndex == 0) {
+    return (Register < EFI_MM_SAVE_STATE_REGISTER_IO ?
+            EFI_NOT_FOUND :
+            EFI_UNSUPPORTED);
+  }
+
+  CpuSaveState = (QEMU_SMRAM_SAVE_STATE_MAP *)gSmst->CpuSaveState[CpuIndex];
+
+  //
+  // Do not write non-writable SaveState, because it will cause exception.
+  //
+  if (!mCpuWidthOffset[RegisterIndex].Writeable) {
+    return EFI_UNSUPPORTED;
+  }
+
+  //
+  // Check CPU mode
+  //
+  if ((CpuSaveState->x86.SMMRevId & 0xFFFF) == 0) {
+    //
+    // If 32-bit mode width is zero, then the specified register can not be
+    // accessed
+    //
+    if (mCpuWidthOffset[RegisterIndex].Width32 == 0) {
+      return EFI_NOT_FOUND;
+    }
+
+    //
+    // If Width is bigger than the 32-bit mode width, then the specified
+    // register can not be accessed
+    //
+    if (Width > mCpuWidthOffset[RegisterIndex].Width32) {
+      return EFI_INVALID_PARAMETER;
+    }
+
+    //
+    // Write SMM State register
+    //
+    ASSERT (CpuSaveState != NULL);
+    CopyMem (
+      (UINT8 *)CpuSaveState + mCpuWidthOffset[RegisterIndex].Offset32,
+      Buffer,
+      Width
+      );
+  } else {
+    //
+    // If 64-bit mode width is zero, then the specified register can not be
+    // accessed
+    //
+    if (mCpuWidthOffset[RegisterIndex].Width64 == 0) {
+      return EFI_NOT_FOUND;
+    }
+
+    //
+    // If Width is bigger than the 64-bit mode width, then the specified
+    // register can not be accessed
+    //
+    if (Width > mCpuWidthOffset[RegisterIndex].Width64) {
+      return EFI_INVALID_PARAMETER;
+    }
+
+    //
+    // Write lower 32-bits of SMM State register
+    //
+    CopyMem (
+      (UINT8 *)CpuSaveState + mCpuWidthOffset[RegisterIndex].Offset64Lo,
+      Buffer,
+      MIN (4, Width)
+      );
+    if (Width >= 4) {
+      //
+      // Write upper 32-bits of SMM State register
+      //
+      CopyMem (
+        (UINT8 *)CpuSaveState + mCpuWidthOffset[RegisterIndex].Offset64Hi,
+        (UINT8 *)Buffer + 4,
+        Width - 4
+        );
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Returns LMA value of the Processor.
+
+  @param[in]  CpuIndex  Specifies the zero-based index of the CPU save state.
+
+  @retval     UINT8     returns LMA bit value.
+**/
+UINT8
+EFIAPI
+MmSaveStateGetRegisterLma (
+  IN UINTN  CpuIndex
+  )
+{
+  QEMU_SMRAM_SAVE_STATE_MAP  *CpuSaveState;
+
+  CpuSaveState = (QEMU_SMRAM_SAVE_STATE_MAP *)gSmst->CpuSaveState[CpuIndex];
+
+  if ((CpuSaveState->x86.SMMRevId & 0xFFFF) == 0) {
+    return EFI_MM_SAVE_STATE_REGISTER_LMA_32BIT;
+  }
+
+  return EFI_MM_SAVE_STATE_REGISTER_LMA_64BIT;
+}
diff --git a/UefiCpuPkg/UefiCpuPkg.ci.yaml b/UefiCpuPkg/UefiCpuPkg.ci.yaml
index c2280aedf5ce..b7b7a65ac352 100644
--- a/UefiCpuPkg/UefiCpuPkg.ci.yaml
+++ b/UefiCpuPkg/UefiCpuPkg.ci.yaml
@@ -44,6 +44,7 @@
         "AcceptableDependencies": [
             "MdePkg/MdePkg.dec",
             "MdeModulePkg/MdeModulePkg.dec",
+            "OvmfPkg/OvmfPkg.dec",
             "UefiCpuPkg/UefiCpuPkg.dec"
         ],
         # For host based unit tests
-- 
2.25.1



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#103629): https://edk2.groups.io/g/devel/message/103629
Mute This Topic: https://groups.io/mt/98510092/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-
Re: [edk2-devel] [PATCH v9 7/9] UefiCpuPkg: Implements MmSaveStateLib for Ovmf
Posted by Gerd Hoffmann 2 years, 9 months ago
On Wed, Apr 26, 2023 at 12:52:25PM +0530, Abdul Lateef Attar wrote:
> From: Abdul Lateef Attar <AbdulLateef.Attar@amd.com>
> 
> BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4182
> 
> Implements MmSaveStateLib library interfaces
> to read and write save state
> registers for Ovmf/Qemu.

You can drop this patch and use the AMD version.

Additionally QemuSmramSaveStateMap.h can be removed and likewise
the AMD version used.  See patch below.  Feel free to include it
in your patch series.

take care,
  Gerd

----------------------- cut here ---------------------
From fbc0c8000588b6f7104de1007242177448b38141 Mon Sep 17 00:00:00 2001
From: Gerd Hoffmann <kraxel@redhat.com>
Date: Wed, 26 Apr 2023 11:38:41 +0200
Subject: [PATCH 1/1] [testing] drop QemuSmramSaveStateMap.h, use
 Amd/SmramSaveStateMap.h instead

---
 .../Include/Register/QemuSmramSaveStateMap.h  | 178 ------------------
 .../PeiDxeMemEncryptSevLibInternal.c          |   4 +-
 .../SmmCpuFeaturesLib/SmmCpuFeaturesLib.c     |  21 +--
 3 files changed, 12 insertions(+), 191 deletions(-)
 delete mode 100644 OvmfPkg/Include/Register/QemuSmramSaveStateMap.h

diff --git a/OvmfPkg/Include/Register/QemuSmramSaveStateMap.h b/OvmfPkg/Include/Register/QemuSmramSaveStateMap.h
deleted file mode 100644
index 8ffde0548c4c..000000000000
--- a/OvmfPkg/Include/Register/QemuSmramSaveStateMap.h
+++ /dev/null
@@ -1,178 +0,0 @@
-/** @file
-SMRAM Save State Map Definitions.
-
-SMRAM Save State Map definitions based on contents of the
-Intel(R) 64 and IA-32 Architectures Software Developer's Manual
-  Volume 3C, Section 34.4 SMRAM
-  Volume 3C, Section 34.5 SMI Handler Execution Environment
-  Volume 3C, Section 34.7 Managing Synchronous and Asynchronous SMIs
-
-and the AMD64 Architecture Programmer's Manual
-  Volume 2, Section 10.2 SMM Resources
-
-Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
-Copyright (c) 2015, Red Hat, Inc.<BR>
-SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#ifndef __QEMU_SMRAM_SAVE_STATE_MAP_H__
-#define __QEMU_SMRAM_SAVE_STATE_MAP_H__
-
-#pragma pack (1)
-
-///
-/// 32-bit SMRAM Save State Map
-///
-typedef struct {
-  UINT8     Reserved0[0x200]; // 7c00h
-  UINT8     Reserved1[0xf8];  // 7e00h
-  UINT32    SMBASE;           // 7ef8h
-  UINT32    SMMRevId;         // 7efch
-  UINT16    IORestart;        // 7f00h
-  UINT16    AutoHALTRestart;  // 7f02h
-  UINT8     Reserved2[0x9C];  // 7f08h
-  UINT32    IOMemAddr;        // 7fa0h
-  UINT32    IOMisc;           // 7fa4h
-  UINT32    _ES;              // 7fa8h
-  UINT32    _CS;              // 7fach
-  UINT32    _SS;              // 7fb0h
-  UINT32    _DS;              // 7fb4h
-  UINT32    _FS;              // 7fb8h
-  UINT32    _GS;              // 7fbch
-  UINT32    Reserved3;        // 7fc0h
-  UINT32    _TR;              // 7fc4h
-  UINT32    _DR7;             // 7fc8h
-  UINT32    _DR6;             // 7fcch
-  UINT32    _EAX;             // 7fd0h
-  UINT32    _ECX;             // 7fd4h
-  UINT32    _EDX;             // 7fd8h
-  UINT32    _EBX;             // 7fdch
-  UINT32    _ESP;             // 7fe0h
-  UINT32    _EBP;             // 7fe4h
-  UINT32    _ESI;             // 7fe8h
-  UINT32    _EDI;             // 7fech
-  UINT32    _EIP;             // 7ff0h
-  UINT32    _EFLAGS;          // 7ff4h
-  UINT32    _CR3;             // 7ff8h
-  UINT32    _CR0;             // 7ffch
-} QEMU_SMRAM_SAVE_STATE_MAP32;
-
-///
-/// 64-bit SMRAM Save State Map
-///
-typedef struct {
-  UINT8     Reserved0[0x200]; // 7c00h
-
-  UINT16    _ES;             // 7e00h
-  UINT16    _ESAccessRights; // 7e02h
-  UINT32    _ESLimit;        // 7e04h
-  UINT64    _ESBase;         // 7e08h
-
-  UINT16    _CS;             // 7e10h
-  UINT16    _CSAccessRights; // 7e12h
-  UINT32    _CSLimit;        // 7e14h
-  UINT64    _CSBase;         // 7e18h
-
-  UINT16    _SS;             // 7e20h
-  UINT16    _SSAccessRights; // 7e22h
-  UINT32    _SSLimit;        // 7e24h
-  UINT64    _SSBase;         // 7e28h
-
-  UINT16    _DS;             // 7e30h
-  UINT16    _DSAccessRights; // 7e32h
-  UINT32    _DSLimit;        // 7e34h
-  UINT64    _DSBase;         // 7e38h
-
-  UINT16    _FS;             // 7e40h
-  UINT16    _FSAccessRights; // 7e42h
-  UINT32    _FSLimit;        // 7e44h
-  UINT64    _FSBase;         // 7e48h
-
-  UINT16    _GS;             // 7e50h
-  UINT16    _GSAccessRights; // 7e52h
-  UINT32    _GSLimit;        // 7e54h
-  UINT64    _GSBase;         // 7e58h
-
-  UINT32    _GDTRReserved1;  // 7e60h
-  UINT16    _GDTRLimit;      // 7e64h
-  UINT16    _GDTRReserved2;  // 7e66h
-  UINT64    _GDTRBase;       // 7e68h
-
-  UINT16    _LDTR;             // 7e70h
-  UINT16    _LDTRAccessRights; // 7e72h
-  UINT32    _LDTRLimit;        // 7e74h
-  UINT64    _LDTRBase;         // 7e78h
-
-  UINT32    _IDTRReserved1;  // 7e80h
-  UINT16    _IDTRLimit;      // 7e84h
-  UINT16    _IDTRReserved2;  // 7e86h
-  UINT64    _IDTRBase;       // 7e88h
-
-  UINT16    _TR;             // 7e90h
-  UINT16    _TRAccessRights; // 7e92h
-  UINT32    _TRLimit;        // 7e94h
-  UINT64    _TRBase;         // 7e98h
-
-  UINT64    IO_RIP;          // 7ea0h
-  UINT64    IO_RCX;          // 7ea8h
-  UINT64    IO_RSI;          // 7eb0h
-  UINT64    IO_RDI;          // 7eb8h
-  UINT32    IO_DWord;        // 7ec0h
-  UINT8     Reserved1[0x04]; // 7ec4h
-  UINT8     IORestart;       // 7ec8h
-  UINT8     AutoHALTRestart; // 7ec9h
-  UINT8     Reserved2[0x06]; // 7ecah
-
-  UINT64    IA32_EFER;       // 7ed0h
-  UINT64    SVM_Guest;       // 7ed8h
-  UINT64    SVM_GuestVMCB;   // 7ee0h
-  UINT64    SVM_GuestVIntr;  // 7ee8h
-  UINT8     Reserved3[0x0c]; // 7ef0h
-
-  UINT32    SMMRevId;        // 7efch
-  UINT32    SMBASE;          // 7f00h
-
-  UINT8     Reserved4[0x1c];   // 7f04h
-  UINT64    SVM_GuestPAT;      // 7f20h
-  UINT64    SVM_HostIA32_EFER; // 7f28h
-  UINT64    SVM_HostCR4;       // 7f30h
-  UINT64    SVM_HostCR3;       // 7f38h
-  UINT64    SVM_HostCR0;       // 7f40h
-
-  UINT64    _CR4;            // 7f48h
-  UINT64    _CR3;            // 7f50h
-  UINT64    _CR0;            // 7f58h
-  UINT64    _DR7;            // 7f60h
-  UINT64    _DR6;            // 7f68h
-  UINT64    _RFLAGS;         // 7f70h
-  UINT64    _RIP;            // 7f78h
-  UINT64    _R15;            // 7f80h
-  UINT64    _R14;            // 7f88h
-  UINT64    _R13;            // 7f90h
-  UINT64    _R12;            // 7f98h
-  UINT64    _R11;            // 7fa0h
-  UINT64    _R10;            // 7fa8h
-  UINT64    _R9;             // 7fb0h
-  UINT64    _R8;             // 7fb8h
-  UINT64    _RDI;            // 7fc0h
-  UINT64    _RSI;            // 7fc8h
-  UINT64    _RBP;            // 7fd0h
-  UINT64    _RSP;            // 7fd8h
-  UINT64    _RBX;            // 7fe0h
-  UINT64    _RDX;            // 7fe8h
-  UINT64    _RCX;            // 7ff0h
-  UINT64    _RAX;            // 7ff8h
-} QEMU_SMRAM_SAVE_STATE_MAP64;
-
-///
-/// Union of 32-bit and 64-bit SMRAM Save State Maps
-///
-typedef union  {
-  QEMU_SMRAM_SAVE_STATE_MAP32    x86;
-  QEMU_SMRAM_SAVE_STATE_MAP64    x64;
-} QEMU_SMRAM_SAVE_STATE_MAP;
-
-#pragma pack ()
-
-#endif
diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/PeiDxeMemEncryptSevLibInternal.c b/OvmfPkg/Library/BaseMemEncryptSevLib/PeiDxeMemEncryptSevLibInternal.c
index 78ea16ae06ff..43a2a3e3b7e3 100644
--- a/OvmfPkg/Library/BaseMemEncryptSevLib/PeiDxeMemEncryptSevLibInternal.c
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/PeiDxeMemEncryptSevLibInternal.c
@@ -12,7 +12,7 @@
 #include <Library/DebugLib.h>
 #include <Library/MemEncryptSevLib.h>
 #include <Library/PcdLib.h>
-#include <Register/QemuSmramSaveStateMap.h>
+#include <Register/Amd/SmramSaveStateMap.h>
 #include <Register/SmramSaveStateMap.h>
 #include <Uefi/UefiBaseType.h>
 
@@ -49,7 +49,7 @@ MemEncryptSevLocateInitialSmramSaveStateMapPages (
   }
 
   MapStart      = SMM_DEFAULT_SMBASE + SMRAM_SAVE_STATE_MAP_OFFSET;
-  MapEnd        = MapStart + sizeof (QEMU_SMRAM_SAVE_STATE_MAP);
+  MapEnd        = MapStart + sizeof (AMD_SMRAM_SAVE_STATE_MAP);
   MapPagesStart = MapStart & ~(UINTN)EFI_PAGE_MASK;
   MapPagesEnd   = ALIGN_VALUE (MapEnd, EFI_PAGE_SIZE);
   MapPagesSize  = MapPagesEnd - MapPagesStart;
diff --git a/OvmfPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.c b/OvmfPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.c
index 4c354bafe42f..63822b126e3d 100644
--- a/OvmfPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.c
+++ b/OvmfPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.c
@@ -20,8 +20,7 @@
 #include <Library/HobLib.h>
 #include <Pcd/CpuHotEjectData.h>
 #include <PiSmm.h>
-#include <Register/Intel/SmramSaveStateMap.h>
-#include <Register/QemuSmramSaveStateMap.h>
+#include <Register/Amd/SmramSaveStateMap.h>
 #include <Guid/SmmBaseHob.h>
 
 //
@@ -90,15 +89,15 @@ SmmCpuFeaturesInitializeProcessor (
   IN CPU_HOT_PLUG_DATA          *CpuHotPlugData
   )
 {
-  QEMU_SMRAM_SAVE_STATE_MAP  *CpuState;
+  AMD_SMRAM_SAVE_STATE_MAP  *CpuState;
 
   //
   // Configure SMBASE.
   //
-  CpuState = (QEMU_SMRAM_SAVE_STATE_MAP *)(UINTN)(
-                                                  SMM_DEFAULT_SMBASE +
-                                                  SMRAM_SAVE_STATE_MAP_OFFSET
-                                                  );
+  CpuState = (AMD_SMRAM_SAVE_STATE_MAP *)(UINTN)(
+                                                 SMM_DEFAULT_SMBASE +
+                                                 SMRAM_SAVE_STATE_MAP_OFFSET
+                                                 );
   if ((CpuState->x86.SMMRevId & 0xFFFF) == 0) {
     CpuState->x86.SMBASE = (UINT32)CpuHotPlugData->SmBase[CpuIndex];
   } else {
@@ -150,10 +149,10 @@ SmmCpuFeaturesHookReturnFromSmm (
   IN UINT64                NewInstructionPointer
   )
 {
-  UINT64                     OriginalInstructionPointer;
-  QEMU_SMRAM_SAVE_STATE_MAP  *CpuSaveState;
+  UINT64                    OriginalInstructionPointer;
+  AMD_SMRAM_SAVE_STATE_MAP  *CpuSaveState;
 
-  CpuSaveState = (QEMU_SMRAM_SAVE_STATE_MAP *)CpuState;
+  CpuSaveState = (AMD_SMRAM_SAVE_STATE_MAP *)CpuState;
   if ((CpuSaveState->x86.SMMRevId & 0xFFFF) == 0) {
     OriginalInstructionPointer = (UINT64)CpuSaveState->x86._EIP;
     CpuSaveState->x86._EIP     = (UINT32)NewInstructionPointer;
@@ -166,7 +165,7 @@ SmmCpuFeaturesHookReturnFromSmm (
     }
   } else {
     OriginalInstructionPointer = CpuSaveState->x64._RIP;
-    if ((CpuSaveState->x64.IA32_EFER & LMA) == 0) {
+    if ((CpuSaveState->x64.EFER & LMA) == 0) {
       CpuSaveState->x64._RIP = (UINT32)NewInstructionPointer32;
     } else {
       CpuSaveState->x64._RIP = (UINT32)NewInstructionPointer;
-- 
2.40.0



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#103642): https://edk2.groups.io/g/devel/message/103642
Mute This Topic: https://groups.io/mt/98510092/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-