Skip to content

Commit 4a68176

Browse files
zhihaoli1064mergify[bot]
authored andcommitted
UefiCpuPkg: Extend SMM CPU Service with rendezvous support.
REF? https://bugzilla.tianocore.org/show_bug.cgi?id=3815 This patch define a new Protocol with the new services SmmWaitForAllProcessor(), which can be used by SMI handler to optionally wait for other APs to complete SMM rendezvous in relaxed AP mode. A new library SmmCpuRendezvousLib is provided to abstract the service into library API to simple SMI handler code. Cc: Eric Dong <eric.dong@intel.com> Reviewed-by: Ray Ni <ray.ni@intel.com> Cc: Rahul Kumar <rahul1.kumar@intel.com> Cc: Siyuan Fu <siyuan.fu@intel.com> Cc: Zhihao Li <zhihao.li@intel.com> Signed-off-by: Zhihao Li <zhihao.li@intel.com>
1 parent b83d0a6 commit 4a68176

File tree

10 files changed

+322
-12
lines changed

10 files changed

+322
-12
lines changed
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/** @file
2+
SMM CPU Rendezvous library header file.
3+
4+
Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
5+
SPDX-License-Identifier: BSD-2-Clause-Patent
6+
7+
**/
8+
9+
#ifndef SMM_CPU_RENDEZVOUS_H_
10+
#define SMM_CPU_RENDEZVOUS_H_
11+
12+
/**
13+
This routine wait for all AP processors to arrive in SMM.
14+
15+
@param[in] BlockingMode Blocking mode or non-blocking mode.
16+
17+
@retval EFI_SUCCESS All processors checked in to SMM.
18+
@retval EFI_TIMEOUT Wait for all APs until timeout.
19+
20+
**/
21+
EFI_STATUS
22+
EFIAPI
23+
SmmWaitForAllProcessor (
24+
IN BOOLEAN BlockingMode
25+
);
26+
27+
#endif

UefiCpuPkg/Include/Protocol/SmmCpuService.h

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/** @file
22
SMM CPU Service protocol definition.
33
4-
Copyright (c) 2013 - 2015, Intel Corporation. All rights reserved.<BR>
4+
Copyright (c) 2013 - 2022, Intel Corporation. All rights reserved.<BR>
55
SPDX-License-Identifier: BSD-2-Clause-Patent
66
77
**/
@@ -200,4 +200,38 @@ struct _EFI_SMM_CPU_SERVICE_PROTOCOL {
200200

201201
extern EFI_GUID gEfiSmmCpuServiceProtocolGuid;
202202

203+
//
204+
// EDKII_SMM_CPU_RENDEZVOUS_PROTOCOL provide SMM CPU
205+
// rendezvous service support.
206+
//
207+
#define EDKII_SMM_CPU_RENDEZVOUS_PROTOCOL_GUID \
208+
{ \
209+
0xaa00d50b, 0x4911, 0x428f, { 0xb9, 0x1a, 0xa5, 0x9d, 0xdb, 0x13, 0xe2, 0x4c } \
210+
}
211+
212+
typedef struct _EDKII_SMM_CPU_RENDEZVOUS_PROTOCOL EDKII_SMM_CPU_RENDEZVOUS_PROTOCOL;
213+
214+
/**
215+
Wait for all APs to arrive SMM mode in given timeout constraint.
216+
217+
@param[in] This A pointer to the EDKII_SMM_CPU_RENDEZVOUS_PROTOCOL instance.
218+
@param[in] BlockingMode Block or non-block mode.
219+
220+
@retval EFI_SUCCESS All APs have arrived SMM mode except SMI disabled APs.
221+
@retval EFI_TIMEOUT There are APs not in SMM mode in given timeout constraint.
222+
223+
**/
224+
typedef
225+
EFI_STATUS
226+
(EFIAPI *EDKII_WAIT_FOR_ALL_PROCESSOR)(
227+
IN EDKII_SMM_CPU_RENDEZVOUS_PROTOCOL *This,
228+
IN BOOLEAN BlockingMode
229+
);
230+
231+
struct _EDKII_SMM_CPU_RENDEZVOUS_PROTOCOL {
232+
EDKII_WAIT_FOR_ALL_PROCESSOR WaitForAllProcessor;
233+
};
234+
235+
extern EFI_GUID gEdkiiSmmCpuRendezvousProtocolGuid;
236+
203237
#endif
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
/** @file
2+
SMM CPU Rendezvous sevice implement.
3+
4+
Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
5+
SPDX-License-Identifier: BSD-2-Clause-Patent
6+
7+
**/
8+
9+
#include <Base.h>
10+
#include <Uefi.h>
11+
#include <Library/BaseLib.h>
12+
#include <Library/DebugLib.h>
13+
#include <Library/MmServicesTableLib.h>
14+
#include <Protocol/SmmCpuService.h>
15+
#include <Library/SmmCpuRendezvousLib.h>
16+
17+
STATIC EDKII_SMM_CPU_RENDEZVOUS_PROTOCOL *mSmmCpuRendezvous = NULL;
18+
STATIC VOID *mRegistration = NULL;
19+
20+
/**
21+
Callback function to wait Smm cpu rendezvous service located.
22+
23+
SmmCpuRendezvousLib need to support MM_STANDALONE and DXE_SMM_DRIVER driver.
24+
So do not use library constructor to locate the protocol.
25+
26+
@param[in] Protocol Points to the protocol's unique identifier.
27+
@param[in] Interface Points to the interface instance.
28+
@param[in] Handle The handle on which the interface was installed.
29+
30+
@retval EFI_SUCCESS Notification runs successfully.
31+
32+
**/
33+
EFI_STATUS
34+
EFIAPI
35+
SmmCpuRendezvousProtocolNotify (
36+
IN CONST EFI_GUID *Protocol,
37+
IN VOID *Interface,
38+
IN EFI_HANDLE Handle
39+
)
40+
{
41+
EFI_STATUS Status;
42+
43+
Status = gMmst->MmLocateProtocol (
44+
&gEdkiiSmmCpuRendezvousProtocolGuid,
45+
NULL,
46+
(VOID **)&mSmmCpuRendezvous
47+
);
48+
ASSERT_EFI_ERROR (Status);
49+
50+
return EFI_SUCCESS;
51+
}
52+
53+
/**
54+
This routine wait for all AP processors to arrive in SMM.
55+
56+
@param[in] BlockingMode Blocking mode or non-blocking mode.
57+
58+
@retval EFI_SUCCESS All avaiable APs arrived.
59+
@retval EFI_TIMEOUT Wait for all APs until timeout.
60+
@retval OTHER Fail to register SMM CPU Rendezvous service Protocol.
61+
**/
62+
EFI_STATUS
63+
EFIAPI
64+
SmmWaitForAllProcessor (
65+
IN BOOLEAN BlockingMode
66+
)
67+
{
68+
EFI_STATUS Status;
69+
70+
if ((mRegistration == NULL) && (mSmmCpuRendezvous == NULL)) {
71+
//
72+
// Locate SMM cpu rendezvous protocol for the first time execute the function.
73+
//
74+
Status = gMmst->MmLocateProtocol (
75+
&gEdkiiSmmCpuRendezvousProtocolGuid,
76+
NULL,
77+
(VOID **)&mSmmCpuRendezvous
78+
);
79+
if (EFI_ERROR (Status)) {
80+
Status = gMmst->MmRegisterProtocolNotify (
81+
&gEdkiiSmmCpuRendezvousProtocolGuid,
82+
SmmCpuRendezvousProtocolNotify,
83+
&mRegistration
84+
);
85+
if (EFI_ERROR (Status)) {
86+
return Status;
87+
}
88+
}
89+
}
90+
91+
//
92+
// The platform have not set up. It doesn't need smm cpu rendezvous.
93+
//
94+
if (mSmmCpuRendezvous == NULL) {
95+
return EFI_SUCCESS;
96+
}
97+
98+
Status = mSmmCpuRendezvous->WaitForAllProcessor (
99+
mSmmCpuRendezvous,
100+
BlockingMode
101+
);
102+
return Status;
103+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
## @file
2+
# SMM CPU Rendezvous service lib.
3+
#
4+
# This is SMM CPU rendezvous service lib that wait for all
5+
# APs to enter SMM mode.
6+
#
7+
# Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
8+
# SPDX-License-Identifier: BSD-2-Clause-Patent
9+
#
10+
##
11+
12+
[Defines]
13+
INF_VERSION = 0x00010005
14+
BASE_NAME = SmmCpuRendezvousLib
15+
FILE_GUID = 1509Bb36-9Ba4-438B-B195-Ac5914Db14E2
16+
MODULE_TYPE = DXE_SMM_DRIVER
17+
LIBRARY_CLASS = SmmCpuRendezvousLib|MM_STANDALONE DXE_SMM_DRIVER
18+
19+
[Sources]
20+
SmmCpuRendezvousLib.c
21+
22+
[Packages]
23+
MdePkg/MdePkg.dec
24+
UefiCpuPkg/UefiCpuPkg.dec
25+
26+
[LibraryClasses]
27+
BaseLib
28+
DebugLib
29+
MmServicesTableLib
30+
31+
[Pcd]
32+
gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmApSyncTimeout ## CONSUMES
33+
34+
[Protocols]
35+
gEdkiiSmmCpuRendezvousProtocolGuid

UefiCpuPkg/PiSmmCpuDxeSmm/CpuService.c

Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/** @file
22
Implementation of SMM CPU Services Protocol.
33
4-
Copyright (c) 2011 - 2015, Intel Corporation. All rights reserved.<BR>
4+
Copyright (c) 2011 - 2022, Intel Corporation. All rights reserved.<BR>
55
SPDX-License-Identifier: BSD-2-Clause-Patent
66
77
**/
@@ -20,6 +20,13 @@ EFI_SMM_CPU_SERVICE_PROTOCOL mSmmCpuService = {
2020
SmmRegisterExceptionHandler
2121
};
2222

23+
//
24+
// EDKII SMM CPU Rendezvous Service Protocol instance
25+
//
26+
EDKII_SMM_CPU_RENDEZVOUS_PROTOCOL mSmmCpuRendezvousService = {
27+
SmmCpuRendezvous
28+
};
29+
2330
/**
2431
Gets processor information on the requested processor at the instant this call is made.
2532
@@ -350,6 +357,7 @@ SmmRegisterExceptionHandler (
350357
@param ImageHandle The firmware allocated handle for the EFI image.
351358
352359
@retval EFI_SUCCESS EFI SMM CPU Services Protocol was installed successfully.
360+
@retval OTHER Fail to install Protocol.
353361
**/
354362
EFI_STATUS
355363
InitializeSmmCpuServices (
@@ -365,5 +373,64 @@ InitializeSmmCpuServices (
365373
&mSmmCpuService
366374
);
367375
ASSERT_EFI_ERROR (Status);
376+
if (EFI_ERROR (Status)) {
377+
return Status;
378+
}
379+
380+
Status = gSmst->SmmInstallProtocolInterface (
381+
&Handle,
382+
&gEdkiiSmmCpuRendezvousProtocolGuid,
383+
EFI_NATIVE_INTERFACE,
384+
&mSmmCpuRendezvousService
385+
);
386+
ASSERT_EFI_ERROR (Status);
387+
return Status;
388+
}
389+
390+
/**
391+
Wait for all processors enterring SMM until all CPUs are already synchronized or not.
392+
393+
If BlockingMode is False, timeout value is zero.
394+
395+
@param This A pointer to the EDKII_SMM_CPU_RENDEZVOUS_PROTOCOL instance.
396+
@param BlockingMode Blocking mode or non-blocking mode.
397+
398+
@retval EFI_SUCCESS All avaiable APs arrived.
399+
@retval EFI_TIMEOUT Wait for all APs until timeout.
400+
401+
**/
402+
EFI_STATUS
403+
EFIAPI
404+
SmmCpuRendezvous (
405+
IN EDKII_SMM_CPU_RENDEZVOUS_PROTOCOL *This,
406+
IN BOOLEAN BlockingMode
407+
)
408+
{
409+
EFI_STATUS Status;
410+
411+
//
412+
// Return success immediately if all CPUs are already synchronized.
413+
//
414+
if (mSmmMpSyncData->AllApArrivedWithException) {
415+
Status = EFI_SUCCESS;
416+
goto ON_EXIT;
417+
}
418+
419+
if (!BlockingMode) {
420+
Status = EFI_TIMEOUT;
421+
goto ON_EXIT;
422+
}
423+
424+
//
425+
// There are some APs outside SMM, Wait for all avaiable APs to arrive.
426+
//
427+
SmmWaitForApArrival ();
428+
Status = mSmmMpSyncData->AllApArrivedWithException ? EFI_SUCCESS : EFI_TIMEOUT;
429+
430+
ON_EXIT:
431+
if (!mSmmMpSyncData->AllApArrivedWithException) {
432+
DEBUG ((DEBUG_INFO, "EdkiiSmmWaitForAllApArrival: Timeout to wait all APs arrival\n"));
433+
}
434+
368435
return Status;
369436
}

UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/** @file
22
SMM MP service implementation
33
4-
Copyright (c) 2009 - 2021, Intel Corporation. All rights reserved.<BR>
4+
Copyright (c) 2009 - 2022, Intel Corporation. All rights reserved.<BR>
55
Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR>
66
77
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -293,10 +293,14 @@ SmmWaitForApArrival (
293293
// Sync with APs 1st timeout
294294
//
295295
for (Timer = StartSyncTimer ();
296-
!IsSyncTimerTimeout (Timer) && !(LmceEn && LmceSignal) &&
297-
!AllCpusInSmmWithExceptions (ARRIVAL_EXCEPTION_BLOCKED | ARRIVAL_EXCEPTION_SMI_DISABLED);
296+
!IsSyncTimerTimeout (Timer) && !(LmceEn && LmceSignal);
298297
)
299298
{
299+
mSmmMpSyncData->AllApArrivedWithException = AllCpusInSmmWithExceptions (ARRIVAL_EXCEPTION_BLOCKED | ARRIVAL_EXCEPTION_SMI_DISABLED);
300+
if (mSmmMpSyncData->AllApArrivedWithException) {
301+
break;
302+
}
303+
300304
CpuPause ();
301305
}
302306

@@ -330,10 +334,14 @@ SmmWaitForApArrival (
330334
// Sync with APs 2nd timeout.
331335
//
332336
for (Timer = StartSyncTimer ();
333-
!IsSyncTimerTimeout (Timer) &&
334-
!AllCpusInSmmWithExceptions (ARRIVAL_EXCEPTION_BLOCKED | ARRIVAL_EXCEPTION_SMI_DISABLED);
337+
!IsSyncTimerTimeout (Timer);
335338
)
336339
{
340+
mSmmMpSyncData->AllApArrivedWithException = AllCpusInSmmWithExceptions (ARRIVAL_EXCEPTION_BLOCKED | ARRIVAL_EXCEPTION_SMI_DISABLED);
341+
if (mSmmMpSyncData->AllApArrivedWithException) {
342+
break;
343+
}
344+
337345
CpuPause ();
338346
}
339347
}
@@ -1887,6 +1895,8 @@ InitializeMpSyncData (
18871895
*mSmmMpSyncData->InsideSmm = FALSE;
18881896
*mSmmMpSyncData->AllCpusInSync = FALSE;
18891897

1898+
mSmmMpSyncData->AllApArrivedWithException = FALSE;
1899+
18901900
for (CpuIndex = 0; CpuIndex < gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus; CpuIndex++) {
18911901
mSmmMpSyncData->CpuData[CpuIndex].Busy =
18921902
(SPIN_LOCK *)((UINTN)mSmmCpuSemaphores.SemaphoreCpu.Busy + mSemaphoreSize * CpuIndex);

0 commit comments

Comments
 (0)