[edk2-devel] [PATCH v2 2/2] MdeModulePkg: Optimize CoreConnectSingleController
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
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
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
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
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
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
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
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
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] -=-=-=-=-=-=-=-=-=-=-=-