public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: "Yao, Jiewen" <jiewen.yao@intel.com>
To: Brijesh Singh <brijesh.singh@amd.com>,
	"devel@edk2.groups.io" <devel@edk2.groups.io>
Cc: James Bottomley <jejb@linux.ibm.com>,
	"Xu, Min M" <min.m.xu@intel.com>,
	Tom Lendacky <thomas.lendacky@amd.com>,
	"Justen, Jordan L" <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>,
	"Dong, Eric" <eric.dong@intel.com>, "Ni, Ray" <ray.ni@intel.com>,
	"Kumar, Rahul1" <rahul1.kumar@intel.com>
Subject: Re: [PATCH v11 02/32] UefiCpuPkg/MpInitLib: move SEV specific routines in AmdSev.c
Date: Thu, 4 Nov 2021 13:53:27 +0000	[thread overview]
Message-ID: <PH0PR11MB488512A254919EF680154DD18C8D9@PH0PR11MB4885.namprd11.prod.outlook.com> (raw)
In-Reply-To: <ce4c7a34-4826-b16a-61aa-eff2ec57ca4f@amd.com>

Hey
It has been a while since the patch is sent, any feedback from UefiCpuPkg maintainer?



> -----Original Message-----
> From: Brijesh Singh <brijesh.singh@amd.com>
> Sent: Monday, October 25, 2021 7:46 AM
> To: devel@edk2.groups.io
> Cc: brijesh.singh@amd.com; James Bottomley <jejb@linux.ibm.com>; Xu, Min M
> <min.m.xu@intel.com>; Yao, Jiewen <jiewen.yao@intel.com>; Tom Lendacky
> <thomas.lendacky@amd.com>; Justen, Jordan L <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>; Dong, Eric <eric.dong@intel.com>; Ni, Ray
> <ray.ni@intel.com>; Kumar, Rahul1 <rahul1.kumar@intel.com>
> Subject: Re: [PATCH v11 02/32] UefiCpuPkg/MpInitLib: move SEV specific
> routines in AmdSev.c
> 
> Hi Ray and Rahul,
> 
> Any comment on this patch ? If you are okay with it then can I get Ack
> or R-b ?
> 
> -Brijesh
> 
> On 10/22/21 11:13 PM, Brijesh Singh wrote:
> > 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>
> > 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          |  33 +++
> >  UefiCpuPkg/Library/MpInitLib/AmdSev.c         | 239 ++++++++++++++++++
> >  UefiCpuPkg/Library/MpInitLib/MpLib.c          | 218 +---------------
> >  UefiCpuPkg/Library/MpInitLib/X64/AmdSev.nasm  | 119 +++++++++
> >  UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm | 100 ++------
> >  7 files changed, 413 insertions(+), 298 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 e88a5355c983..3d4446df8ce6 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')
> > @@ -741,5 +744,35 @@ 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..7dbf117c2b71
> > --- /dev/null
> > +++ b/UefiCpuPkg/Library/MpInitLib/AmdSev.c
> > @@ -0,0 +1,239 @@
> > +/** @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 b9a06747edbf..890945bc5994 100644
> > --- a/UefiCpuPkg/Library/MpInitLib/MpLib.c
> > +++ b/UefiCpuPkg/Library/MpInitLib/MpLib.c
> > @@ -596,117 +596,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.
> >
> > @@ -884,47 +773,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 ();
> >          }
> > @@ -1252,71 +1101,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

  reply	other threads:[~2021-11-04 13:53 UTC|newest]

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

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=PH0PR11MB488512A254919EF680154DD18C8D9@PH0PR11MB4885.namprd11.prod.outlook.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