public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: "duntan" <dun.tan@intel.com>
To: devel@edk2.groups.io
Cc: Ray Ni <ray.ni@intel.com>, Rahul Kumar <rahul1.kumar@intel.com>,
	Gerd Hoffmann <kraxel@redhat.com>,
	Jiaxin Wu <jiaxin.wu@intel.com>
Subject: [edk2-devel] [Patch V2 13/18] UefiCpuPkg:Relocate AP to new safe buffer in PeiMpLib
Date: Fri, 17 May 2024 17:46:05 +0800	[thread overview]
Message-ID: <20240517094610.533-14-dun.tan@intel.com> (raw)
In-Reply-To: <20240517094610.533-1-dun.tan@intel.com>

In this commit, change PeiMpLib to install callback
of gEdkiiEndOfS3ResumeGuid to relocate AP to new safe
buffer. The gEdkiiEndOfS3ResumeGuid is installed in
S3Resume.c before jmping to OS waking vector.

Previously, code in CpuS3.c of PiSmmCpuDxe driver will
prepare the new safe buffer for AP and place AP in hlt
loop state. With this code change, we can remove the
Machine Instructions of mApHltLoopCode in PiSmmCpuDxe.
Also we can reuse the related code in DxeMpLib for
PeiMpLib.

Signed-off-by: Dun Tan <dun.tan@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Jiaxin Wu <jiaxin.wu@intel.com>
---
 UefiCpuPkg/Library/MpInitLib/MpLib.h          |   3 +++
 UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf |   6 +++++-
 UefiCpuPkg/Library/MpInitLib/PeiMpLib.c       | 154 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 161 insertions(+), 2 deletions(-)

diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.h b/UefiCpuPkg/Library/MpInitLib/MpLib.h
index a4a33bf538..cc850c7dd5 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.h
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.h
@@ -33,6 +33,7 @@
 #include <Library/HobLib.h>
 #include <Library/PcdLib.h>
 #include <Library/MicrocodeLib.h>
+#include <Library/CpuPageTableLib.h>
 #include <ConfidentialComputingGuestAttr.h>
 
 #include <Register/Amd/Fam17Msr.h>
@@ -68,6 +69,8 @@
 //
 #define DEFAULT_MAX_MICROCODE_PATCH_NUM  8
 
+#define PAGING_4K_ADDRESS_MASK_64  0x000FFFFFFFFFF000ull
+
 //
 // Data structure for microcode patch information
 //
diff --git a/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf b/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
index e31e34b6f9..e4a7485fef 100644
--- a/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
+++ b/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
@@ -1,7 +1,7 @@
 ## @file
 #  MP Initialize Library instance for PEI driver.
 #
-#  Copyright (c) 2016 - 2021, Intel Corporation. All rights reserved.<BR>
+#  Copyright (c) 2016 - 2024, Intel Corporation. All rights reserved.<BR>
 #  Copyright (c) 2024, Loongson Technology Corporation Limited. All rights reserved.<BR>
 #  SPDX-License-Identifier: BSD-2-Clause-Patent
 #
@@ -25,10 +25,12 @@
 [Sources.IA32]
   Ia32/AmdSev.c
   Ia32/MpFuncs.nasm
+  Ia32/CreatePageTable.c
 
 [Sources.X64]
   X64/AmdSev.c
   X64/MpFuncs.nasm
+  X64/CreatePageTable.c
 
 [Sources.IA32, Sources.X64]
   AmdSev.c
@@ -64,6 +66,7 @@
   LocalApicLib
   MicrocodeLib
   MtrrLib
+  CpuPageTableLib
 
 [Pcd]
   gEfiMdeModulePkgTokenSpaceGuid.PcdGhcbBase                       ## CONSUMES
@@ -87,6 +90,7 @@
   gEdkiiS3SmmInitDoneGuid
   gEdkiiMicrocodePatchHobGuid
   gGhcbApicIdsGuid                       ## SOMETIMES_CONSUMES
+  gEdkiiEndOfS3ResumeGuid
 
 [Guids.LoongArch64]
   gProcessorResourceHobGuid              ## SOMETIMES_CONSUMES  ## HOB
diff --git a/UefiCpuPkg/Library/MpInitLib/PeiMpLib.c b/UefiCpuPkg/Library/MpInitLib/PeiMpLib.c
index 4d3acb491f..16a858d542 100644
--- a/UefiCpuPkg/Library/MpInitLib/PeiMpLib.c
+++ b/UefiCpuPkg/Library/MpInitLib/PeiMpLib.c
@@ -1,7 +1,7 @@
 /** @file
   MP initialize support functions for PEI phase.
 
-  Copyright (c) 2016 - 2020, Intel Corporation. All rights reserved.<BR>
+  Copyright (c) 2016 - 2024, Intel Corporation. All rights reserved.<BR>
   SPDX-License-Identifier: BSD-2-Clause-Patent
 
 **/
@@ -9,6 +9,7 @@
 #include "MpLib.h"
 #include <Library/PeiServicesLib.h>
 #include <Guid/S3SmmInitDone.h>
+#include <Guid/EndOfS3Resume.h>
 #include <Ppi/ShadowMicrocode.h>
 
 STATIC UINT64  mSevEsPeiWakeupBuffer = BASE_1MB;
@@ -449,6 +450,47 @@ BuildMicrocodeCacheHob (
   return;
 }
 
+/**
+  S3 SMM Init Done notification function.
+
+  @param  PeiServices      Indirect reference to the PEI Services Table.
+  @param  NotifyDesc       Address of the notification descriptor data structure.
+  @param  InvokePpi        Address of the PPI that was invoked.
+
+  @retval EFI_SUCCESS      The function completes successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+NotifyOnEndOfS3Resume (
+  IN  EFI_PEI_SERVICES           **PeiServices,
+  IN  EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyDesc,
+  IN  VOID                       *InvokePpi
+  )
+{
+  CPU_MP_DATA  *CpuMpData;
+
+  CpuMpData       = GetCpuMpData ();
+  mNumberToFinish = CpuMpData->CpuCount - 1;
+  WakeUpAP (CpuMpData, TRUE, 0, RelocateApLoop, NULL, TRUE);
+  while (mNumberToFinish > 0) {
+    CpuPause ();
+  }
+
+  DEBUG ((DEBUG_INFO, "%a() done!\n", __func__));
+
+  return EFI_SUCCESS;
+}
+
+//
+// Global function
+//
+EFI_PEI_NOTIFY_DESCRIPTOR  mEndOfS3ResumeNotifyDesc = {
+  EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+  &gEdkiiEndOfS3ResumeGuid,
+  NotifyOnEndOfS3Resume
+};
+
 /**
   Initialize global data for MP support.
 
@@ -463,12 +505,16 @@ InitMpGlobalData (
 
   BuildMicrocodeCacheHob (CpuMpData);
   SaveCpuMpData (CpuMpData);
+  PrepareApLoopCode (CpuMpData);
 
   ///
   /// Install Notify
   ///
   Status = PeiServicesNotifyPpi (&mS3SmmInitDoneNotifyDesc);
   ASSERT_EFI_ERROR (Status);
+
+  Status = PeiServicesNotifyPpi (&mEndOfS3ResumeNotifyDesc);
+  ASSERT_EFI_ERROR (Status);
 }
 
 /**
@@ -815,3 +861,109 @@ PlatformShadowMicrocode (
 
   return EFI_SUCCESS;
 }
+
+/**
+  Allocate buffer for ApLoopCode.
+
+  @param[in]      Pages    Number of pages to allocate.
+  @param[in, out] Address  Pointer to the allocated buffer.
+**/
+VOID
+AllocateApLoopCodeBuffer (
+  IN UINTN                     Pages,
+  IN OUT EFI_PHYSICAL_ADDRESS  *Address
+  )
+{
+  EFI_STATUS  Status;
+
+  Status = PeiServicesAllocatePages (EfiACPIMemoryNVS, Pages, Address);
+  if (EFI_ERROR (Status)) {
+    *Address = 0;
+  }
+}
+
+/**
+  Remove Nx protection for the range specific by BaseAddress and Length.
+
+  The PEI implementation uses CpuPageTableLib to change the attribute.
+  The DXE implementation uses gDS to change the attribute.
+
+  @param[in] BaseAddress  BaseAddress of the range.
+  @param[in] Length       Length of the range.
+**/
+VOID
+RemoveNxprotection (
+  IN EFI_PHYSICAL_ADDRESS  BaseAddress,
+  IN UINTN                 Length
+  )
+{
+  EFI_STATUS                  Status;
+  UINTN                       PageTable;
+  EFI_PHYSICAL_ADDRESS        Buffer;
+  UINTN                       BufferSize;
+  IA32_MAP_ATTRIBUTE          MapAttribute;
+  IA32_MAP_ATTRIBUTE          MapMask;
+  PAGING_MODE                 PagingMode;
+  IA32_CR4                    Cr4;
+  BOOLEAN                     Page5LevelSupport;
+  UINT32                      RegEax;
+  BOOLEAN                     Page1GSupport;
+  CPUID_EXTENDED_CPU_SIG_EDX  RegEdx;
+
+  if (sizeof (UINTN) == sizeof (UINT64)) {
+    //
+    // Check Page5Level Support or not.
+    //
+    Cr4.UintN         = AsmReadCr4 ();
+    Page5LevelSupport = (Cr4.Bits.LA57 ? TRUE : FALSE);
+
+    //
+    // Check Page1G Support or not.
+    //
+    Page1GSupport = FALSE;
+    AsmCpuid (CPUID_EXTENDED_FUNCTION, &RegEax, NULL, NULL, NULL);
+    if (RegEax >= CPUID_EXTENDED_CPU_SIG) {
+      AsmCpuid (CPUID_EXTENDED_CPU_SIG, NULL, NULL, NULL, &RegEdx.Uint32);
+      if (RegEdx.Bits.Page1GB != 0) {
+        Page1GSupport = TRUE;
+      }
+    }
+
+    //
+    // Decide Paging Mode according Page5LevelSupport & Page1GSupport.
+    //
+    if (Page5LevelSupport) {
+      PagingMode = Page1GSupport ? Paging5Level1GB : Paging5Level;
+    } else {
+      PagingMode = Page1GSupport ? Paging4Level1GB : Paging4Level;
+    }
+  } else {
+    PagingMode = PagingPae;
+  }
+
+  MapAttribute.Uint64 = 0;
+  MapMask.Uint64      = 0;
+  MapMask.Bits.Nx     = 1;
+  PageTable           = AsmReadCr3 () & PAGING_4K_ADDRESS_MASK_64;
+  BufferSize          = 0;
+
+  //
+  // Get required buffer size for changing the pagetable.
+  //
+  Status = PageTableMap (&PageTable, PagingMode, 0, &BufferSize, BaseAddress, Length, &MapAttribute, &MapMask, NULL);
+  if (Status == EFI_BUFFER_TOO_SMALL) {
+    //
+    // Allocate required Buffer.
+    //
+    Status = PeiServicesAllocatePages (
+               EfiBootServicesData,
+               EFI_SIZE_TO_PAGES (BufferSize),
+               &Buffer
+               );
+    ASSERT_EFI_ERROR (Status);
+    Status = PageTableMap (&PageTable, PagingMode, (VOID *)(UINTN)Buffer, &BufferSize, BaseAddress, Length, &MapAttribute, &MapMask, NULL);
+  }
+
+  ASSERT_EFI_ERROR (Status);
+  AsmWriteCr3 (PageTable);
+}
-- 
2.31.1.windows.1



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#119010): https://edk2.groups.io/g/devel/message/119010
Mute This Topic: https://groups.io/mt/106150773/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-



  parent reply	other threads:[~2024-05-17  9:47 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-05-17  9:45 [edk2-devel] [Patch V2 00/18] Remove some S3 related code in CpuS3.c of smm cpu driver duntan
2024-05-17  9:45 ` [edk2-devel] [Patch V2 01/18] MdeModulePkg: Add gEdkiiS3MtrrSettingGuid duntan
2024-05-17  9:45 ` [edk2-devel] [Patch V2 02/18] OvmfPkg: Save MTRR by lockbox in CpuS3DataDxe duntan
2024-05-17  9:45 ` [edk2-devel] [Patch V2 03/18] UefiCpuPkg: Add locbox lib instance in DSC duntan
2024-05-17  9:45 ` [edk2-devel] [Patch V2 04/18] UefiCpuPkg: Save MTRR by lockbox in CpuS3DataDxe duntan
2024-05-17  9:45 ` [edk2-devel] [Patch V2 05/18] UefiCpuPkg: LoadMtrrData for all cpu in S3Resume duntan
2024-05-17  9:45 ` [edk2-devel] [Patch V2 06/18] UefiCpuPkg: Remove code to load mtrr setting duntan
2024-05-17  9:45 ` [edk2-devel] [Patch V2 07/18] UefiCpuPkg:Set PcdCpuFeaturesInitOnS3Resume to TRUE duntan
2024-05-17  9:46 ` [edk2-devel] [Patch V2 08/18] UefiCpuPkg: Remove code to set register table duntan
2024-05-17  9:46 ` [edk2-devel] [Patch V2 09/18] UefiCpuPkg: Disable PG in IA32 ApLoopCode duntan
2024-05-17  9:46 ` [edk2-devel] [Patch V2 10/18] UefiCpuPkg:Abstract some DxeMpLib code to function duntan
2024-05-17  9:46 ` [edk2-devel] [Patch V2 11/18] UefiCpuPkg:Move some code in DxeMpLib to common place duntan
2024-05-17  9:46 ` [edk2-devel] [Patch V2 12/18] UefiCpuPkg: Install gEdkiiEndOfS3ResumeGuid in S3Resume duntan
2024-05-17  9:46 ` duntan [this message]
2024-05-17  9:46 ` [edk2-devel] [Patch V2 14/18] UefiCpuPkg:Remove code to handle APIC setting and Interrupt duntan
2024-05-17  9:46 ` [edk2-devel] [Patch V2 15/18] UefiCpuPkg:Remove code to wakeup AP and relocate ap duntan
2024-05-17  9:46 ` [edk2-devel] [Patch V2 16/18] UefiCpuPkg: Remove unneeded MpService2Ppi assignment duntan
2024-05-17  9:46 ` [edk2-devel] [Patch V2 17/18] MdeModulePkg:Remove MpService2Ppi field in SMM_S3_RESUME_STATE duntan
2024-05-17  9:46 ` [edk2-devel] [Patch V2 18/18] UefiCpuPkg: Remove GetAcpiCpuData() in CpuS3.c duntan
2024-05-20  7:05 ` [edk2-devel] [Patch V2 00/18] Remove some S3 related code in CpuS3.c of smm cpu driver Ni, Ray
2024-05-24  3:18   ` duntan
2024-05-24  3:07 ` Wu, Jiaxin
     [not found] ` <17D03DA5161A67E3.17823@groups.io>
2024-05-28  6:35   ` [edk2-devel] [Patch V2 17/18] MdeModulePkg:Remove MpService2Ppi field in SMM_S3_RESUME_STATE duntan
2024-05-28  9:16     ` 回复: " gaoliming via groups.io
2024-05-28  9:34       ` duntan
2024-05-28  9:39         ` 回复: " gaoliming via groups.io
2024-05-28  9:44           ` duntan
2024-05-30  5:00             ` 回复: " gaoliming via groups.io
     [not found] ` <17D03D9CBFB2693B.16299@groups.io>
2024-05-28  6:37   ` [edk2-devel] [Patch V2 01/18] MdeModulePkg: Add gEdkiiS3MtrrSettingGuid duntan
2024-05-28  9:14     ` 回复: " gaoliming via groups.io

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=20240517094610.533-14-dun.tan@intel.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