X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=UefiCpuPkg%2FPiSmmCpuDxeSmm%2FCpuService.c;fp=UefiCpuPkg%2FPiSmmCpuDxeSmm%2FCpuService.c;h=2ebf4543c3ed75c043b58c58532d3604c509cf2e;hp=5d624f8e9ed65b47fe2f1c43b1794e8d0e4d7564;hb=4a68176cb548902cad93e6ebb5957d0cac94d297;hpb=b83d0a6438f24ba3c6234d9b7593be6f2246ec1e diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/CpuService.c b/UefiCpuPkg/PiSmmCpuDxeSmm/CpuService.c index 5d624f8e9e..2ebf4543c3 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/CpuService.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/CpuService.c @@ -1,7 +1,7 @@ /** @file Implementation of SMM CPU Services Protocol. -Copyright (c) 2011 - 2015, Intel Corporation. All rights reserved.
+Copyright (c) 2011 - 2022, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -20,6 +20,13 @@ EFI_SMM_CPU_SERVICE_PROTOCOL mSmmCpuService = { SmmRegisterExceptionHandler }; +// +// EDKII SMM CPU Rendezvous Service Protocol instance +// +EDKII_SMM_CPU_RENDEZVOUS_PROTOCOL mSmmCpuRendezvousService = { + SmmCpuRendezvous +}; + /** Gets processor information on the requested processor at the instant this call is made. @@ -350,6 +357,7 @@ SmmRegisterExceptionHandler ( @param ImageHandle The firmware allocated handle for the EFI image. @retval EFI_SUCCESS EFI SMM CPU Services Protocol was installed successfully. + @retval OTHER Fail to install Protocol. **/ EFI_STATUS InitializeSmmCpuServices ( @@ -365,5 +373,64 @@ InitializeSmmCpuServices ( &mSmmCpuService ); ASSERT_EFI_ERROR (Status); + if (EFI_ERROR (Status)) { + return Status; + } + + Status = gSmst->SmmInstallProtocolInterface ( + &Handle, + &gEdkiiSmmCpuRendezvousProtocolGuid, + EFI_NATIVE_INTERFACE, + &mSmmCpuRendezvousService + ); + ASSERT_EFI_ERROR (Status); + return Status; +} + +/** + Wait for all processors enterring SMM until all CPUs are already synchronized or not. + + If BlockingMode is False, timeout value is zero. + + @param This A pointer to the EDKII_SMM_CPU_RENDEZVOUS_PROTOCOL instance. + @param BlockingMode Blocking mode or non-blocking mode. + + @retval EFI_SUCCESS All avaiable APs arrived. + @retval EFI_TIMEOUT Wait for all APs until timeout. + +**/ +EFI_STATUS +EFIAPI +SmmCpuRendezvous ( + IN EDKII_SMM_CPU_RENDEZVOUS_PROTOCOL *This, + IN BOOLEAN BlockingMode + ) +{ + EFI_STATUS Status; + + // + // Return success immediately if all CPUs are already synchronized. + // + if (mSmmMpSyncData->AllApArrivedWithException) { + Status = EFI_SUCCESS; + goto ON_EXIT; + } + + if (!BlockingMode) { + Status = EFI_TIMEOUT; + goto ON_EXIT; + } + + // + // There are some APs outside SMM, Wait for all avaiable APs to arrive. + // + SmmWaitForApArrival (); + Status = mSmmMpSyncData->AllApArrivedWithException ? EFI_SUCCESS : EFI_TIMEOUT; + +ON_EXIT: + if (!mSmmMpSyncData->AllApArrivedWithException) { + DEBUG ((DEBUG_INFO, "EdkiiSmmWaitForAllApArrival: Timeout to wait all APs arrival\n")); + } + return Status; }