[edk2-devel] [PATCH v2 2/2] MdeModulePkg: Optimize CoreConnectSingleController

2024-01-22 Thread Zhi Jin
CoreConnectSingleController() searches for the Driver Family Override
Protocol drivers by looping and checking each Driver Binding Handles.
This loop can be skipped by checking if any Driver Family Override
Protocol installed in the platform first, to improve the performance.

Cc: Liming Gao 
Cc: Ray Ni 
Reviewed-by: Michael D Kinney 
Signed-off-by: Zhi Jin 
---
 MdeModulePkg/Core/Dxe/Hand/DriverSupport.c | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/MdeModulePkg/Core/Dxe/Hand/DriverSupport.c 
b/MdeModulePkg/Core/Dxe/Hand/DriverSupport.c
index 0b824c62b7..64d7474f15 100644
--- a/MdeModulePkg/Core/Dxe/Hand/DriverSupport.c
+++ b/MdeModulePkg/Core/Dxe/Hand/DriverSupport.c
@@ -497,7 +497,12 @@ CoreConnectSingleController (
   //
   // Add the Driver Family Override Protocol drivers for ControllerHandle
   //
-  while (TRUE) {
+  Status = CoreLocateProtocol (
+ ,
+ NULL,
+ (VOID **)
+ );
+  while (!EFI_ERROR (Status) && (DriverFamilyOverride != NULL)) {
 HighestIndex   = DriverBindingHandleCount;
 HighestVersion = 0;
 for (Index = 0; Index < DriverBindingHandleCount; Index++) {
-- 
2.39.2



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#114138): https://edk2.groups.io/g/devel/message/114138
Mute This Topic: https://groups.io/mt/103883258/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-




[edk2-devel] [PATCH v2 1/2] MdeModulePkg: Remove the handle validation check in CoreGetProtocolInterface

2024-01-22 Thread Zhi Jin
CoreGetProtocolInterface() is called by CoreOpenProtocol(),
CoreCloseProtocol() and CoreOpenProtocolInformation().
Before CoreOpenProtocol() calls CoreGetProtocolInterface(), the input
parameter UserHandle has been already checked for validation. So does
CoreCloseProtocol().
Removing the handle validation check in CoreGetProtocolInterface()
could improve the performance, as CoreOpenProtocol() is called very
frequently.
To ensure the assumption that the caller of CoreGetProtocolInterface()
must pass in a valid UserHandle that is checked with CoreValidateHandle(),
add the parameter check in CoreOpenProtocolInformation(), and declare
CoreGetProtocolInterface() as static.

v1 -> v2:
  1. Update the description of UserHandle to state that the caller
 must pass in a valid UserHandle that is checked with
 CoreValidateHandle().
  2. Declare CoreGetProtocolInterface() as static.

Cc: Liming Gao 
Cc: Ray Ni 
Cc: Michael D Kinney 
Signed-off-by: Zhi Jin 
---
 MdeModulePkg/Core/Dxe/Hand/Handle.c | 18 --
 1 file changed, 12 insertions(+), 6 deletions(-)

diff --git a/MdeModulePkg/Core/Dxe/Hand/Handle.c 
b/MdeModulePkg/Core/Dxe/Hand/Handle.c
index 51e5b5d3b3..24e4fbf5f3 100644
--- a/MdeModulePkg/Core/Dxe/Hand/Handle.c
+++ b/MdeModulePkg/Core/Dxe/Hand/Handle.c
@@ -918,28 +918,25 @@ CoreUninstallMultipleProtocolInterfaces (
   Locate a certain GUID protocol interface in a Handle's protocols.
 
   @param  UserHandle The handle to obtain the protocol interface on
+ The caller must pass in a valid UserHandle 
that
+ is checked with CoreValidateHandle().
   @param  Protocol   The GUID of the protocol
 
   @return The requested protocol interface for the handle
 
 **/
+STATIC
 PROTOCOL_INTERFACE  *
 CoreGetProtocolInterface (
   IN  EFI_HANDLE  UserHandle,
   IN  EFI_GUID*Protocol
   )
 {
-  EFI_STATUS  Status;
   PROTOCOL_ENTRY  *ProtEntry;
   PROTOCOL_INTERFACE  *Prot;
   IHANDLE *Handle;
   LIST_ENTRY  *Link;
 
-  Status = CoreValidateHandle (UserHandle);
-  if (EFI_ERROR (Status)) {
-return NULL;
-  }
-
   Handle = (IHANDLE *)UserHandle;
 
   //
@@ -1392,6 +1389,15 @@ CoreOpenProtocolInformation (
   //
   CoreAcquireProtocolLock ();
 
+  //
+  // Check for invalid UserHandle
+  //
+  Status = CoreValidateHandle (UserHandle);
+  if (EFI_ERROR (Status)) {
+Status = EFI_NOT_FOUND;
+goto Done;
+  }
+
   //
   // Look at each protocol interface for a match
   //
-- 
2.39.2



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#114137): https://edk2.groups.io/g/devel/message/114137
Mute This Topic: https://groups.io/mt/103883257/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-




[edk2-devel] [PATCH 2/2] MdeModulePkg: Optimize CoreConnectSingleController

2024-01-16 Thread Zhi Jin
CoreConnectSingleController() searches for the Driver Family Override
Protocol drivers by looping and checking each Driver Binding Handles.
This loop can be skipped by checking if any Driver Family Override
Protocol installed in the platform first, to improve the performance.

Cc: Liming Gao 
Cc: Ray Ni 
Signed-off-by: Zhi Jin 
---
 MdeModulePkg/Core/Dxe/Hand/DriverSupport.c | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/MdeModulePkg/Core/Dxe/Hand/DriverSupport.c 
b/MdeModulePkg/Core/Dxe/Hand/DriverSupport.c
index 0b824c62b7..64d7474f15 100644
--- a/MdeModulePkg/Core/Dxe/Hand/DriverSupport.c
+++ b/MdeModulePkg/Core/Dxe/Hand/DriverSupport.c
@@ -497,7 +497,12 @@ CoreConnectSingleController (
   //
   // Add the Driver Family Override Protocol drivers for ControllerHandle
   //
-  while (TRUE) {
+  Status = CoreLocateProtocol (
+ ,
+ NULL,
+ (VOID **)
+ );
+  while (!EFI_ERROR (Status) && (DriverFamilyOverride != NULL)) {
 HighestIndex   = DriverBindingHandleCount;
 HighestVersion = 0;
 for (Index = 0; Index < DriverBindingHandleCount; Index++) {
-- 
2.39.2



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#113931): https://edk2.groups.io/g/devel/message/113931
Mute This Topic: https://groups.io/mt/103781274/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-




[edk2-devel] [PATCH 1/2] MdeModulePkg: Remove the handle validation check in CoreGetProtocolInterface

2024-01-16 Thread Zhi Jin
CoreGetProtocolInterface() is called by CoreOpenProtocol(),
CoreCloseProtocol() and CoreOpenProtocolInformation().
Before CoreOpenProtocol() calls CoreGetProtocolInterface(), the input
parameter UserHandle has been already checked for validation. So does
CoreCloseProtocol().
Removing the handle validation check in CoreGetProtocolInterface()
could improve the performance, as CoreOpenProtocol() is called very
frequently.
Meanwhile, need to make it the caller's responsibility to check the
parameters, and add the check in CoreOpenProtocolInformation().

Cc: Liming Gao 
Cc: Ray Ni 
Signed-off-by: Zhi Jin 
---
 MdeModulePkg/Core/Dxe/Hand/Handle.c | 17 +++--
 1 file changed, 11 insertions(+), 6 deletions(-)

diff --git a/MdeModulePkg/Core/Dxe/Hand/Handle.c 
b/MdeModulePkg/Core/Dxe/Hand/Handle.c
index 51e5b5d3b3..a0d2d03267 100644
--- a/MdeModulePkg/Core/Dxe/Hand/Handle.c
+++ b/MdeModulePkg/Core/Dxe/Hand/Handle.c
@@ -916,6 +916,8 @@ CoreUninstallMultipleProtocolInterfaces (
 
 /**
   Locate a certain GUID protocol interface in a Handle's protocols.
+  Note: This function doesn't do parameters checking, it's caller's 
responsibility
+  to pass in valid parameters.
 
   @param  UserHandle The handle to obtain the protocol interface on
   @param  Protocol   The GUID of the protocol
@@ -929,17 +931,11 @@ CoreGetProtocolInterface (
   IN  EFI_GUID*Protocol
   )
 {
-  EFI_STATUS  Status;
   PROTOCOL_ENTRY  *ProtEntry;
   PROTOCOL_INTERFACE  *Prot;
   IHANDLE *Handle;
   LIST_ENTRY  *Link;
 
-  Status = CoreValidateHandle (UserHandle);
-  if (EFI_ERROR (Status)) {
-return NULL;
-  }
-
   Handle = (IHANDLE *)UserHandle;
 
   //
@@ -1392,6 +1388,15 @@ CoreOpenProtocolInformation (
   //
   CoreAcquireProtocolLock ();
 
+  //
+  // Check for invalid UserHandle
+  //
+  Status = CoreValidateHandle (UserHandle);
+  if (EFI_ERROR (Status)) {
+Status = EFI_NOT_FOUND;
+goto Done;
+  }
+
   //
   // Look at each protocol interface for a match
   //
-- 
2.39.2



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#113930): https://edk2.groups.io/g/devel/message/113930
Mute This Topic: https://groups.io/mt/103781273/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-




[edk2-devel] [PATCH v2 1/1] UefiCpuPkg/PiSmmCpuDxeSmm: Optimize PatchSmmSaveStateMap and FlushTlbForAll

2024-01-04 Thread Zhi Jin
PatchSmmSaveStateMap patches the SMM entry (code) and SmmSaveState
region (data) for each core, which can be improved to flush TLB once
after all the memory entries have been patched.
FlushTlbForAll flushes TLB for each core in serial, which can be
improved to flush TLB in parrallel.

v2:
   Add the missing FlushTlbForAll() back in PatchSmmSaveStateMap().

Cc: Ray Ni 
Cc: Laszlo Ersek 
Cc: Rahul Kumar 
Cc: Gerd Hoffmann 
Cc: Jiaxin Wu 
Signed-off-by: Zhi Jin 
---
 .../PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c   | 97 +--
 1 file changed, 65 insertions(+), 32 deletions(-)

diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c 
b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c
index 15f998e501..12f3c0b8e8 100644
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c
+++ b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c
@@ -547,17 +547,14 @@ FlushTlbForAll (
   VOID
   )
 {
-  UINTN  Index;
-
   FlushTlbOnCurrentProcessor (NULL);
-
-  for (Index = 0; Index < gSmst->NumberOfCpus; Index++) {
-if (Index != gSmst->CurrentlyExecutingCpu) {
-  // Force to start up AP in blocking mode,
-  SmmBlockingStartupThisAp (FlushTlbOnCurrentProcessor, Index, NULL);
-  // Do not check return status, because AP might not be present in some 
corner cases.
-}
-  }
+  InternalSmmStartupAllAPs (
+(EFI_AP_PROCEDURE2)FlushTlbOnCurrentProcessor,
+0,
+NULL,
+NULL,
+NULL
+);
 }
 
 /**
@@ -799,72 +796,108 @@ PatchSmmSaveStateMap (
   UINTN  TileCodeSize;
   UINTN  TileDataSize;
   UINTN  TileSize;
+  UINTN  PageTableBase;
 
-  TileCodeSize = GetSmiHandlerSize ();
-  TileCodeSize = ALIGN_VALUE (TileCodeSize, SIZE_4KB);
-  TileDataSize = (SMRAM_SAVE_STATE_MAP_OFFSET - SMM_PSD_OFFSET) + sizeof 
(SMRAM_SAVE_STATE_MAP);
-  TileDataSize = ALIGN_VALUE (TileDataSize, SIZE_4KB);
-  TileSize = TileDataSize + TileCodeSize - 1;
-  TileSize = 2 * GetPowerOfTwo32 ((UINT32)TileSize);
+  TileCodeSize  = GetSmiHandlerSize ();
+  TileCodeSize  = ALIGN_VALUE (TileCodeSize, SIZE_4KB);
+  TileDataSize  = (SMRAM_SAVE_STATE_MAP_OFFSET - SMM_PSD_OFFSET) + sizeof 
(SMRAM_SAVE_STATE_MAP);
+  TileDataSize  = ALIGN_VALUE (TileDataSize, SIZE_4KB);
+  TileSize  = TileDataSize + TileCodeSize - 1;
+  TileSize  = 2 * GetPowerOfTwo32 ((UINT32)TileSize);
+  PageTableBase = AsmReadCr3 () & PAGING_4K_ADDRESS_MASK_64;
 
   DEBUG ((DEBUG_INFO, "PatchSmmSaveStateMap:\n"));
   for (Index = 0; Index < mMaxNumberOfCpus - 1; Index++) {
 //
 // Code
 //
-SmmSetMemoryAttributes (
+ConvertMemoryPageAttributes (
+  PageTableBase,
+  mPagingMode,
   mCpuHotPlugData.SmBase[Index] + SMM_HANDLER_OFFSET,
   TileCodeSize,
-  EFI_MEMORY_RO
+  EFI_MEMORY_RO,
+  TRUE,
+  NULL
   );
-SmmClearMemoryAttributes (
+ConvertMemoryPageAttributes (
+  PageTableBase,
+  mPagingMode,
   mCpuHotPlugData.SmBase[Index] + SMM_HANDLER_OFFSET,
   TileCodeSize,
-  EFI_MEMORY_XP
+  EFI_MEMORY_XP,
+  FALSE,
+  NULL
   );
 
 //
 // Data
 //
-SmmClearMemoryAttributes (
+ConvertMemoryPageAttributes (
+  PageTableBase,
+  mPagingMode,
   mCpuHotPlugData.SmBase[Index] + SMM_HANDLER_OFFSET + TileCodeSize,
   TileSize - TileCodeSize,
-  EFI_MEMORY_RO
+  EFI_MEMORY_RO,
+  FALSE,
+  NULL
   );
-SmmSetMemoryAttributes (
+ConvertMemoryPageAttributes (
+  PageTableBase,
+  mPagingMode,
   mCpuHotPlugData.SmBase[Index] + SMM_HANDLER_OFFSET + TileCodeSize,
   TileSize - TileCodeSize,
-  EFI_MEMORY_XP
+  EFI_MEMORY_XP,
+  TRUE,
+  NULL
   );
   }
 
   //
   // Code
   //
-  SmmSetMemoryAttributes (
+  ConvertMemoryPageAttributes (
+PageTableBase,
+mPagingMode,
 mCpuHotPlugData.SmBase[mMaxNumberOfCpus - 1] + SMM_HANDLER_OFFSET,
 TileCodeSize,
-EFI_MEMORY_RO
+EFI_MEMORY_RO,
+TRUE,
+NULL
 );
-  SmmClearMemoryAttributes (
+  ConvertMemoryPageAttributes (
+PageTableBase,
+mPagingMode,
 mCpuHotPlugData.SmBase[mMaxNumberOfCpus - 1] + SMM_HANDLER_OFFSET,
 TileCodeSize,
-EFI_MEMORY_XP
+EFI_MEMORY_XP,
+FALSE,
+NULL
 );
 
   //
   // Data
   //
-  SmmClearMemoryAttributes (
+  ConvertMemoryPageAttributes (
+PageTableBase,
+mPagingMode,
 mCpuHotPlugData.SmBase[mMaxNumberOfCpus - 1] + SMM_HANDLER_OFFSET + 
TileCodeSize,
 SIZE_32KB - TileCodeSize,
-EFI_MEMORY_RO
+EFI_MEMORY_RO,
+FALSE,
+NULL
 );
-  SmmSetMemoryAttributes (
+  ConvertMemoryPageAttributes (
+PageTableBase,
+mPagingMode,
 mCpuHotPlugData.SmBase[mMaxNumberOfCpus - 1] + SMM_HANDLER_OFFSET + 
TileCodeSize,
 SIZE_32KB - TileCodeSize,
-EFI_MEMORY_XP
+EFI_MEMORY_XP,
+TRUE,
+NULL
 );
+
+  FlushTlbForAll ();
 }
 
 /**
-- 
2.39.2



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Onli

Re: [edk2-devel] [PATCH 1/1] UefiCpuPkg/PiSmmCpuDxeSmm: Optimize PatchSmmSaveStateMap and FlushTlbForAll

2024-01-04 Thread Zhi Jin
Thanks for the comments, Ray.
It is a mistake to remove the FlushTlb() in this patch. I will send out the 
patch v2.

BRs
Zhi Jin

-Original Message-
From: Ni, Ray  
Sent: Friday, January 05, 2024 10:21 AM
To: devel@edk2.groups.io; Jin, Zhi 
Cc: Laszlo Ersek ; Kumar, Rahul R ; 
Gerd Hoffmann ; Wu, Jiaxin 
Subject: RE: [edk2-devel] [PATCH 1/1] UefiCpuPkg/PiSmmCpuDxeSmm: Optimize 
PatchSmmSaveStateMap and FlushTlbForAll

Zhi,
With your patch,
1. SMM entry(code) and SmmSaveState region (data) are changed to correct paging 
attributes.
2. FlushTlb() is removed after the changing.
3. FlushTlb() is updated to flush in parallel.

My concern is about #2. Can you explain a bit why FlushTlb() can be removed 
after changing paging attributes in #1?

Thanks,
Ray
> -Original Message-
> From: devel@edk2.groups.io  On Behalf Of Jin, Zhi
> Sent: Friday, January 5, 2024 10:04 AM
> To: devel@edk2.groups.io
> Cc: Jin, Zhi ; Ni, Ray ; Laszlo Ersek
> ; Kumar, Rahul R ; Gerd
> Hoffmann ; Wu, Jiaxin 
> Subject: [edk2-devel] [PATCH 1/1] UefiCpuPkg/PiSmmCpuDxeSmm: Optimize
> PatchSmmSaveStateMap and FlushTlbForAll
> 
> PatchSmmSaveStateMap patches the SMM entry (code) and SmmSaveState
> region (data) for each core, which can be improved to flush TLB once
> after all the memory entries have been patched.
> FlushTlbForAll flushes TLB for each core in serial, which can be
> improved to flush TLB in parrallel.
> 
> Cc: Ray Ni 
> Cc: Laszlo Ersek 
> Cc: Rahul Kumar 
> Cc: Gerd Hoffmann 
> Cc: Jiaxin Wu 
> Signed-off-by: Zhi Jin 
> ---
>  .../PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c   | 95
> ---
>  1 file changed, 63 insertions(+), 32 deletions(-)
> 
> diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c
> b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c
> index 15f998e501..d4066436f5 100644
> --- a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c
> +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c
> @@ -547,17 +547,14 @@ FlushTlbForAll (
>VOID
>)
>  {
> -  UINTN  Index;
> -
>FlushTlbOnCurrentProcessor (NULL);
> -
> -  for (Index = 0; Index < gSmst->NumberOfCpus; Index++) {
> -if (Index != gSmst->CurrentlyExecutingCpu) {
> -  // Force to start up AP in blocking mode,
> -  SmmBlockingStartupThisAp (FlushTlbOnCurrentProcessor, Index, NULL);
> -  // Do not check return status, because AP might not be present in some
> corner cases.
> -}
> -  }
> +  InternalSmmStartupAllAPs (
> +(EFI_AP_PROCEDURE2)FlushTlbOnCurrentProcessor,
> +0,
> +NULL,
> +NULL,
> +NULL
> +);
>  }
> 
>  /**
> @@ -799,71 +796,105 @@ PatchSmmSaveStateMap (
>UINTN  TileCodeSize;
>UINTN  TileDataSize;
>UINTN  TileSize;
> +  UINTN  PageTableBase;
> 
> -  TileCodeSize = GetSmiHandlerSize ();
> -  TileCodeSize = ALIGN_VALUE (TileCodeSize, SIZE_4KB);
> -  TileDataSize = (SMRAM_SAVE_STATE_MAP_OFFSET - SMM_PSD_OFFSET) +
> sizeof (SMRAM_SAVE_STATE_MAP);
> -  TileDataSize = ALIGN_VALUE (TileDataSize, SIZE_4KB);
> -  TileSize = TileDataSize + TileCodeSize - 1;
> -  TileSize = 2 * GetPowerOfTwo32 ((UINT32)TileSize);
> +  TileCodeSize  = GetSmiHandlerSize ();
> +  TileCodeSize  = ALIGN_VALUE (TileCodeSize, SIZE_4KB);
> +  TileDataSize  = (SMRAM_SAVE_STATE_MAP_OFFSET - SMM_PSD_OFFSET) +
> sizeof (SMRAM_SAVE_STATE_MAP);
> +  TileDataSize  = ALIGN_VALUE (TileDataSize, SIZE_4KB);
> +  TileSize  = TileDataSize + TileCodeSize - 1;
> +  TileSize  = 2 * GetPowerOfTwo32 ((UINT32)TileSize);
> +  PageTableBase = AsmReadCr3 () & PAGING_4K_ADDRESS_MASK_64;
> 
>DEBUG ((DEBUG_INFO, "PatchSmmSaveStateMap:\n"));
>for (Index = 0; Index < mMaxNumberOfCpus - 1; Index++) {
>  //
>  // Code
>  //
> -SmmSetMemoryAttributes (
> +ConvertMemoryPageAttributes (
> +  PageTableBase,
> +  mPagingMode,
>mCpuHotPlugData.SmBase[Index] + SMM_HANDLER_OFFSET,
>TileCodeSize,
> -  EFI_MEMORY_RO
> +  EFI_MEMORY_RO,
> +  TRUE,
> +  NULL
>);
> -SmmClearMemoryAttributes (
> +ConvertMemoryPageAttributes (
> +  PageTableBase,
> +  mPagingMode,
>mCpuHotPlugData.SmBase[Index] + SMM_HANDLER_OFFSET,
>TileCodeSize,
> -  EFI_MEMORY_XP
> +  EFI_MEMORY_XP,
> +  FALSE,
> +  NULL
>);
> 
>  //
>  // Data
>  //
> -SmmClearMemoryAttributes (
> +ConvertMemoryPageAttributes (
> +  PageTableBase,
> +  mPagingMode,
>mCpuHotPlugData.SmBase[Index] + SMM_HANDLER_OFFSET +
> TileCodeSize,
>TileSize - TileCodeSize,
> -  EFI_MEMORY_RO
> +  EFI_MEMORY_RO,
&

[edk2-devel] [PATCH 1/1] UefiCpuPkg/PiSmmCpuDxeSmm: Optimize PatchSmmSaveStateMap and FlushTlbForAll

2024-01-04 Thread Zhi Jin
PatchSmmSaveStateMap patches the SMM entry (code) and SmmSaveState
region (data) for each core, which can be improved to flush TLB once
after all the memory entries have been patched.
FlushTlbForAll flushes TLB for each core in serial, which can be
improved to flush TLB in parrallel.

Cc: Ray Ni 
Cc: Laszlo Ersek 
Cc: Rahul Kumar 
Cc: Gerd Hoffmann 
Cc: Jiaxin Wu 
Signed-off-by: Zhi Jin 
---
 .../PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c   | 95 ---
 1 file changed, 63 insertions(+), 32 deletions(-)

diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c 
b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c
index 15f998e501..d4066436f5 100644
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c
+++ b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c
@@ -547,17 +547,14 @@ FlushTlbForAll (
   VOID
   )
 {
-  UINTN  Index;
-
   FlushTlbOnCurrentProcessor (NULL);
-
-  for (Index = 0; Index < gSmst->NumberOfCpus; Index++) {
-if (Index != gSmst->CurrentlyExecutingCpu) {
-  // Force to start up AP in blocking mode,
-  SmmBlockingStartupThisAp (FlushTlbOnCurrentProcessor, Index, NULL);
-  // Do not check return status, because AP might not be present in some 
corner cases.
-}
-  }
+  InternalSmmStartupAllAPs (
+(EFI_AP_PROCEDURE2)FlushTlbOnCurrentProcessor,
+0,
+NULL,
+NULL,
+NULL
+);
 }
 
 /**
@@ -799,71 +796,105 @@ PatchSmmSaveStateMap (
   UINTN  TileCodeSize;
   UINTN  TileDataSize;
   UINTN  TileSize;
+  UINTN  PageTableBase;
 
-  TileCodeSize = GetSmiHandlerSize ();
-  TileCodeSize = ALIGN_VALUE (TileCodeSize, SIZE_4KB);
-  TileDataSize = (SMRAM_SAVE_STATE_MAP_OFFSET - SMM_PSD_OFFSET) + sizeof 
(SMRAM_SAVE_STATE_MAP);
-  TileDataSize = ALIGN_VALUE (TileDataSize, SIZE_4KB);
-  TileSize = TileDataSize + TileCodeSize - 1;
-  TileSize = 2 * GetPowerOfTwo32 ((UINT32)TileSize);
+  TileCodeSize  = GetSmiHandlerSize ();
+  TileCodeSize  = ALIGN_VALUE (TileCodeSize, SIZE_4KB);
+  TileDataSize  = (SMRAM_SAVE_STATE_MAP_OFFSET - SMM_PSD_OFFSET) + sizeof 
(SMRAM_SAVE_STATE_MAP);
+  TileDataSize  = ALIGN_VALUE (TileDataSize, SIZE_4KB);
+  TileSize  = TileDataSize + TileCodeSize - 1;
+  TileSize  = 2 * GetPowerOfTwo32 ((UINT32)TileSize);
+  PageTableBase = AsmReadCr3 () & PAGING_4K_ADDRESS_MASK_64;
 
   DEBUG ((DEBUG_INFO, "PatchSmmSaveStateMap:\n"));
   for (Index = 0; Index < mMaxNumberOfCpus - 1; Index++) {
 //
 // Code
 //
-SmmSetMemoryAttributes (
+ConvertMemoryPageAttributes (
+  PageTableBase,
+  mPagingMode,
   mCpuHotPlugData.SmBase[Index] + SMM_HANDLER_OFFSET,
   TileCodeSize,
-  EFI_MEMORY_RO
+  EFI_MEMORY_RO,
+  TRUE,
+  NULL
   );
-SmmClearMemoryAttributes (
+ConvertMemoryPageAttributes (
+  PageTableBase,
+  mPagingMode,
   mCpuHotPlugData.SmBase[Index] + SMM_HANDLER_OFFSET,
   TileCodeSize,
-  EFI_MEMORY_XP
+  EFI_MEMORY_XP,
+  FALSE,
+  NULL
   );
 
 //
 // Data
 //
-SmmClearMemoryAttributes (
+ConvertMemoryPageAttributes (
+  PageTableBase,
+  mPagingMode,
   mCpuHotPlugData.SmBase[Index] + SMM_HANDLER_OFFSET + TileCodeSize,
   TileSize - TileCodeSize,
-  EFI_MEMORY_RO
+  EFI_MEMORY_RO,
+  FALSE,
+  NULL
   );
-SmmSetMemoryAttributes (
+ConvertMemoryPageAttributes (
+  PageTableBase,
+  mPagingMode,
   mCpuHotPlugData.SmBase[Index] + SMM_HANDLER_OFFSET + TileCodeSize,
   TileSize - TileCodeSize,
-  EFI_MEMORY_XP
+  EFI_MEMORY_XP,
+  TRUE,
+  NULL
   );
   }
 
   //
   // Code
   //
-  SmmSetMemoryAttributes (
+  ConvertMemoryPageAttributes (
+PageTableBase,
+mPagingMode,
 mCpuHotPlugData.SmBase[mMaxNumberOfCpus - 1] + SMM_HANDLER_OFFSET,
 TileCodeSize,
-EFI_MEMORY_RO
+EFI_MEMORY_RO,
+TRUE,
+NULL
 );
-  SmmClearMemoryAttributes (
+  ConvertMemoryPageAttributes (
+PageTableBase,
+mPagingMode,
 mCpuHotPlugData.SmBase[mMaxNumberOfCpus - 1] + SMM_HANDLER_OFFSET,
 TileCodeSize,
-EFI_MEMORY_XP
+EFI_MEMORY_XP,
+FALSE,
+NULL
 );
 
   //
   // Data
   //
-  SmmClearMemoryAttributes (
+  ConvertMemoryPageAttributes (
+PageTableBase,
+mPagingMode,
 mCpuHotPlugData.SmBase[mMaxNumberOfCpus - 1] + SMM_HANDLER_OFFSET + 
TileCodeSize,
 SIZE_32KB - TileCodeSize,
-EFI_MEMORY_RO
+EFI_MEMORY_RO,
+FALSE,
+NULL
 );
-  SmmSetMemoryAttributes (
+  ConvertMemoryPageAttributes (
+PageTableBase,
+mPagingMode,
 mCpuHotPlugData.SmBase[mMaxNumberOfCpus - 1] + SMM_HANDLER_OFFSET + 
TileCodeSize,
 SIZE_32KB - TileCodeSize,
-EFI_MEMORY_XP
+EFI_MEMORY_XP,
+TRUE,
+NULL
 );
 }
 
-- 
2.39.2



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#113205): https://edk2.groups.io/g/devel/message/113205
Mute This Topic: https://groups.io/mt/1

Re: [edk2-devel] [PATCH 1/1] MdeModulePkg: Optimize CoreInstallMultipleProtocolInterfaces

2023-11-26 Thread Zhi Jin
Hi @Liming Gao<mailto:gaolim...@byosoft.com.cn>,

  Would you please help to review this patch? Thanks!

BRs
Zhi Jin

From: Ni, Ray 
Sent: Thursday, November 09, 2023 10:36 AM
To: Jin, Zhi ; devel@edk2.groups.io
Cc: Wang, Jian J ; Gao, Liming 
; Bi, Dandan 
Subject: Re: [PATCH 1/1] MdeModulePkg: Optimize 
CoreInstallMultipleProtocolInterfaces

Reviewed-by: Ray Ni mailto:ray...@intel.com>>

Thanks,
Ray

From: Jin, Zhi mailto:zhi@intel.com>>
Sent: Thursday, November 9, 2023 9:46 AM
To: devel@edk2.groups.io<mailto:devel@edk2.groups.io> 
mailto:devel@edk2.groups.io>>
Cc: Jin, Zhi mailto:zhi@intel.com>>; Wang, Jian J 
mailto:jian.j.w...@intel.com>>; Gao, Liming 
mailto:gaolim...@byosoft.com.cn>>; Bi, Dandan 
mailto:dandan...@intel.com>>; Ni, Ray 
mailto:ray...@intel.com>>
Subject: [PATCH 1/1] MdeModulePkg: Optimize 
CoreInstallMultipleProtocolInterfaces

CoreLocateDevicePath is used in CoreInstallMultipleProtocolInterfaces to
check if a Device Path Protocol instance with the same device path is
alreay installed.
CoreLocateDevicePath is a generic API, and would introduce some
unnecessary overhead for such usage.

The optimization is:
1. Implement IsDevicePathInstalled to loop all the Device Path
   Protocols installed and check if any of them matchs the given device
   path.
2. Replace CoreLocateDevicePath with IsDevicePathInstalled in
   CoreInstallMultipleProtocolInterfaces.

This optimization could save several seconds in PCI enumeration on a
system with many PCI devices.

Cc: Jian J Wang mailto:jian.j.w...@intel.com>>
Cc: Liming Gao mailto:gaolim...@byosoft.com.cn>>
Cc: Dandan Bi mailto:dandan...@intel.com>>
Cc: Ray Ni mailto:ray...@intel.com>>
Signed-off-by: Zhi Jin mailto:zhi@intel.com>>
---
 MdeModulePkg/Core/Dxe/Hand/Handle.c | 74 +
 1 file changed, 64 insertions(+), 10 deletions(-)

diff --git a/MdeModulePkg/Core/Dxe/Hand/Handle.c 
b/MdeModulePkg/Core/Dxe/Hand/Handle.c
index bd6c57843e..a08cf19bfd 100644
--- a/MdeModulePkg/Core/Dxe/Hand/Handle.c
+++ b/MdeModulePkg/Core/Dxe/Hand/Handle.c
@@ -197,6 +197,66 @@ CoreFindProtocolInterface (
   return Prot;
 }

+/**
+  Check if the given device path is already installed
+
+  @param  DevicePathThe given device path
+
+  @retval TRUE  The device path is already installed
+  @retval FALSE The device path is not installed
+
+**/
+BOOLEAN
+IsDevicePathInstalled (
+  IN EFI_DEVICE_PATH_PROTOCOL  *DevicePath
+  )
+{
+  UINTN SourceSize;
+  UINTN Size;
+  BOOLEAN   Found;
+  LIST_ENTRY*Link;
+  PROTOCOL_ENTRY*ProtEntry;
+  PROTOCOL_INTERFACE*Prot;
+
+  if (DevicePath == NULL) {
+return FALSE;
+  }
+
+  Found = FALSE;
+  SourceSize= GetDevicePathSize (DevicePath);
+  ASSERT (SourceSize >= END_DEVICE_PATH_LENGTH);
+
+  CoreAcquireProtocolLock ();
+  //
+  // Look up the protocol entry
+  //
+  ProtEntry = CoreFindProtocolEntry (, FALSE);
+  if (ProtEntry == NULL) {
+goto Done;
+  }
+
+  for (Link = ProtEntry->Protocols.ForwardLink; Link != >Protocols; 
Link = Link->ForwardLink) {
+//
+// Loop on the DevicePathProtocol interfaces
+//
+Prot = CR (Link, PROTOCOL_INTERFACE, ByProtocol, 
PROTOCOL_INTERFACE_SIGNATURE);
+
+//
+// Check if DevicePath is same as this interface
+//
+Size = GetDevicePathSize (Prot->Interface);
+ASSERT (Size >= END_DEVICE_PATH_LENGTH);
+if ((Size == SourceSize) && (CompareMem (DevicePath, Prot->Interface, Size 
- END_DEVICE_PATH_LENGTH) == 0)) {
+  Found = TRUE;
+  break;
+}
+  }
+
+Done:
+  CoreReleaseProtocolLock ();
+  return Found;
+}
+
 /**
   Removes an event from a register protocol notify list on a protocol.

@@ -517,8 +577,6 @@ CoreInstallMultipleProtocolInterfaces (
   EFI_TPL   OldTpl;
   UINTN Index;
   EFI_HANDLEOldHandle;
-  EFI_HANDLEDeviceHandle;
-  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;

   if (Handle == NULL) {
 return EFI_INVALID_PARAMETER;
@@ -548,14 +606,10 @@ CoreInstallMultipleProtocolInterfaces (
 //
 // Make sure you are installing on top a device path that has already been 
added.
 //
-if (CompareGuid (Protocol, )) {
-  DeviceHandle = NULL;
-  DevicePath   = Interface;
-  Status   = CoreLocateDevicePath (, 
, );
-  if (!EFI_ERROR (Status) && (DeviceHandle != NULL) && IsDevicePathEnd 
(DevicePath)) {
-Status = EFI_ALREADY_STARTED;
-continue;
-  }
+if (CompareGuid (Protocol, ) &&
+IsDevicePathInstalled (Interface)) {
+  Status = EFI_ALREADY_STARTED;
+  continue;
 }

 //
--
2.39.2


-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive al

[edk2-devel] [PATCH 1/1] MdeModulePkg: Optimize CoreInstallMultipleProtocolInterfaces

2023-11-08 Thread Zhi Jin
CoreLocateDevicePath is used in CoreInstallMultipleProtocolInterfaces to
check if a Device Path Protocol instance with the same device path is
alreay installed.
CoreLocateDevicePath is a generic API, and would introduce some
unnecessary overhead for such usage.

The optimization is:
1. Implement IsDevicePathInstalled to loop all the Device Path
   Protocols installed and check if any of them matchs the given device
   path.
2. Replace CoreLocateDevicePath with IsDevicePathInstalled in
   CoreInstallMultipleProtocolInterfaces.

This optimization could save several seconds in PCI enumeration on a
system with many PCI devices.

Cc: Jian J Wang 
Cc: Liming Gao 
Cc: Dandan Bi 
Cc: Ray Ni 
Signed-off-by: Zhi Jin 
---
 MdeModulePkg/Core/Dxe/Hand/Handle.c | 74 +
 1 file changed, 64 insertions(+), 10 deletions(-)

diff --git a/MdeModulePkg/Core/Dxe/Hand/Handle.c 
b/MdeModulePkg/Core/Dxe/Hand/Handle.c
index bd6c57843e..a08cf19bfd 100644
--- a/MdeModulePkg/Core/Dxe/Hand/Handle.c
+++ b/MdeModulePkg/Core/Dxe/Hand/Handle.c
@@ -197,6 +197,66 @@ CoreFindProtocolInterface (
   return Prot;
 }
 
+/**
+  Check if the given device path is already installed
+
+  @param  DevicePathThe given device path
+
+  @retval TRUE  The device path is already installed
+  @retval FALSE The device path is not installed
+
+**/
+BOOLEAN
+IsDevicePathInstalled (
+  IN EFI_DEVICE_PATH_PROTOCOL  *DevicePath
+  )
+{
+  UINTN SourceSize;
+  UINTN Size;
+  BOOLEAN   Found;
+  LIST_ENTRY*Link;
+  PROTOCOL_ENTRY*ProtEntry;
+  PROTOCOL_INTERFACE*Prot;
+
+  if (DevicePath == NULL) {
+return FALSE;
+  }
+
+  Found = FALSE;
+  SourceSize= GetDevicePathSize (DevicePath);
+  ASSERT (SourceSize >= END_DEVICE_PATH_LENGTH);
+
+  CoreAcquireProtocolLock ();
+  //
+  // Look up the protocol entry
+  //
+  ProtEntry = CoreFindProtocolEntry (, FALSE);
+  if (ProtEntry == NULL) {
+goto Done;
+  }
+
+  for (Link = ProtEntry->Protocols.ForwardLink; Link != >Protocols; 
Link = Link->ForwardLink) {
+//
+// Loop on the DevicePathProtocol interfaces
+//
+Prot = CR (Link, PROTOCOL_INTERFACE, ByProtocol, 
PROTOCOL_INTERFACE_SIGNATURE);
+
+//
+// Check if DevicePath is same as this interface
+//
+Size = GetDevicePathSize (Prot->Interface);
+ASSERT (Size >= END_DEVICE_PATH_LENGTH);
+if ((Size == SourceSize) && (CompareMem (DevicePath, Prot->Interface, Size 
- END_DEVICE_PATH_LENGTH) == 0)) {
+  Found = TRUE;
+  break;
+}
+  }
+
+Done:
+  CoreReleaseProtocolLock ();
+  return Found;
+}
+
 /**
   Removes an event from a register protocol notify list on a protocol.
 
@@ -517,8 +577,6 @@ CoreInstallMultipleProtocolInterfaces (
   EFI_TPL   OldTpl;
   UINTN Index;
   EFI_HANDLEOldHandle;
-  EFI_HANDLEDeviceHandle;
-  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
 
   if (Handle == NULL) {
 return EFI_INVALID_PARAMETER;
@@ -548,14 +606,10 @@ CoreInstallMultipleProtocolInterfaces (
 //
 // Make sure you are installing on top a device path that has already been 
added.
 //
-if (CompareGuid (Protocol, )) {
-  DeviceHandle = NULL;
-  DevicePath   = Interface;
-  Status   = CoreLocateDevicePath (, 
, );
-  if (!EFI_ERROR (Status) && (DeviceHandle != NULL) && IsDevicePathEnd 
(DevicePath)) {
-Status = EFI_ALREADY_STARTED;
-continue;
-  }
+if (CompareGuid (Protocol, ) &&
+IsDevicePathInstalled (Interface)) {
+  Status = EFI_ALREADY_STARTED;
+  continue;
 }
 
 //
-- 
2.39.2



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#110945): https://edk2.groups.io/g/devel/message/110945
Mute This Topic: https://groups.io/mt/102478834/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-