public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: "Brijesh Singh" <brijesh.singh@amd.com>
To: <devel@edk2.groups.io>
Cc: James Bottomley <jejb@linux.ibm.com>, Min Xu <min.m.xu@intel.com>,
	"Jiewen Yao" <jiewen.yao@intel.com>,
	Tom Lendacky <thomas.lendacky@amd.com>,
	"Jordan Justen" <jordan.l.justen@intel.com>,
	Ard Biesheuvel <ardb+tianocore@kernel.org>,
	Erdem Aktas <erdemaktas@google.com>,
	"Michael Roth" <Michael.Roth@amd.com>,
	Gerd Hoffmann <kraxel@redhat.com>,
	"Michael D Kinney" <michael.d.kinney@intel.com>,
	Liming Gao <gaoliming@byosoft.com.cn>,
	Zhiguang Liu <zhiguang.liu@intel.com>, Ray Ni <ray.ni@intel.com>,
	Rahul Kumar <rahul1.kumar@intel.com>,
	Eric Dong <eric.dong@intel.com>,
	Brijesh Singh <brijesh.singh@amd.com>,
	Michael Roth <michael.roth@amd.com>,
	Jiewen Yao <Jiewen.yao@intel.com>
Subject: [PATCH v14 02/32] UefiCpuPkg/MpInitLib: move SEV specific routines in AmdSev.c
Date: Wed, 8 Dec 2021 21:27:30 -0600	[thread overview]
Message-ID: <20211209032800.3802995-3-brijesh.singh@amd.com> (raw)
In-Reply-To: <20211209032800.3802995-1-brijesh.singh@amd.com>

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

Move all the SEV specific function in AmdSev.c.

No functional change intended.

Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Cc: Michael Roth <michael.roth@amd.com>
Cc: James Bottomley <jejb@linux.ibm.com>
Cc: Min Xu <min.m.xu@intel.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Erdem Aktas <erdemaktas@google.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
Suggested-by: Jiewen Yao <Jiewen.yao@intel.com>
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
---
 UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf |   1 +
 UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf |   1 +
 UefiCpuPkg/Library/MpInitLib/MpLib.h          |  37 ++-
 UefiCpuPkg/Library/MpInitLib/AmdSev.c         | 245 ++++++++++++++++++
 UefiCpuPkg/Library/MpInitLib/MpLib.c          | 224 +---------------
 UefiCpuPkg/Library/MpInitLib/X64/AmdSev.nasm  | 119 +++++++++
 UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm | 100 ++-----
 7 files changed, 421 insertions(+), 306 deletions(-)
 create mode 100644 UefiCpuPkg/Library/MpInitLib/AmdSev.c
 create mode 100644 UefiCpuPkg/Library/MpInitLib/X64/AmdSev.nasm

diff --git a/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf b/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
index d34419c2a524..6e510aa89120 100644
--- a/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
+++ b/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
@@ -28,6 +28,7 @@ [Sources.X64]
   X64/MpFuncs.nasm
 
 [Sources.common]
+  AmdSev.c
   MpEqu.inc
   DxeMpLib.c
   MpLib.c
diff --git a/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf b/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
index 36fcb96b5852..2cbd9b8b8acc 100644
--- a/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
+++ b/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
@@ -28,6 +28,7 @@ [Sources.X64]
   X64/MpFuncs.nasm
 
 [Sources.common]
+  AmdSev.c
   MpEqu.inc
   PeiMpLib.c
   MpLib.c
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.h b/UefiCpuPkg/Library/MpInitLib/MpLib.h
index a647772088d9..16b4d76d019b 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.h
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.h
@@ -34,6 +34,9 @@
 #include <Library/PcdLib.h>
 #include <Library/MicrocodeLib.h>
 
+#include <Register/Amd/Fam17Msr.h>
+#include <Register/Amd/Ghcb.h>
+
 #include <Guid/MicrocodePatchHob.h>
 
 #define WAKEUP_AP_SIGNAL  SIGNATURE_32 ('S', 'T', 'A', 'P')
@@ -321,7 +324,7 @@ typedef struct {
                            from long mode to real mode.
 **/
 typedef
-VOID
+  VOID
 (EFIAPI AP_RESET)(
   IN UINTN    BufferStart,
   IN UINT16   Code16,
@@ -346,7 +349,7 @@ extern EFI_GUID  mCpuInitMpLibHobGuid;
   @param[in] PmCodeSegment   Protected mode code segment value.
 **/
 typedef
-VOID
+  VOID
 (EFIAPI *ASM_RELOCATE_AP_LOOP)(
   IN BOOLEAN                 MwaitSupport,
   IN UINTN                   ApTargetCState,
@@ -740,4 +743,34 @@ PlatformShadowMicrocode (
   IN OUT CPU_MP_DATA  *CpuMpData
   );
 
+/**
+  Allocate the SEV-ES AP jump table buffer.
+
+  @param[in, out]  CpuMpData  The pointer to CPU MP Data structure.
+**/
+VOID
+AllocateSevEsAPMemory (
+  IN OUT CPU_MP_DATA  *CpuMpData
+  );
+
+/**
+  Program the SEV-ES AP jump table buffer.
+
+  @param[in]  SipiVector  The SIPI vector used for the AP Reset
+**/
+VOID
+SetSevEsJumpTable (
+  IN UINTN  SipiVector
+  );
+
+/**
+  The function puts the AP in halt loop.
+
+  @param[in]  CpuMpData  The pointer to CPU MP Data structure.
+**/
+VOID
+SevEsPlaceApHlt (
+  CPU_MP_DATA  *CpuMpData
+  );
+
 #endif
diff --git a/UefiCpuPkg/Library/MpInitLib/AmdSev.c b/UefiCpuPkg/Library/MpInitLib/AmdSev.c
new file mode 100644
index 000000000000..0e3c6e231077
--- /dev/null
+++ b/UefiCpuPkg/Library/MpInitLib/AmdSev.c
@@ -0,0 +1,245 @@
+/** @file
+  CPU MP Initialize helper function for AMD SEV.
+
+  Copyright (c) 2021, AMD Inc. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "MpLib.h"
+#include <Library/VmgExitLib.h>
+
+/**
+  Get Protected mode code segment with 16-bit default addressing
+  from current GDT table.
+
+  @return  Protected mode 16-bit code segment value.
+**/
+STATIC
+UINT16
+GetProtectedMode16CS (
+  VOID
+  )
+{
+  IA32_DESCRIPTOR          GdtrDesc;
+  IA32_SEGMENT_DESCRIPTOR  *GdtEntry;
+  UINTN                    GdtEntryCount;
+  UINT16                   Index;
+
+  Index = (UINT16)-1;
+  AsmReadGdtr (&GdtrDesc);
+  GdtEntryCount = (GdtrDesc.Limit + 1) / sizeof (IA32_SEGMENT_DESCRIPTOR);
+  GdtEntry      = (IA32_SEGMENT_DESCRIPTOR *)GdtrDesc.Base;
+  for (Index = 0; Index < GdtEntryCount; Index++) {
+    if ((GdtEntry->Bits.L == 0) &&
+        (GdtEntry->Bits.DB == 0) &&
+        (GdtEntry->Bits.Type > 8))
+    {
+      break;
+    }
+
+    GdtEntry++;
+  }
+
+  ASSERT (Index != GdtEntryCount);
+  return Index * 8;
+}
+
+/**
+  Get Protected mode code segment with 32-bit default addressing
+  from current GDT table.
+
+  @return  Protected mode 32-bit code segment value.
+**/
+STATIC
+UINT16
+GetProtectedMode32CS (
+  VOID
+  )
+{
+  IA32_DESCRIPTOR          GdtrDesc;
+  IA32_SEGMENT_DESCRIPTOR  *GdtEntry;
+  UINTN                    GdtEntryCount;
+  UINT16                   Index;
+
+  Index = (UINT16)-1;
+  AsmReadGdtr (&GdtrDesc);
+  GdtEntryCount = (GdtrDesc.Limit + 1) / sizeof (IA32_SEGMENT_DESCRIPTOR);
+  GdtEntry      = (IA32_SEGMENT_DESCRIPTOR *)GdtrDesc.Base;
+  for (Index = 0; Index < GdtEntryCount; Index++) {
+    if ((GdtEntry->Bits.L == 0) &&
+        (GdtEntry->Bits.DB == 1) &&
+        (GdtEntry->Bits.Type > 8))
+    {
+      break;
+    }
+
+    GdtEntry++;
+  }
+
+  ASSERT (Index != GdtEntryCount);
+  return Index * 8;
+}
+
+/**
+  Reset an AP when in SEV-ES mode.
+
+  If successful, this function never returns.
+
+  @param[in] Ghcb                 Pointer to the GHCB
+  @param[in] CpuMpData            Pointer to CPU MP Data
+
+**/
+VOID
+MpInitLibSevEsAPReset (
+  IN GHCB         *Ghcb,
+  IN CPU_MP_DATA  *CpuMpData
+  )
+{
+  EFI_STATUS  Status;
+  UINTN       ProcessorNumber;
+  UINT16      Code16, Code32;
+  AP_RESET    *APResetFn;
+  UINTN       BufferStart;
+  UINTN       StackStart;
+
+  Status = GetProcessorNumber (CpuMpData, &ProcessorNumber);
+  ASSERT_EFI_ERROR (Status);
+
+  Code16 = GetProtectedMode16CS ();
+  Code32 = GetProtectedMode32CS ();
+
+  if (CpuMpData->WakeupBufferHigh != 0) {
+    APResetFn = (AP_RESET *)(CpuMpData->WakeupBufferHigh + CpuMpData->AddressMap.SwitchToRealNoNxOffset);
+  } else {
+    APResetFn = (AP_RESET *)(CpuMpData->MpCpuExchangeInfo->BufferStart + CpuMpData->AddressMap.SwitchToRealOffset);
+  }
+
+  BufferStart = CpuMpData->MpCpuExchangeInfo->BufferStart;
+  StackStart  = CpuMpData->SevEsAPResetStackStart -
+                (AP_RESET_STACK_SIZE * ProcessorNumber);
+
+  //
+  // This call never returns.
+  //
+  APResetFn (BufferStart, Code16, Code32, StackStart);
+}
+
+/**
+  Allocate the SEV-ES AP jump table buffer.
+
+  @param[in, out]  CpuMpData  The pointer to CPU MP Data structure.
+**/
+VOID
+AllocateSevEsAPMemory (
+  IN OUT CPU_MP_DATA  *CpuMpData
+  )
+{
+  if (CpuMpData->SevEsAPBuffer == (UINTN)-1) {
+    CpuMpData->SevEsAPBuffer =
+      CpuMpData->SevEsIsEnabled ? GetSevEsAPMemory () : 0;
+  }
+}
+
+/**
+  Program the SEV-ES AP jump table buffer.
+
+  @param[in]  SipiVector  The SIPI vector used for the AP Reset
+**/
+VOID
+SetSevEsJumpTable (
+  IN UINTN  SipiVector
+  )
+{
+  SEV_ES_AP_JMP_FAR  *JmpFar;
+  UINT32             Offset, InsnByte;
+  UINT8              LoNib, HiNib;
+
+  JmpFar = (SEV_ES_AP_JMP_FAR *)(UINTN)FixedPcdGet32 (PcdSevEsWorkAreaBase);
+  ASSERT (JmpFar != NULL);
+
+  //
+  // Obtain the address of the Segment/Rip location in the workarea.
+  // This will be set to a value derived from the SIPI vector and will
+  // be the memory address used for the far jump below.
+  //
+  Offset  = FixedPcdGet32 (PcdSevEsWorkAreaBase);
+  Offset += sizeof (JmpFar->InsnBuffer);
+  LoNib   = (UINT8)Offset;
+  HiNib   = (UINT8)(Offset >> 8);
+
+  //
+  // Program the workarea (which is the initial AP boot address) with
+  // far jump to the SIPI vector (where XX and YY represent the
+  // address of where the SIPI vector is stored.
+  //
+  //   JMP FAR [CS:XXYY] => 2E FF 2E YY XX
+  //
+  InsnByte                       = 0;
+  JmpFar->InsnBuffer[InsnByte++] = 0x2E;  // CS override prefix
+  JmpFar->InsnBuffer[InsnByte++] = 0xFF;  // JMP (FAR)
+  JmpFar->InsnBuffer[InsnByte++] = 0x2E;  // ModRM (JMP memory location)
+  JmpFar->InsnBuffer[InsnByte++] = LoNib; // YY offset ...
+  JmpFar->InsnBuffer[InsnByte++] = HiNib; // XX offset ...
+
+  //
+  // Program the Segment/Rip based on the SIPI vector (always at least
+  // 16-byte aligned, so Rip is set to 0).
+  //
+  JmpFar->Rip     = 0;
+  JmpFar->Segment = (UINT16)(SipiVector >> 4);
+}
+
+/**
+  The function puts the AP in halt loop.
+
+  @param[in]  CpuMpData  The pointer to CPU MP Data structure.
+**/
+VOID
+SevEsPlaceApHlt (
+  CPU_MP_DATA  *CpuMpData
+  )
+{
+  MSR_SEV_ES_GHCB_REGISTER  Msr;
+  GHCB                      *Ghcb;
+  UINT64                    Status;
+  BOOLEAN                   DoDecrement;
+  BOOLEAN                   InterruptState;
+
+  DoDecrement = (BOOLEAN)(CpuMpData->InitFlag == ApInitConfig);
+
+  while (TRUE) {
+    Msr.GhcbPhysicalAddress = AsmReadMsr64 (MSR_SEV_ES_GHCB);
+    Ghcb                    = Msr.Ghcb;
+
+    VmgInit (Ghcb, &InterruptState);
+
+    if (DoDecrement) {
+      DoDecrement = FALSE;
+
+      //
+      // Perform the delayed decrement just before issuing the first
+      // VMGEXIT with AP_RESET_HOLD.
+      //
+      InterlockedDecrement ((UINT32 *)&CpuMpData->MpCpuExchangeInfo->NumApsExecuting);
+    }
+
+    Status = VmgExit (Ghcb, SVM_EXIT_AP_RESET_HOLD, 0, 0);
+    if ((Status == 0) && (Ghcb->SaveArea.SwExitInfo2 != 0)) {
+      VmgDone (Ghcb, InterruptState);
+      break;
+    }
+
+    VmgDone (Ghcb, InterruptState);
+  }
+
+  //
+  // Awakened in a new phase? Use the new CpuMpData
+  //
+  if (CpuMpData->NewCpuMpData != NULL) {
+    CpuMpData = CpuMpData->NewCpuMpData;
+  }
+
+  MpInitLibSevEsAPReset (Ghcb, CpuMpData);
+}
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.c b/UefiCpuPkg/Library/MpInitLib/MpLib.c
index 2d8e9512ab98..34555c069331 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.c
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.c
@@ -599,123 +599,6 @@ InitializeApData (
   SetApState (&CpuMpData->CpuData[ProcessorNumber], CpuStateIdle);
 }
 
-/**
-  Get Protected mode code segment with 16-bit default addressing
-  from current GDT table.
-
-  @return  Protected mode 16-bit code segment value.
-**/
-STATIC
-UINT16
-GetProtectedMode16CS (
-  VOID
-  )
-{
-  IA32_DESCRIPTOR          GdtrDesc;
-  IA32_SEGMENT_DESCRIPTOR  *GdtEntry;
-  UINTN                    GdtEntryCount;
-  UINT16                   Index;
-
-  Index = (UINT16)-1;
-  AsmReadGdtr (&GdtrDesc);
-  GdtEntryCount = (GdtrDesc.Limit + 1) / sizeof (IA32_SEGMENT_DESCRIPTOR);
-  GdtEntry      = (IA32_SEGMENT_DESCRIPTOR *)GdtrDesc.Base;
-  for (Index = 0; Index < GdtEntryCount; Index++) {
-    if ((GdtEntry->Bits.L == 0) &&
-        (GdtEntry->Bits.DB == 0) &&
-        (GdtEntry->Bits.Type > 8))
-    {
-      break;
-    }
-
-    GdtEntry++;
-  }
-
-  ASSERT (Index != GdtEntryCount);
-  return Index * 8;
-}
-
-/**
-  Get Protected mode code segment with 32-bit default addressing
-  from current GDT table.
-
-  @return  Protected mode 32-bit code segment value.
-**/
-STATIC
-UINT16
-GetProtectedMode32CS (
-  VOID
-  )
-{
-  IA32_DESCRIPTOR          GdtrDesc;
-  IA32_SEGMENT_DESCRIPTOR  *GdtEntry;
-  UINTN                    GdtEntryCount;
-  UINT16                   Index;
-
-  Index = (UINT16)-1;
-  AsmReadGdtr (&GdtrDesc);
-  GdtEntryCount = (GdtrDesc.Limit + 1) / sizeof (IA32_SEGMENT_DESCRIPTOR);
-  GdtEntry      = (IA32_SEGMENT_DESCRIPTOR *)GdtrDesc.Base;
-  for (Index = 0; Index < GdtEntryCount; Index++) {
-    if ((GdtEntry->Bits.L == 0) &&
-        (GdtEntry->Bits.DB == 1) &&
-        (GdtEntry->Bits.Type > 8))
-    {
-      break;
-    }
-
-    GdtEntry++;
-  }
-
-  ASSERT (Index != GdtEntryCount);
-  return Index * 8;
-}
-
-/**
-  Reset an AP when in SEV-ES mode.
-
-  If successful, this function never returns.
-
-  @param[in] Ghcb                 Pointer to the GHCB
-  @param[in] CpuMpData            Pointer to CPU MP Data
-
-**/
-STATIC
-VOID
-MpInitLibSevEsAPReset (
-  IN GHCB         *Ghcb,
-  IN CPU_MP_DATA  *CpuMpData
-  )
-{
-  EFI_STATUS  Status;
-  UINTN       ProcessorNumber;
-  UINT16      Code16, Code32;
-  AP_RESET    *APResetFn;
-  UINTN       BufferStart;
-  UINTN       StackStart;
-
-  Status = GetProcessorNumber (CpuMpData, &ProcessorNumber);
-  ASSERT_EFI_ERROR (Status);
-
-  Code16 = GetProtectedMode16CS ();
-  Code32 = GetProtectedMode32CS ();
-
-  if (CpuMpData->WakeupBufferHigh != 0) {
-    APResetFn = (AP_RESET *)(CpuMpData->WakeupBufferHigh + CpuMpData->AddressMap.SwitchToRealNoNxOffset);
-  } else {
-    APResetFn = (AP_RESET *)(CpuMpData->MpCpuExchangeInfo->BufferStart + CpuMpData->AddressMap.SwitchToRealOffset);
-  }
-
-  BufferStart = CpuMpData->MpCpuExchangeInfo->BufferStart;
-  StackStart  = CpuMpData->SevEsAPResetStackStart -
-                (AP_RESET_STACK_SIZE * ProcessorNumber);
-
-  //
-  // This call never returns.
-  //
-  APResetFn (BufferStart, Code16, Code32, StackStart);
-}
-
 /**
   This function will be called from AP reset code if BSP uses WakeUpAP.
 
@@ -895,47 +778,7 @@ ApWakeupFunction (
       while (TRUE) {
         DisableInterrupts ();
         if (CpuMpData->SevEsIsEnabled) {
-          MSR_SEV_ES_GHCB_REGISTER  Msr;
-          GHCB                      *Ghcb;
-          UINT64                    Status;
-          BOOLEAN                   DoDecrement;
-          BOOLEAN                   InterruptState;
-
-          DoDecrement = (BOOLEAN)(CpuMpData->InitFlag == ApInitConfig);
-
-          while (TRUE) {
-            Msr.GhcbPhysicalAddress = AsmReadMsr64 (MSR_SEV_ES_GHCB);
-            Ghcb                    = Msr.Ghcb;
-
-            VmgInit (Ghcb, &InterruptState);
-
-            if (DoDecrement) {
-              DoDecrement = FALSE;
-
-              //
-              // Perform the delayed decrement just before issuing the first
-              // VMGEXIT with AP_RESET_HOLD.
-              //
-              InterlockedDecrement ((UINT32 *)&CpuMpData->MpCpuExchangeInfo->NumApsExecuting);
-            }
-
-            Status = VmgExit (Ghcb, SVM_EXIT_AP_RESET_HOLD, 0, 0);
-            if ((Status == 0) && (Ghcb->SaveArea.SwExitInfo2 != 0)) {
-              VmgDone (Ghcb, InterruptState);
-              break;
-            }
-
-            VmgDone (Ghcb, InterruptState);
-          }
-
-          //
-          // Awakened in a new phase? Use the new CpuMpData
-          //
-          if (CpuMpData->NewCpuMpData != NULL) {
-            CpuMpData = CpuMpData->NewCpuMpData;
-          }
-
-          MpInitLibSevEsAPReset (Ghcb, CpuMpData);
+          SevEsPlaceApHlt (CpuMpData);
         } else {
           CpuSleep ();
         }
@@ -1268,71 +1111,6 @@ FreeResetVector (
   }
 }
 
-/**
-  Allocate the SEV-ES AP jump table buffer.
-
-  @param[in, out]  CpuMpData  The pointer to CPU MP Data structure.
-**/
-VOID
-AllocateSevEsAPMemory (
-  IN OUT CPU_MP_DATA  *CpuMpData
-  )
-{
-  if (CpuMpData->SevEsAPBuffer == (UINTN)-1) {
-    CpuMpData->SevEsAPBuffer =
-      CpuMpData->SevEsIsEnabled ? GetSevEsAPMemory () : 0;
-  }
-}
-
-/**
-  Program the SEV-ES AP jump table buffer.
-
-  @param[in]  SipiVector  The SIPI vector used for the AP Reset
-**/
-VOID
-SetSevEsJumpTable (
-  IN UINTN  SipiVector
-  )
-{
-  SEV_ES_AP_JMP_FAR  *JmpFar;
-  UINT32             Offset, InsnByte;
-  UINT8              LoNib, HiNib;
-
-  JmpFar = (SEV_ES_AP_JMP_FAR *)(UINTN)FixedPcdGet32 (PcdSevEsWorkAreaBase);
-  ASSERT (JmpFar != NULL);
-
-  //
-  // Obtain the address of the Segment/Rip location in the workarea.
-  // This will be set to a value derived from the SIPI vector and will
-  // be the memory address used for the far jump below.
-  //
-  Offset  = FixedPcdGet32 (PcdSevEsWorkAreaBase);
-  Offset += sizeof (JmpFar->InsnBuffer);
-  LoNib   = (UINT8)Offset;
-  HiNib   = (UINT8)(Offset >> 8);
-
-  //
-  // Program the workarea (which is the initial AP boot address) with
-  // far jump to the SIPI vector (where XX and YY represent the
-  // address of where the SIPI vector is stored.
-  //
-  //   JMP FAR [CS:XXYY] => 2E FF 2E YY XX
-  //
-  InsnByte                       = 0;
-  JmpFar->InsnBuffer[InsnByte++] = 0x2E;  // CS override prefix
-  JmpFar->InsnBuffer[InsnByte++] = 0xFF;  // JMP (FAR)
-  JmpFar->InsnBuffer[InsnByte++] = 0x2E;  // ModRM (JMP memory location)
-  JmpFar->InsnBuffer[InsnByte++] = LoNib; // YY offset ...
-  JmpFar->InsnBuffer[InsnByte++] = HiNib; // XX offset ...
-
-  //
-  // Program the Segment/Rip based on the SIPI vector (always at least
-  // 16-byte aligned, so Rip is set to 0).
-  //
-  JmpFar->Rip     = 0;
-  JmpFar->Segment = (UINT16)(SipiVector >> 4);
-}
-
 /**
   This function will be called by BSP to wakeup AP.
 
diff --git a/UefiCpuPkg/Library/MpInitLib/X64/AmdSev.nasm b/UefiCpuPkg/Library/MpInitLib/X64/AmdSev.nasm
new file mode 100644
index 000000000000..0ccafe25eca4
--- /dev/null
+++ b/UefiCpuPkg/Library/MpInitLib/X64/AmdSev.nasm
@@ -0,0 +1,119 @@
+;------------------------------------------------------------------------------ ;
+; Copyright (c) 2021, AMD Inc. All rights reserved.<BR>
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+; Module Name:
+;
+;   AmdSev.nasm
+;
+; Abstract:
+;
+;   This provides helper used by the MpFunc.nasm. If AMD SEV-ES is active
+;   then helpers perform the additional setups (such as GHCB).
+;
+;-------------------------------------------------------------------------------
+
+%define SIZE_4KB    0x1000
+
+;
+; The function checks whether SEV-ES is enabled, if enabled
+; then setup the GHCB page.
+;
+SevEsSetupGhcb:
+    lea        edi, [esi + MP_CPU_EXCHANGE_INFO_FIELD (SevEsIsEnabled)]
+    cmp        byte [edi], 1        ; SevEsIsEnabled
+    jne        SevEsSetupGhcbExit
+
+    ;
+    ; program GHCB
+    ;   Each page after the GHCB is a per-CPU page, so the calculation programs
+    ;   a GHCB to be every 8KB.
+    ;
+    mov        eax, SIZE_4KB
+    shl        eax, 1                            ; EAX = SIZE_4K * 2
+    mov        ecx, ebx
+    mul        ecx                               ; EAX = SIZE_4K * 2 * CpuNumber
+    mov        edi, esi
+    add        edi, MP_CPU_EXCHANGE_INFO_FIELD (GhcbBase)
+    add        rax, qword [edi]
+    mov        rdx, rax
+    shr        rdx, 32
+    mov        rcx, 0xc0010130
+    wrmsr
+
+SevEsSetupGhcbExit:
+    OneTimeCallRet    SevEsSetupGhcb
+
+;
+; The function checks whether SEV-ES is enabled, if enabled, use
+; the GHCB
+;
+SevEsGetApicId:
+    lea        edi, [esi + MP_CPU_EXCHANGE_INFO_FIELD (SevEsIsEnabled)]
+    cmp        byte [edi], 1        ; SevEsIsEnabled
+    jne        SevEsGetApicIdExit
+
+    ;
+    ; Since we don't have a stack yet, we can't take a #VC
+    ; exception. Use the GHCB protocol to perform the CPUID
+    ; calls.
+    ;
+    mov        rcx, 0xc0010130
+    rdmsr
+    shl        rdx, 32
+    or         rax, rdx
+    mov        rdi, rax             ; RDI now holds the original GHCB GPA
+
+    mov        rdx, 0               ; CPUID function 0
+    mov        rax, 0               ; RAX register requested
+    or         rax, 4
+    wrmsr
+    rep vmmcall
+    rdmsr
+    cmp        edx, 0bh
+    jb         NoX2ApicSevEs        ; CPUID level below CPUID_EXTENDED_TOPOLOGY
+
+    mov        rdx, 0bh             ; CPUID function 0x0b
+    mov        rax, 040000000h      ; RBX register requested
+    or         rax, 4
+    wrmsr
+    rep vmmcall
+    rdmsr
+    test       edx, 0ffffh
+    jz         NoX2ApicSevEs        ; CPUID.0BH:EBX[15:0] is zero
+
+    mov        rdx, 0bh             ; CPUID function 0x0b
+    mov        rax, 0c0000000h      ; RDX register requested
+    or         rax, 4
+    wrmsr
+    rep vmmcall
+    rdmsr
+
+    ; Processor is x2APIC capable; 32-bit x2APIC ID is now in EDX
+    jmp        RestoreGhcb
+
+NoX2ApicSevEs:
+    ; Processor is not x2APIC capable, so get 8-bit APIC ID
+    mov        rdx, 1               ; CPUID function 1
+    mov        rax, 040000000h      ; RBX register requested
+    or         rax, 4
+    wrmsr
+    rep vmmcall
+    rdmsr
+    shr        edx, 24
+
+RestoreGhcb:
+    mov        rbx, rdx             ; Save x2APIC/APIC ID
+
+    mov        rdx, rdi             ; RDI holds the saved GHCB GPA
+    shr        rdx, 32
+    mov        eax, edi
+    wrmsr
+
+    mov        rdx, rbx
+
+    ; x2APIC ID or APIC ID is in EDX
+    jmp        GetProcessorNumber
+
+SevEsGetApicIdExit:
+    OneTimeCallRet    SevEsGetApicId
diff --git a/UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm b/UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm
index 50df802d1fca..f7f2937fafad 100644
--- a/UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm
+++ b/UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm
@@ -15,6 +15,15 @@
 %include "MpEqu.inc"
 extern ASM_PFX(InitializeFloatingPointUnits)
 
+%macro  OneTimeCall 1
+    jmp     %1
+%1 %+ OneTimerCallReturn:
+%endmacro
+
+%macro  OneTimeCallRet 1
+    jmp     %1 %+ OneTimerCallReturn
+%endmacro
+
 DEFAULT REL
 
 SECTION .text
@@ -144,6 +153,12 @@ SkipEnable5LevelPaging:
     jmp far    [edi]
 
 BITS 64
+
+;
+; Required for the AMD SEV helper functions
+;
+%include "AmdSev.nasm"
+
 LongModeStart:
     mov        esi, ebx
     lea        edi, [esi + MP_CPU_EXCHANGE_INFO_FIELD (InitFlag)]
@@ -175,94 +190,17 @@ LongModeStart:
     add        rax, qword [edi]
     mov        rsp, rax
 
-    lea        edi, [esi + MP_CPU_EXCHANGE_INFO_FIELD (SevEsIsEnabled)]
-    cmp        byte [edi], 1        ; SevEsIsEnabled
-    jne        CProcedureInvoke
-
     ;
-    ; program GHCB
-    ;   Each page after the GHCB is a per-CPU page, so the calculation programs
-    ;   a GHCB to be every 8KB.
+    ;  Setup the GHCB when AMD SEV-ES active.
     ;
-    mov        eax, SIZE_4KB
-    shl        eax, 1                            ; EAX = SIZE_4K * 2
-    mov        ecx, ebx
-    mul        ecx                               ; EAX = SIZE_4K * 2 * CpuNumber
-    mov        edi, esi
-    add        edi, MP_CPU_EXCHANGE_INFO_FIELD (GhcbBase)
-    add        rax, qword [edi]
-    mov        rdx, rax
-    shr        rdx, 32
-    mov        rcx, 0xc0010130
-    wrmsr
+    OneTimeCall SevEsSetupGhcb
     jmp        CProcedureInvoke
 
 GetApicId:
-    lea        edi, [esi + MP_CPU_EXCHANGE_INFO_FIELD (SevEsIsEnabled)]
-    cmp        byte [edi], 1        ; SevEsIsEnabled
-    jne        DoCpuid
-
     ;
-    ; Since we don't have a stack yet, we can't take a #VC
-    ; exception. Use the GHCB protocol to perform the CPUID
-    ; calls.
+    ; Use the GHCB protocol to get the ApicId when SEV-ES is active.
     ;
-    mov        rcx, 0xc0010130
-    rdmsr
-    shl        rdx, 32
-    or         rax, rdx
-    mov        rdi, rax             ; RDI now holds the original GHCB GPA
-
-    mov        rdx, 0               ; CPUID function 0
-    mov        rax, 0               ; RAX register requested
-    or         rax, 4
-    wrmsr
-    rep vmmcall
-    rdmsr
-    cmp        edx, 0bh
-    jb         NoX2ApicSevEs        ; CPUID level below CPUID_EXTENDED_TOPOLOGY
-
-    mov        rdx, 0bh             ; CPUID function 0x0b
-    mov        rax, 040000000h      ; RBX register requested
-    or         rax, 4
-    wrmsr
-    rep vmmcall
-    rdmsr
-    test       edx, 0ffffh
-    jz         NoX2ApicSevEs        ; CPUID.0BH:EBX[15:0] is zero
-
-    mov        rdx, 0bh             ; CPUID function 0x0b
-    mov        rax, 0c0000000h      ; RDX register requested
-    or         rax, 4
-    wrmsr
-    rep vmmcall
-    rdmsr
-
-    ; Processor is x2APIC capable; 32-bit x2APIC ID is now in EDX
-    jmp        RestoreGhcb
-
-NoX2ApicSevEs:
-    ; Processor is not x2APIC capable, so get 8-bit APIC ID
-    mov        rdx, 1               ; CPUID function 1
-    mov        rax, 040000000h      ; RBX register requested
-    or         rax, 4
-    wrmsr
-    rep vmmcall
-    rdmsr
-    shr        edx, 24
-
-RestoreGhcb:
-    mov        rbx, rdx             ; Save x2APIC/APIC ID
-
-    mov        rdx, rdi             ; RDI holds the saved GHCB GPA
-    shr        rdx, 32
-    mov        eax, edi
-    wrmsr
-
-    mov        rdx, rbx
-
-    ; x2APIC ID or APIC ID is in EDX
-    jmp        GetProcessorNumber
+    OneTimeCall SevEsGetApicId
 
 DoCpuid:
     mov        eax, 0
-- 
2.25.1


  parent reply	other threads:[~2021-12-09  3:28 UTC|newest]

Thread overview: 34+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-12-09  3:27 [PATCH v14 00/32] Add AMD Secure Nested Paging (SEV-SNP) support Brijesh Singh
2021-12-09  3:27 ` [PATCH v14 01/32] OvmfPkg/SecMain: move SEV specific routines in AmdSev.c Brijesh Singh
2021-12-09  3:27 ` Brijesh Singh [this message]
2021-12-09  3:27 ` [PATCH v14 03/32] OvmfPkg/ResetVector: move clearing GHCB in SecMain Brijesh Singh
2021-12-09  3:27 ` [PATCH v14 04/32] OvmfPkg/ResetVector: introduce SEV metadata descriptor for VMM use Brijesh Singh
2021-12-09  3:27 ` [PATCH v14 05/32] OvmfPkg: reserve SNP secrets page Brijesh Singh
2021-12-09  3:27 ` [PATCH v14 06/32] OvmfPkg: reserve CPUID page Brijesh Singh
2021-12-09  3:27 ` [PATCH v14 07/32] OvmfPkg/ResetVector: pre-validate the data pages used in SEC phase Brijesh Singh
2021-12-09  3:27 ` [PATCH v14 08/32] OvmfPkg/ResetVector: use SEV-SNP-validated CPUID values Brijesh Singh
2021-12-09  3:27 ` [PATCH v14 09/32] OvmfPkg/MemEncryptSevLib: add MemEncryptSevSnpEnabled() Brijesh Singh
2021-12-09  3:27 ` [PATCH v14 10/32] OvmfPkg/SecMain: register GHCB gpa for the SEV-SNP guest Brijesh Singh
2021-12-09  3:27 ` [PATCH v14 11/32] OvmfPkg/VmgExitLib: use SEV-SNP-validated CPUID values Brijesh Singh
2021-12-09  3:27 ` [PATCH v14 12/32] OvmfPkg/PlatformPei: register GHCB gpa for the SEV-SNP guest Brijesh Singh
2021-12-09  3:27 ` [PATCH v14 13/32] OvmfPkg/AmdSevDxe: do not use extended PCI config space Brijesh Singh
2021-12-09  3:27 ` [PATCH v14 14/32] OvmfPkg/MemEncryptSevLib: add support to validate system RAM Brijesh Singh
2021-12-09  3:27 ` [PATCH v14 15/32] OvmfPkg/MemEncryptSevLib: add function to check the VMPL0 Brijesh Singh
2021-12-09  3:27 ` [PATCH v14 16/32] OvmfPkg/BaseMemEncryptSevLib: skip the pre-validated system RAM Brijesh Singh
2021-12-09  3:27 ` [PATCH v14 17/32] OvmfPkg/MemEncryptSevLib: add support to validate > 4GB memory in PEI phase Brijesh Singh
2021-12-09  3:27 ` [PATCH v14 18/32] OvmfPkg/SecMain: validate the memory used for decompressing Fv Brijesh Singh
2021-12-09  3:27 ` [PATCH v14 19/32] OvmfPkg/PlatformPei: validate the system RAM when SNP is active Brijesh Singh
2021-12-09  3:27 ` [PATCH v14 20/32] MdePkg: Define ConfidentialComputingGuestAttr Brijesh Singh
2021-12-09  3:27 ` [PATCH v14 21/32] OvmfPkg/PlatformPei: set PcdConfidentialComputingAttr when SEV is active Brijesh Singh
2021-12-09  3:27 ` [PATCH v14 22/32] UefiCpuPkg/MpInitLib: use PcdConfidentialComputingAttr to check SEV status Brijesh Singh
2021-12-09  3:27 ` [PATCH v14 23/32] UefiCpuPkg: add PcdGhcbHypervisorFeatures Brijesh Singh
2021-12-09  3:27 ` [PATCH v14 24/32] OvmfPkg/PlatformPei: set the Hypervisor Features PCD Brijesh Singh
2021-12-09  3:27 ` [PATCH v14 25/32] MdePkg/GHCB: increase the GHCB protocol max version Brijesh Singh
2021-12-09  3:27 ` [PATCH v14 26/32] UefiCpuPkg/MpLib: add support to register GHCB GPA when SEV-SNP is enabled Brijesh Singh
2021-12-09  3:27 ` [PATCH v14 27/32] UefiCpuPkg/MpInitLib: use BSP to do extended topology check Brijesh Singh
2021-12-09  3:27 ` [PATCH v14 28/32] OvmfPkg/MemEncryptSevLib: change the page state in the RMP table Brijesh Singh
2021-12-09  3:27 ` [PATCH v14 29/32] OvmfPkg/MemEncryptSevLib: skip page state change for Mmio address Brijesh Singh
2021-12-09  3:27 ` [PATCH v14 30/32] OvmfPkg/PlatformPei: mark cpuid and secrets memory reserved in EFI map Brijesh Singh
2021-12-09  3:27 ` [PATCH v14 31/32] OvmfPkg/AmdSev: expose the SNP reserved pages through configuration table Brijesh Singh
2021-12-09  3:28 ` [PATCH v14 32/32] UefiCpuPkg/MpInitLib: Use SEV-SNP AP Creation NAE event to launch APs Brijesh Singh
2021-12-09  6:30 ` [edk2-devel] [PATCH v14 00/32] Add AMD Secure Nested Paging (SEV-SNP) support Yao, Jiewen

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=20211209032800.3802995-3-brijesh.singh@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