From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by spool.mail.gandi.net (Postfix) with ESMTPS id BF69A9413C7 for ; Tue, 19 Dec 2023 09:34:41 +0000 (UTC) DKIM-Signature: a=rsa-sha256; bh=R5xgzhXVBkRxcYU5e+0DM82fxMkGbPA7Ze7iCp0QMYA=; c=relaxed/simple; d=groups.io; h=ARC-Seal:ARC-Message-Signature:ARC-Authentication-Results:From:To:CC:Subject:Thread-Topic:Thread-Index:Date:Message-ID:References:In-Reply-To:Accept-Language:MIME-Version:Precedence:List-Subscribe:List-Help:Sender:List-Id:Mailing-List:Delivered-To:Reply-To:List-Unsubscribe-Post:List-Unsubscribe:Content-Language:Content-Type:Content-Transfer-Encoding; s=20140610; t=1702978480; v=1; b=X2FhosklvQZOSA9Lb0CSaEAyqEW97Zn5/tiOa7JlNa0oqQpAF7/2HR0kG5FRUkY9E8/Cird3 NaS0s/FM/wwR1U5AnKSDH9CRLXtFImte0yrMccXm0qDToP/6BLzTFvI3ge8C/gDub1IZzi8L31Z 0mu+GSauG4odKgckQZd3QwvU= X-Received: by 127.0.0.2 with SMTP id LTTFYY7687511xmVFVgcJu5m; Tue, 19 Dec 2023 01:34:40 -0800 X-Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.13]) by mx.groups.io with SMTP id smtpd.web10.8671.1702978479650751259 for ; Tue, 19 Dec 2023 01:34:39 -0800 X-IronPort-AV: E=McAfee;i="6600,9927,10928"; a="2728510" X-IronPort-AV: E=Sophos;i="6.04,287,1695711600"; d="scan'208";a="2728510" X-Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by orvoesa105.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 19 Dec 2023 01:34:39 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10928"; a="894222107" X-IronPort-AV: E=Sophos;i="6.04,287,1695711600"; d="scan'208";a="894222107" X-Received: from orsmsx603.amr.corp.intel.com ([10.22.229.16]) by fmsmga002.fm.intel.com with ESMTP/TLS/AES256-GCM-SHA384; 19 Dec 2023 01:34:38 -0800 X-Received: from orsmsx611.amr.corp.intel.com (10.22.229.24) by ORSMSX603.amr.corp.intel.com (10.22.229.16) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.35; Tue, 19 Dec 2023 01:34:37 -0800 X-Received: from orsedg603.ED.cps.intel.com (10.7.248.4) by orsmsx611.amr.corp.intel.com (10.22.229.24) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.35 via Frontend Transport; Tue, 19 Dec 2023 01:34:37 -0800 X-Received: from NAM04-BN8-obe.outbound.protection.outlook.com (104.47.74.41) by edgegateway.intel.com (134.134.137.100) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.1.2507.35; Tue, 19 Dec 2023 01:34:36 -0800 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=gcEnNHvjwJKcFDtO0efq2cJ+5T7Os3IpeHLTzCgg4QXtGAFg7VuEw/J0lop0oK9m/FsgG6JuyuThkiKtwSrWwYJ7umsOpYpN/C/Cqy5JiYxBYDfDjgyS42DT4Za9aQmEeHsawBpsgMYDQf0z3Ecn8U/HmJxyMsDiZzVJDIwNPzbejGb/WR+lakoYF04nD4fUuIckQvy2X1I/5NfDH5k7xEoBq43VJ44gd0uudAVMSRHHZSQv3RLxkV2E7RtFaViESFqBC+3YN2C1BjApr7XpRybtrwjEw+9pwszlehLAIaEcJ5xWZem38N5dDbrIay5cEMwmre8/ZB9cG9CXcKBomQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=Hg9zBYt3pRDoZLj1X9kCQ8Qde5Y/1IXs/VfirBNtiOs=; b=ekL9IDeR/E6cxWS5yR3NqkIYniQ/6tU5ekCr9ekac5pN/UqNirwWElBy17K+DxiFS8OEbPotzORmrOeoIk5KuNjuqzMfrtW1bggm4Qw4Y3nHVuk4+0mR+ROQiNXzaWUe7wVPpxOsK2sMrI3Vt6RY2pfe1AFmXqZCsipNS6qBT2pzto/TU0kdmfE77qTzKQZrOIoRQNeD8uhLpPbbQFK3a5qUFfKSRFfAewyMm9VbCHNxxKrANs4Q8U0PuLJMXFADnakhqtcOghBBb2iU+jEVrSSViVbQp6JzuWCBOIOBNfBVVZY5hEHkm4X6f9CbIkMHlTuTGnOkgxrdTbOBpineIQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=intel.com; dmarc=pass action=none header.from=intel.com; dkim=pass header.d=intel.com; arc=none X-Received: from MN6PR11MB8244.namprd11.prod.outlook.com (2603:10b6:208:470::14) by PH8PR11MB6660.namprd11.prod.outlook.com (2603:10b6:510:1c3::13) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7091.38; Tue, 19 Dec 2023 09:34:28 +0000 X-Received: from MN6PR11MB8244.namprd11.prod.outlook.com ([fe80::b614:1f5e:8b0c:9858]) by MN6PR11MB8244.namprd11.prod.outlook.com ([fe80::b614:1f5e:8b0c:9858%4]) with mapi id 15.20.7091.034; Tue, 19 Dec 2023 09:34:28 +0000 From: "Ni, Ray" To: "Wu, Jiaxin" , "devel@edk2.groups.io" CC: Laszlo Ersek , "Dong, Eric" , "Zeng, Star" , Gerd Hoffmann , "Kumar, Rahul R" Subject: Re: [edk2-devel] [PATCH v5 4/8] UefiCpuPkg: Implements SmmCpuSyncLib library instance Thread-Topic: [PATCH v5 4/8] UefiCpuPkg: Implements SmmCpuSyncLib library instance Thread-Index: AQHaMkuiaUiBr0r1MEusjioEof0DmLCwWEqw Date: Tue, 19 Dec 2023 09:34:28 +0000 Message-ID: References: <20231219071839.4248-1-jiaxin.wu@intel.com> <20231219071839.4248-5-jiaxin.wu@intel.com> In-Reply-To: <20231219071839.4248-5-jiaxin.wu@intel.com> Accept-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-ms-publictraffictype: Email x-ms-traffictypediagnostic: MN6PR11MB8244:EE_|PH8PR11MB6660:EE_ x-ms-office365-filtering-correlation-id: bc2057b0-454a-4976-6335-08dc0075b276 x-ms-exchange-senderadcheck: 1 x-ms-exchange-antispam-relay: 0 x-microsoft-antispam-message-info: h61MMoMFEksBpyRii4wtMTdIU/enxoxg3RyJAAzA1Sy96OtzIjW9wKWv2AUcPsLekPskjyTJKuO2nMaK/gn8f1EkW+BtPuq6kOvQI6mwhTWMc18+O6SuHeX27CA3eZV0besqCYALunVQDf+63WjVBXiEPUKEdU4LG+ISakip9ZT3L8Zm/vOJEU1CIc4F0UatD53uOAXFhY0rdUDppz+aydHB9iFM3dstm220d6vDEodqsHmoOrJu3MPZx87WOu6VivNY9sBtl4OQbBqRFMZt3+AmNl3QgnK+jisQPk0LhM9ez9X0goXu+5xOaO7LXqMBb9lCqD0enuqKt2A1LQV6Dkm2rGr9NGbJe3qp49G+D4S5VXQXamQivZdRldW/pq2JSUMDsOAYUVfOrRt6mNj3cdU75SeKDn8s3fwLmc7zDpvJucKzTufMwHH70Lizh6fTpfAvbvEtEdIV4eVbVWtuRbC5SNJOG7D3nJIx+sPTROebUmkHJsfPA2qjq5GqrrJAxFvZuAeyyoylgp5wj8SysD9NPj3+MdZPrTxuuzaEwBejQuATFdGVtd4JWAM/i2eGDw2/7Divgx6b4FNNcSkWWYCCuf0dTLllQTBjbD1eRspmTWVJP7JAGXmDkcnW62NE x-ms-exchange-antispam-messagedata-chunkcount: 1 x-ms-exchange-antispam-messagedata-0: =?us-ascii?Q?W+JnfxFfnFbt4Eh5KvWMMR7FmUdefWwi0iOwyDTx0hbzXPRhXIQfeTlfzI2h?= =?us-ascii?Q?dPIE6uurLYwEFU2R4rRasPvnAzHktjIbDaR8QDqyYihKwlkxjDAADA3QGdWn?= =?us-ascii?Q?3whI44t0DJckZpvcLDyQ8PNU3/46q551YuOGnNmR1XeSNPkG+h0du7jagITH?= =?us-ascii?Q?yIICEtGu0UjTiON+ylMUlSwGcCl37D82wqrB1HODF+XK/oWb4wU/Y3aAl0v/?= =?us-ascii?Q?hcnE5XjOjRx7N5Hhjr8/oFD5U+U3rQPC4Nud4xXDFSvpRjM8fVdzjktRTIXq?= =?us-ascii?Q?sjfgp0JflaEzp9cAAAdMn3k4QiBuFuoRvLR2cAxbY4r5TAoKUj0DTdL43CoU?= =?us-ascii?Q?Cwwsle9JAi2NVtZaBC+ODKIAUBKZ/AJwK1FzYK6Mbp+kNTEbRLJhKFh6iGFJ?= =?us-ascii?Q?qt9554YsHtX7I2OleWEiNUNBSfV8LCwb19Y+xhb7iExu5Ah73enbWOvMvwh9?= =?us-ascii?Q?CvVHapCoy4epzYpwEb2emEBEcyhqBNu6LxzB45XinXhr2LhAy2rt8nmlDYCE?= =?us-ascii?Q?UXnVvwRzdhkgRrsIhmuKA8RRgWjMPKcnA+FU3P7tVA3WX0UqmOH1Zt02o15+?= =?us-ascii?Q?b5Hj/7aR4/pBTgGtpfIZyYdFXMTqPjCeX7pDZs2nOqxc4r4PtFfxIU/WkBtQ?= =?us-ascii?Q?3s4Hj5yYaBKhdi76nL+ZXHedY8Nvs18U+NvuRjvqOrStuy6zL685Vsm9vHAd?= =?us-ascii?Q?RdSfOsMW9qF373HSNdpzPTEXTAKYyDa9aR3xd9Yvl9hVOOPyhtCJEtgVXRcM?= =?us-ascii?Q?iRDi308UPh6x2QCWX+y6Fm2wmw/jIHkYx3wb0GQ0//SQFfesOmd7qzSIzwyR?= =?us-ascii?Q?JMTnxKESkJwHijruBKFyQz0rRU5QPKyug4KLoL/NuGMsCu5FLG91EvBJrE3w?= =?us-ascii?Q?w+w56WK0RdWh8CXb3vJMSxllKMVXjxj+t1CftsyV+qzLT3OzrJSzEu5EW6be?= =?us-ascii?Q?I9+hz2M+MihCeD8/bkU6l3qRLq6A/VbwQ3bPKshVVeVGlHiFpnzKfA3bJylu?= =?us-ascii?Q?zXL+suicpgTfeMlrlAvGcjIAYYnMF5MhK83UKtNYpT9OX4H6y2y2wQFSphR1?= =?us-ascii?Q?YqHRLt+YCcP2Pwf+PsaLFkZgyNd6gxGSdLBoMps4ZKYJ9BNdsrRJQF1ZlY0l?= =?us-ascii?Q?oQ+VcAuHUgJgPXSAOAiSaCt4rsmZcRHFAFUdWL5hweGnqN9Gy1xZF+2j2cev?= =?us-ascii?Q?iWxcB9fb6cHuA0zBfbAzNRpKHip77XfOEku8vTFu4Fzw5nmm3et8VTVkdhmS?= =?us-ascii?Q?FvucsBB7IRgzRu3P+LFOS0+5GChYrgD9nZBg68ZfazX+D93OlxplQhlw2XWb?= =?us-ascii?Q?3vYebn/Lv7OesRoTukL6JnVBVKOu3if/OkfoC945mSn5MLUUz7Z+3pzHyrI/?= =?us-ascii?Q?i93jj6MhkwT+vIjgiEV3RO4S8ElV+UBuLJyUvXzAjJ/N73WejrOR4KoR2fRD?= =?us-ascii?Q?inIkuPdCbkLLqM+H9jYuZdEgnsCZZ101VWgMlbddcSSg4nK8Q+ml8DgJxSkQ?= =?us-ascii?Q?YVcURjjCGBFguquvIBMXOgT17HIIBMEglOHobXCKuZaHc5cPC7YvdfqhNTOe?= =?us-ascii?Q?NNSbzflkNH2l1aEVJu0=3D?= MIME-Version: 1.0 X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-AuthSource: MN6PR11MB8244.namprd11.prod.outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: bc2057b0-454a-4976-6335-08dc0075b276 X-MS-Exchange-CrossTenant-originalarrivaltime: 19 Dec 2023 09:34:28.4623 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 46c98d88-e344-4ed4-8496-4ed7712e255d X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-MS-Exchange-CrossTenant-userprincipalname: L7maiEZp/XqS9iCNv0qFz/4mPo2b2KyNT43HaiVYXlAJ7FO2qW6yVN83wgYwtQCYqlz1SBLiLuo3afpdmoFdYw== X-MS-Exchange-Transport-CrossTenantHeadersStamped: PH8PR11MB6660 X-OriginatorOrg: intel.com Precedence: Bulk List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,ray.ni@intel.com List-Unsubscribe-Post: List-Unsubscribe=One-Click List-Unsubscribe: X-Gm-Message-State: WCHKxYuSo8KsEhIBJLx9UYqEx7686176AA= Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable X-GND-Status: LEGIT Authentication-Results: spool.mail.gandi.net; dkim=pass header.d=groups.io header.s=20140610 header.b=X2Fhoskl; dmarc=fail reason="SPF not aligned (relaxed), DKIM not aligned (relaxed)" header.from=intel.com (policy=none); spf=pass (spool.mail.gandi.net: domain of bounce@groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce@groups.io Reviewed-by: Ray Ni Thanks, Ray > -----Original Message----- > From: Wu, Jiaxin > Sent: Tuesday, December 19, 2023 3:19 PM > To: devel@edk2.groups.io > Cc: Laszlo Ersek ; Dong, Eric ; N= i, > Ray ; Zeng, Star ; Gerd Hoffmann > ; Kumar, Rahul R > Subject: [PATCH v5 4/8] UefiCpuPkg: Implements SmmCpuSyncLib library > instance >=20 > Implements SmmCpuSyncLib Library instance. The instance refers the > existing SMM CPU driver (PiSmmCpuDxeSmm) sync implementation > and behavior: > 1.Abstract Counter and Run semaphores into SmmCpuSyncCtx. > 2.Abstract CPU arrival count operation to > SmmCpuSyncGetArrivedCpuCount(), SmmCpuSyncCheckInCpu(), > SmmCpuSyncCheckOutCpu(), SmmCpuSyncLockDoor(). > Implementation is aligned with existing SMM CPU driver. > 3. Abstract SMM CPU Sync flow to: > BSP: SmmCpuSyncReleaseOneAp --> AP: SmmCpuSyncWaitForBsp > BSP: SmmCpuSyncWaitForAPs <-- AP: SmmCpuSyncReleaseBsp > Semaphores release & wait during sync flow is same as existing SMM > CPU driver. > 4.Same operation to Counter and Run semaphores by leverage the atomic > compare exchange. >=20 > Cc: Laszlo Ersek > Cc: Eric Dong > Cc: Ray Ni > Cc: Zeng Star > Cc: Gerd Hoffmann > Cc: Rahul Kumar > Signed-off-by: Jiaxin Wu > --- > UefiCpuPkg/Library/SmmCpuSyncLib/SmmCpuSyncLib.c | 652 > +++++++++++++++++++++ > UefiCpuPkg/Library/SmmCpuSyncLib/SmmCpuSyncLib.inf | 34 ++ > UefiCpuPkg/UefiCpuPkg.dsc | 2 + > 3 files changed, 688 insertions(+) > create mode 100644 > UefiCpuPkg/Library/SmmCpuSyncLib/SmmCpuSyncLib.c > create mode 100644 > UefiCpuPkg/Library/SmmCpuSyncLib/SmmCpuSyncLib.inf >=20 > diff --git a/UefiCpuPkg/Library/SmmCpuSyncLib/SmmCpuSyncLib.c > b/UefiCpuPkg/Library/SmmCpuSyncLib/SmmCpuSyncLib.c > new file mode 100644 > index 0000000000..d517d4b706 > --- /dev/null > +++ b/UefiCpuPkg/Library/SmmCpuSyncLib/SmmCpuSyncLib.c > @@ -0,0 +1,652 @@ > +/** @file > + SMM CPU Sync lib implementation. > + > + The lib provides 3 sets of APIs: > + 1. ContextInit/ContextDeinit/ContextReset: > + > + ContextInit() is called in driver's entrypoint to allocate and initi= alize the > SMM CPU Sync context. > + ContextDeinit() is called in driver's unload function to deinitializ= e the > SMM CPU Sync context. > + ContextReset() is called by one of CPUs after all CPUs are ready to = exit > SMI, which allows CPU to > + check into the next SMI from this point. > + > + 2. GetArrivedCpuCount/CheckInCpu/CheckOutCpu/LockDoor: > + When SMI happens, all processors including BSP enter to SMM mode by > calling CheckInCpu(). > + CheckOutCpu() can be called in error handling flow for the CPU who > calls CheckInCpu() earlier. > + The elected BSP calls LockDoor() so that CheckInCpu() and > CheckOutCpu() will return the error code after that. > + GetArrivedCpuCount() returns the number of checked-in CPUs. > + > + 3. WaitForAPs/ReleaseOneAp/WaitForBsp/ReleaseBsp > + WaitForAPs() & ReleaseOneAp() are called from BSP to wait the number > of APs and release one specific AP. > + WaitForBsp() & ReleaseBsp() are called from APs to wait and release > BSP. > + The 4 APIs are used to synchronize the running flow among BSP and > APs. > + BSP and AP Sync flow can be easy understand as below: > + BSP: ReleaseOneAp --> AP: WaitForBsp > + BSP: WaitForAPs <-- AP: ReleaseBsp > + > + Copyright (c) 2023, Intel Corporation. All rights reserved.
> + SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +/// > +/// The implementation shall place one semaphore on exclusive cache line > for good performance. > +/// > +typedef volatile UINT32 SMM_CPU_SYNC_SEMAPHORE; > + > +typedef struct { > + /// > + /// Used for control each CPU continue run or wait for signal > + /// > + SMM_CPU_SYNC_SEMAPHORE *Run; > +} SMM_CPU_SYNC_SEMAPHORE_FOR_EACH_CPU; > + > +struct SMM_CPU_SYNC_CONTEXT { > + /// > + /// Indicate all CPUs in the system. > + /// > + UINTN NumberOfCpus; > + /// > + /// Address of semaphores. > + /// > + VOID *SemBuffer; > + /// > + /// Size of semaphores. > + /// > + UINTN SemBufferPages; > + /// > + /// Before the door is locked, CpuCount stores the arrived CPU count. > + /// After the door is locked, CpuCount is set to -1 indicating the doo= r is > locked. > + /// ArrivedCpuCountUponLock stores the arrived CPU count then. > + /// > + UINTN > ArrivedCpuCountUponLock; > + /// > + /// Indicate CPUs entered SMM before lock door. > + /// > + SMM_CPU_SYNC_SEMAPHORE *CpuCount; > + /// > + /// Define an array of structure for each CPU semaphore due to the siz= e > alignment > + /// requirement. With the array of structure for each CPU semaphore, i= t's > easy to > + /// reach the specific CPU with CPU Index for its own semaphore access= : > CpuSem[CpuIndex]. > + /// > + SMM_CPU_SYNC_SEMAPHORE_FOR_EACH_CPU CpuSem[]; > +}; > + > +/** > + Performs an atomic compare exchange operation to get semaphore. > + The compare exchange operation must be performed using MP safe > + mechanisms. > + > + @param[in,out] Sem IN: 32-bit unsigned integer > + OUT: original integer - 1 if Sem is not locked. > + OUT: MAX_UINT32 if Sem is locked. > + > + @retval Original integer - 1 if Sem is not locked. > + MAX_UINT32 if Sem is locked. > + > +**/ > +STATIC > +UINT32 > +InternalWaitForSemaphore ( > + IN OUT volatile UINT32 *Sem > + ) > +{ > + UINT32 Value; > + > + for ( ; ;) { > + Value =3D *Sem; > + if (Value =3D=3D MAX_UINT32) { > + return Value; > + } > + > + if ((Value !=3D 0) && > + (InterlockedCompareExchange32 ( > + (UINT32 *)Sem, > + Value, > + Value - 1 > + ) =3D=3D Value)) > + { > + break; > + } > + > + CpuPause (); > + } > + > + return Value - 1; > +} > + > +/** > + Performs an atomic compare exchange operation to release semaphore. > + The compare exchange operation must be performed using MP safe > + mechanisms. > + > + @param[in,out] Sem IN: 32-bit unsigned integer > + OUT: original integer + 1 if Sem is not locked. > + OUT: MAX_UINT32 if Sem is locked. > + > + @retval Original integer + 1 if Sem is not locked. > + MAX_UINT32 if Sem is locked. > + > +**/ > +STATIC > +UINT32 > +InternalReleaseSemaphore ( > + IN OUT volatile UINT32 *Sem > + ) > +{ > + UINT32 Value; > + > + do { > + Value =3D *Sem; > + } while (Value + 1 !=3D 0 && > + InterlockedCompareExchange32 ( > + (UINT32 *)Sem, > + Value, > + Value + 1 > + ) !=3D Value); > + > + if (Value =3D=3D MAX_UINT32) { > + return Value; > + } > + > + return Value + 1; > +} > + > +/** > + Performs an atomic compare exchange operation to lock semaphore. > + The compare exchange operation must be performed using MP safe > + mechanisms. > + > + @param[in,out] Sem IN: 32-bit unsigned integer > + OUT: -1 > + > + @retval Original integer > + > +**/ > +STATIC > +UINT32 > +InternalLockdownSemaphore ( > + IN OUT volatile UINT32 *Sem > + ) > +{ > + UINT32 Value; > + > + do { > + Value =3D *Sem; > + } while (InterlockedCompareExchange32 ( > + (UINT32 *)Sem, > + Value, > + (UINT32)-1 > + ) !=3D Value); > + > + return Value; > +} > + > +/** > + Create and initialize the SMM CPU Sync context. It is to allocate and > initialize the > + SMM CPU Sync context. > + > + If Context is NULL, then ASSERT(). > + > + @param[in] NumberOfCpus The number of Logical > Processors in the system. > + @param[out] Context Pointer to the new created and > initialized SMM CPU Sync context object. > + NULL will be returned if any > error happen during init. > + > + @retval RETURN_SUCCESS The SMM CPU Sync context > was successful created and initialized. > + @retval RETURN_OUT_OF_RESOURCES There are not enough > resources available to create and initialize SMM CPU Sync context. > + @retval RETURN_BUFFER_TOO_SMALL Overflow happen > + > +**/ > +RETURN_STATUS > +EFIAPI > +SmmCpuSyncContextInit ( > + IN UINTN NumberOfCpus, > + OUT SMM_CPU_SYNC_CONTEXT **Context > + ) > +{ > + RETURN_STATUS Status; > + UINTN ContextSize; > + UINTN OneSemSize; > + UINTN NumSem; > + UINTN TotalSemSize; > + UINTN SemAddr; > + UINTN CpuIndex; > + SMM_CPU_SYNC_SEMAPHORE_FOR_EACH_CPU *CpuSem; > + > + ASSERT (Context !=3D NULL); > + > + // > + // Calculate ContextSize > + // > + Status =3D SafeUintnMult (NumberOfCpus, sizeof > (SMM_CPU_SYNC_SEMAPHORE_FOR_EACH_CPU), &ContextSize); > + if (RETURN_ERROR (Status)) { > + return Status; > + } > + > + Status =3D SafeUintnAdd (ContextSize, sizeof (SMM_CPU_SYNC_CONTEXT), > &ContextSize); > + if (RETURN_ERROR (Status)) { > + return Status; > + } > + > + // > + // Allocate Buffer for Context > + // > + *Context =3D AllocatePool (ContextSize); > + if (*Context =3D=3D NULL) { > + return RETURN_OUT_OF_RESOURCES; > + } > + > + (*Context)->ArrivedCpuCountUponLock =3D 0; > + > + // > + // Save NumberOfCpus > + // > + (*Context)->NumberOfCpus =3D NumberOfCpus; > + > + // > + // Calculate total semaphore size > + // > + OneSemSize =3D GetSpinLockProperties (); > + ASSERT (sizeof (SMM_CPU_SYNC_SEMAPHORE) <=3D OneSemSize); > + > + Status =3D SafeUintnAdd (1, NumberOfCpus, &NumSem); > + if (RETURN_ERROR (Status)) { > + goto ON_ERROR; > + } > + > + Status =3D SafeUintnMult (NumSem, OneSemSize, &TotalSemSize); > + if (RETURN_ERROR (Status)) { > + goto ON_ERROR; > + } > + > + // > + // Allocate for Semaphores in the *Context > + // > + (*Context)->SemBufferPages =3D EFI_SIZE_TO_PAGES (TotalSemSize); > + (*Context)->SemBuffer =3D AllocatePages > ((*Context)->SemBufferPages); > + if ((*Context)->SemBuffer =3D=3D NULL) { > + Status =3D RETURN_OUT_OF_RESOURCES; > + goto ON_ERROR; > + } > + > + // > + // Assign Global Semaphore pointer > + // > + SemAddr =3D (UINTN)(*Context)->SemBuffer; > + (*Context)->CpuCount =3D (SMM_CPU_SYNC_SEMAPHORE *)SemAddr; > + *(*Context)->CpuCount =3D 0; > + > + SemAddr +=3D OneSemSize; > + > + // > + // Assign CPU Semaphore pointer > + // > + CpuSem =3D (*Context)->CpuSem; > + for (CpuIndex =3D 0; CpuIndex < NumberOfCpus; CpuIndex++) { > + CpuSem->Run =3D (SMM_CPU_SYNC_SEMAPHORE *)SemAddr; > + *CpuSem->Run =3D 0; > + > + CpuSem++; > + SemAddr +=3D OneSemSize; > + } > + > + return RETURN_SUCCESS; > + > +ON_ERROR: > + FreePool (*Context); > + return Status; > +} > + > +/** > + Deinit an allocated SMM CPU Sync context. The resources allocated in > SmmCpuSyncContextInit() will > + be freed. > + > + If Context is NULL, then ASSERT(). > + > + @param[in,out] Context Pointer to the SMM CPU Sync context > object to be deinitialized. > + > +**/ > +VOID > +EFIAPI > +SmmCpuSyncContextDeinit ( > + IN OUT SMM_CPU_SYNC_CONTEXT *Context > + ) > +{ > + ASSERT (Context !=3D NULL); > + > + FreePages (Context->SemBuffer, Context->SemBufferPages); > + > + FreePool (Context); > +} > + > +/** > + Reset SMM CPU Sync context. SMM CPU Sync context will be reset to the > initialized state. > + > + This function is called by one of CPUs after all CPUs are ready to exi= t SMI, > which allows CPU to > + check into the next SMI from this point. > + > + If Context is NULL, then ASSERT(). > + > + @param[in,out] Context Pointer to the SMM CPU Sync context > object to be reset. > + > +**/ > +VOID > +EFIAPI > +SmmCpuSyncContextReset ( > + IN OUT SMM_CPU_SYNC_CONTEXT *Context > + ) > +{ > + ASSERT (Context !=3D NULL); > + > + Context->ArrivedCpuCountUponLock =3D 0; > + *Context->CpuCount =3D 0; > +} > + > +/** > + Get current number of arrived CPU in SMI. > + > + BSP might need to know the current number of arrived CPU in SMI to > make sure all APs > + in SMI. This API can be for that purpose. > + > + If Context is NULL, then ASSERT(). > + > + @param[in] Context Pointer to the SMM CPU Sync context > object. > + > + @retval Current number of arrived CPU in SMI. > + > +**/ > +UINTN > +EFIAPI > +SmmCpuSyncGetArrivedCpuCount ( > + IN SMM_CPU_SYNC_CONTEXT *Context > + ) > +{ > + UINT32 Value; > + > + ASSERT (Context !=3D NULL); > + > + Value =3D *Context->CpuCount; > + > + if (Value =3D=3D (UINT32)-1) { > + return Context->ArrivedCpuCountUponLock; > + } > + > + return Value; > +} > + > +/** > + Performs an atomic operation to check in CPU. > + > + When SMI happens, all processors including BSP enter to SMM mode by > calling SmmCpuSyncCheckInCpu(). > + > + If Context is NULL, then ASSERT(). > + If CpuIndex exceeds the range of all CPUs in the system, then ASSERT()= . > + > + @param[in,out] Context Pointer to the SMM CPU Sync > context object. > + @param[in] CpuIndex Check in CPU index. > + > + @retval RETURN_SUCCESS Check in CPU (CpuIndex) > successfully. > + @retval RETURN_ABORTED Check in CPU failed due to > SmmCpuSyncLockDoor() has been called by one elected CPU. > + > +**/ > +RETURN_STATUS > +EFIAPI > +SmmCpuSyncCheckInCpu ( > + IN OUT SMM_CPU_SYNC_CONTEXT *Context, > + IN UINTN CpuIndex > + ) > +{ > + ASSERT (Context !=3D NULL); > + > + ASSERT (CpuIndex < Context->NumberOfCpus); > + > + // > + // Check to return if CpuCount has already been locked. > + // > + if (InternalReleaseSemaphore (Context->CpuCount) =3D=3D MAX_UINT32) { > + return RETURN_ABORTED; > + } > + > + return RETURN_SUCCESS; > +} > + > +/** > + Performs an atomic operation to check out CPU. > + > + This function can be called in error handling flow for the CPU who cal= ls > CheckInCpu() earlier. > + The caller shall make sure the CPU specified by CpuIndex has already > checked-in. > + > + If Context is NULL, then ASSERT(). > + If CpuIndex exceeds the range of all CPUs in the system, then ASSERT()= . > + > + @param[in,out] Context Pointer to the SMM CPU Sync > context object. > + @param[in] CpuIndex Check out CPU index. > + > + @retval RETURN_SUCCESS Check out CPU (CpuIndex) > successfully. > + @retval RETURN_ABORTED Check out CPU failed due to > SmmCpuSyncLockDoor() has been called by one elected CPU. > + > +**/ > +RETURN_STATUS > +EFIAPI > +SmmCpuSyncCheckOutCpu ( > + IN OUT SMM_CPU_SYNC_CONTEXT *Context, > + IN UINTN CpuIndex > + ) > +{ > + ASSERT (Context !=3D NULL); > + > + ASSERT (CpuIndex < Context->NumberOfCpus); > + > + if (InternalWaitForSemaphore (Context->CpuCount) =3D=3D MAX_UINT32) { > + return RETURN_ABORTED; > + } > + > + return RETURN_SUCCESS; > +} > + > +/** > + Performs an atomic operation lock door for CPU checkin and checkout. > After this function: > + CPU can not check in via SmmCpuSyncCheckInCpu(). > + CPU can not check out via SmmCpuSyncCheckOutCpu(). > + > + The CPU specified by CpuIndex is elected to lock door. The caller shal= l > make sure the CpuIndex > + is the actual CPU calling this function to avoid the undefined behavio= r. > + > + If Context is NULL, then ASSERT(). > + If CpuCount is NULL, then ASSERT(). > + If CpuIndex exceeds the range of all CPUs in the system, then ASSERT()= . > + > + @param[in,out] Context Pointer to the SMM CPU Sync > context object. > + @param[in] CpuIndex Indicate which CPU to lock door. > + @param[out] CpuCount Number of arrived CPU in SMI > after look door. > + > +**/ > +VOID > +EFIAPI > +SmmCpuSyncLockDoor ( > + IN OUT SMM_CPU_SYNC_CONTEXT *Context, > + IN UINTN CpuIndex, > + OUT UINTN *CpuCount > + ) > +{ > + ASSERT (Context !=3D NULL); > + > + ASSERT (CpuCount !=3D NULL); > + > + ASSERT (CpuIndex < Context->NumberOfCpus); > + > + // > + // Temporarily record the CpuCount into the ArrivedCpuCountUponLock > before lock door. > + // Recording before lock door is to avoid the Context->CpuCount is loc= ked > but possible > + // Context->ArrivedCpuCountUponLock is not updated. > + // > + Context->ArrivedCpuCountUponLock =3D *Context->CpuCount; > + > + // > + // Lock door operation > + // > + *CpuCount =3D InternalLockdownSemaphore (Context->CpuCount); > + > + // > + // Update the ArrivedCpuCountUponLock > + // > + Context->ArrivedCpuCountUponLock =3D *CpuCount; > +} > + > +/** > + Used by the BSP to wait for APs. > + > + The number of APs need to be waited is specified by NumberOfAPs. The > BSP is specified by BspIndex. > + The caller shall make sure the BspIndex is the actual CPU calling this > function to avoid the undefined behavior. > + The caller shall make sure the NumberOfAPs have already checked-in to > avoid the undefined behavior. > + > + If Context is NULL, then ASSERT(). > + If NumberOfAPs >=3D All CPUs in system, then ASSERT(). > + If BspIndex exceeds the range of all CPUs in the system, then ASSERT()= . > + > + Note: > + This function is blocking mode, and it will return only after the numb= er of > APs released by > + calling SmmCpuSyncReleaseBsp(): > + BSP: WaitForAPs <-- AP: ReleaseBsp > + > + @param[in,out] Context Pointer to the SMM CPU Sync > context object. > + @param[in] NumberOfAPs Number of APs need to be > waited by BSP. > + @param[in] BspIndex The BSP Index to wait for APs. > + > +**/ > +VOID > +EFIAPI > +SmmCpuSyncWaitForAPs ( > + IN OUT SMM_CPU_SYNC_CONTEXT *Context, > + IN UINTN NumberOfAPs, > + IN UINTN BspIndex > + ) > +{ > + UINTN Arrived; > + > + ASSERT (Context !=3D NULL); > + > + ASSERT (NumberOfAPs < Context->NumberOfCpus); > + > + ASSERT (BspIndex < Context->NumberOfCpus); > + > + for (Arrived =3D 0; Arrived < NumberOfAPs; Arrived++) { > + InternalWaitForSemaphore (Context->CpuSem[BspIndex].Run); > + } > +} > + > +/** > + Used by the BSP to release one AP. > + > + The AP is specified by CpuIndex. The BSP is specified by BspIndex. > + The caller shall make sure the BspIndex is the actual CPU calling this > function to avoid the undefined behavior. > + The caller shall make sure the CpuIndex has already checked-in to avoi= d > the undefined behavior. > + > + If Context is NULL, then ASSERT(). > + If CpuIndex =3D=3D BspIndex, then ASSERT(). > + If BspIndex or CpuIndex exceed the range of all CPUs in the system, th= en > ASSERT(). > + > + @param[in,out] Context Pointer to the SMM CPU Sync > context object. > + @param[in] CpuIndex Indicate which AP need to be > released. > + @param[in] BspIndex The BSP Index to release AP. > + > +**/ > +VOID > +EFIAPI > +SmmCpuSyncReleaseOneAp ( > + IN OUT SMM_CPU_SYNC_CONTEXT *Context, > + IN UINTN CpuIndex, > + IN UINTN BspIndex > + ) > +{ > + ASSERT (Context !=3D NULL); > + > + ASSERT (BspIndex !=3D CpuIndex); > + > + ASSERT (CpuIndex < Context->NumberOfCpus); > + > + ASSERT (BspIndex < Context->NumberOfCpus); > + > + InternalReleaseSemaphore (Context->CpuSem[CpuIndex].Run); > +} > + > +/** > + Used by the AP to wait BSP. > + > + The AP is specified by CpuIndex. > + The caller shall make sure the CpuIndex is the actual CPU calling this > function to avoid the undefined behavior. > + The BSP is specified by BspIndex. > + > + If Context is NULL, then ASSERT(). > + If CpuIndex =3D=3D BspIndex, then ASSERT(). > + If BspIndex or CpuIndex exceed the range of all CPUs in the system, th= en > ASSERT(). > + > + Note: > + This function is blocking mode, and it will return only after the AP r= eleased > by > + calling SmmCpuSyncReleaseOneAp(): > + BSP: ReleaseOneAp --> AP: WaitForBsp > + > + @param[in,out] Context Pointer to the SMM CPU Sync > context object. > + @param[in] CpuIndex Indicate which AP wait BSP. > + @param[in] BspIndex The BSP Index to be waited. > + > +**/ > +VOID > +EFIAPI > +SmmCpuSyncWaitForBsp ( > + IN OUT SMM_CPU_SYNC_CONTEXT *Context, > + IN UINTN CpuIndex, > + IN UINTN BspIndex > + ) > +{ > + ASSERT (Context !=3D NULL); > + > + ASSERT (BspIndex !=3D CpuIndex); > + > + ASSERT (CpuIndex < Context->NumberOfCpus); > + > + ASSERT (BspIndex < Context->NumberOfCpus); > + > + InternalWaitForSemaphore (Context->CpuSem[CpuIndex].Run); > +} > + > +/** > + Used by the AP to release BSP. > + > + The AP is specified by CpuIndex. > + The caller shall make sure the CpuIndex is the actual CPU calling this > function to avoid the undefined behavior. > + The BSP is specified by BspIndex. > + > + If Context is NULL, then ASSERT(). > + If CpuIndex =3D=3D BspIndex, then ASSERT(). > + If BspIndex or CpuIndex exceed the range of all CPUs in the system, th= en > ASSERT(). > + > + @param[in,out] Context Pointer to the SMM CPU Sync > context object. > + @param[in] CpuIndex Indicate which AP release BSP. > + @param[in] BspIndex The BSP Index to be released. > + > +**/ > +VOID > +EFIAPI > +SmmCpuSyncReleaseBsp ( > + IN OUT SMM_CPU_SYNC_CONTEXT *Context, > + IN UINTN CpuIndex, > + IN UINTN BspIndex > + ) > +{ > + ASSERT (Context !=3D NULL); > + > + ASSERT (BspIndex !=3D CpuIndex); > + > + ASSERT (CpuIndex < Context->NumberOfCpus); > + > + ASSERT (BspIndex < Context->NumberOfCpus); > + > + InternalReleaseSemaphore (Context->CpuSem[BspIndex].Run); > +} > diff --git a/UefiCpuPkg/Library/SmmCpuSyncLib/SmmCpuSyncLib.inf > b/UefiCpuPkg/Library/SmmCpuSyncLib/SmmCpuSyncLib.inf > new file mode 100644 > index 0000000000..6b0d49c30a > --- /dev/null > +++ b/UefiCpuPkg/Library/SmmCpuSyncLib/SmmCpuSyncLib.inf > @@ -0,0 +1,34 @@ > +## @file > +# SMM CPU Synchronization lib. > +# > +# This is SMM CPU Synchronization lib used for SMM CPU sync operations. > +# > +# Copyright (c) 2023, Intel Corporation. All rights reserved.
> +# SPDX-License-Identifier: BSD-2-Clause-Patent > +# > +## > + > +[Defines] > + INF_VERSION =3D 0x00010005 > + BASE_NAME =3D SmmCpuSyncLib > + FILE_GUID =3D > 1ca1bc1a-16a4-46ef-956a-ca500fd3381f > + MODULE_TYPE =3D DXE_SMM_DRIVER > + LIBRARY_CLASS =3D > SmmCpuSyncLib|DXE_SMM_DRIVER > + > +[Sources] > + SmmCpuSyncLib.c > + > +[Packages] > + MdePkg/MdePkg.dec > + UefiCpuPkg/UefiCpuPkg.dec > + > +[LibraryClasses] > + BaseLib > + DebugLib > + MemoryAllocationLib > + SafeIntLib > + SynchronizationLib > + > +[Pcd] > + > +[Protocols] > diff --git a/UefiCpuPkg/UefiCpuPkg.dsc b/UefiCpuPkg/UefiCpuPkg.dsc > index 074fd77461..28eed85bce 100644 > --- a/UefiCpuPkg/UefiCpuPkg.dsc > +++ b/UefiCpuPkg/UefiCpuPkg.dsc > @@ -54,10 +54,11 @@ >=20 > CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCac > heMaintenanceLib.inf > PciLib|MdePkg/Library/BasePciLibPciExpress/BasePciLibPciExpress.inf > PciExpressLib|MdePkg/Library/BasePciExpressLib/BasePciExpressLib.inf >=20 > SmmCpuPlatformHookLib|UefiCpuPkg/Library/SmmCpuPlatformHookLibNull/ > SmmCpuPlatformHookLibNull.inf >=20 > SmmCpuFeaturesLib|UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeat > uresLib.inf > + > SmmCpuSyncLib|UefiCpuPkg/Library/SmmCpuSyncLib/SmmCpuSyncLib.inf >=20 > PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BaseP > eCoffGetEntryPointLib.inf >=20 > PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePe > CoffExtraActionLibNull.inf >=20 > TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/Tpm > MeasurementLibNull.inf > CcExitLib|UefiCpuPkg/Library/CcExitLibNull/CcExitLibNull.inf > MicrocodeLib|UefiCpuPkg/Library/MicrocodeLib/MicrocodeLib.inf > @@ -154,10 +155,11 @@ >=20 > UefiCpuPkg/Library/RegisterCpuFeaturesLib/DxeRegisterCpuFeaturesLib.inf >=20 > UefiCpuPkg/Library/SmmCpuPlatformHookLibNull/SmmCpuPlatformHookLib > Null.inf > UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.inf > UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLibStm.inf >=20 > UefiCpuPkg/Library/SmmCpuFeaturesLib/StandaloneMmCpuFeaturesLib.inf > + UefiCpuPkg/Library/SmmCpuSyncLib/SmmCpuSyncLib.inf > UefiCpuPkg/Library/CcExitLibNull/CcExitLibNull.inf > UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationPei.inf > UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationSmm.inf > UefiCpuPkg/SecCore/SecCore.inf > UefiCpuPkg/SecCore/SecCoreNative.inf > -- > 2.16.2.windows.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#112716): https://edk2.groups.io/g/devel/message/112716 Mute This Topic: https://groups.io/mt/103259036/7686176 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/leave/12367111/7686176/19134562= 12/xyzzy [rebecca@openfw.io] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-