From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by mx.groups.io with SMTP id smtpd.web08.8773.1617891852443441826 for ; Thu, 08 Apr 2021 07:24:12 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@intel.onmicrosoft.com header.s=selector2-intel-onmicrosoft-com header.b=JbOQv1F2; spf=pass (domain: intel.com, ip: 192.55.52.93, mailfrom: eric.dong@intel.com) IronPort-SDR: 6RTfD37Y0GDC7HA8ytRAhZik4Tr2ntnIHEyhMOtcOMdn7ML3FKgtKvHVl1EPxpqlpRYcGF/KGI qo+w9hcYl9VQ== X-IronPort-AV: E=McAfee;i="6000,8403,9948"; a="190348714" X-IronPort-AV: E=Sophos;i="5.82,206,1613462400"; d="scan'208";a="190348714" Received: from fmsmga008.fm.intel.com ([10.253.24.58]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 Apr 2021 07:24:11 -0700 IronPort-SDR: sRy2so0nvzvMX1KaRtgdkcWi4lNwIwi4/KEkcoP+Tr6RdMbYEKF7iTF2nvSsZ7vsRzinuayBFZ CLuwzkndR6Xg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.82,206,1613462400"; d="scan'208";a="415796561" Received: from fmsmsx604.amr.corp.intel.com ([10.18.126.84]) by fmsmga008.fm.intel.com with ESMTP; 08 Apr 2021 07:24:11 -0700 Received: from fmsmsx608.amr.corp.intel.com (10.18.126.88) by fmsmsx604.amr.corp.intel.com (10.18.126.84) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2106.2; Thu, 8 Apr 2021 07:24:11 -0700 Received: from fmsedg601.ED.cps.intel.com (10.1.192.135) by fmsmsx608.amr.corp.intel.com (10.18.126.88) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2106.2 via Frontend Transport; Thu, 8 Apr 2021 07:24:11 -0700 Received: from NAM10-DM6-obe.outbound.protection.outlook.com (104.47.58.104) by edgegateway.intel.com (192.55.55.70) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.1.2106.2; Thu, 8 Apr 2021 07:24:10 -0700 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=Bz/MoaiWPx9bL8en5XtWGosg6M7NJEA/8Jb4/VCF2IejDlZw6mSurQ+bFE8xfvwkFBrKwkP9hLd/2NzLQHLIlFLy7sUFpI0KmvG8co2yptjIv65fmLgJIrvTC3tzJPn+cvSrvlxEav7HVEAYKdYtCs49Zxck+rklh+igNCfD/tq0CZvJrtSGuBc/1qDfjLN88TWxHfP2OQcet4hCK2oVnVYs6KLbgn448JT6FkDqse8z9+7j/3+zbHIhj9Po8AMLVmV/htsA0Nj9QEIazIfRUtJHwPQRcg7LHQ1qtgtoRtuT9+kU6A09M1xRCL/yuDYlsqV6CmyCYV5iNNhDMpZcyg== 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-SenderADCheck; bh=RKa71kxhO5x8Gr6CaAdBOa/8CTISz1dBIAdsiy6S02A=; b=IJ86aLIFRd1yUWGlVs2iz2G61EHaqNpXGxjHsg8FHISc7hwnnXguGoI4JN/hMj+YYi0XKqOEacrMj+3orc4KhISLL8EVIme5aAZJXZ8gSTOKv5BL2RR1zmjfRDvjr/PKNGUwFtI+4qWLc+cEPAUPpUDfXMsfC716BB4SfzIDX2iOo57GKfb+scclMDDUpM9pZ33xXt6XFynC77ghS/+A5hyFfkvlqKMdKxBH+Ppo2QnWl/2/NRGRnFYm1VfCYjxGKpOsREzi8QZq5B8tJCgdZ9ZeHCOKTGtbEPp/O0HlRY0Z938iHI8yHPhbI34fxv1nGVix7ipre5XQbbwcYBj3hQ== 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 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=intel.onmicrosoft.com; s=selector2-intel-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=RKa71kxhO5x8Gr6CaAdBOa/8CTISz1dBIAdsiy6S02A=; b=JbOQv1F2/wRO79/LN1EvG7t6vEoNvKz0wFP1CG7NndHpfSQmdHy8AJg2zX3GG7TZpK1xr8/w0iVVTRlpLpoMK0BUgyOw93Ml+eKYcRJ4iDuvvcpPlOWursGoeBAaYCoynqrRVmbyPQuD+V8QDAjryrxrQOgROKE5YExH1A/7EII= Received: from CY4PR11MB1272.namprd11.prod.outlook.com (2603:10b6:903:29::9) by CY4PR11MB1656.namprd11.prod.outlook.com (2603:10b6:910:7::21) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3999.27; Thu, 8 Apr 2021 14:24:09 +0000 Received: from CY4PR11MB1272.namprd11.prod.outlook.com ([fe80::918c:7df3:f688:d5e9]) by CY4PR11MB1272.namprd11.prod.outlook.com ([fe80::918c:7df3:f688:d5e9%5]) with mapi id 15.20.3999.032; Thu, 8 Apr 2021 14:24:09 +0000 From: "Dong, Eric" To: "Ni, Ray" , "devel@edk2.groups.io" CC: Laszlo Ersek , "Kumar, Rahul1" Subject: Re: [PATCH 4/4] UefiCpuPkg/MpInitLib: Consume MicrocodeLib to remove duplicated code Thread-Topic: [PATCH 4/4] UefiCpuPkg/MpInitLib: Consume MicrocodeLib to remove duplicated code Thread-Index: AQHXJ4U9V6BYrsuXek2PTjUM520/7qqqtmwQ Date: Thu, 8 Apr 2021 14:24:09 +0000 Message-ID: References: <20210402055807.858-1-ray.ni@intel.com> <20210402055807.858-5-ray.ni@intel.com> In-Reply-To: <20210402055807.858-5-ray.ni@intel.com> Accept-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: dlp-version: 11.5.1.3 dlp-product: dlpe-windows dlp-reaction: no-action authentication-results: intel.com; dkim=none (message not signed) header.d=none;intel.com; dmarc=none action=none header.from=intel.com; x-originating-ip: [61.155.142.105] x-ms-publictraffictype: Email x-ms-office365-filtering-correlation-id: b98759e5-dbaf-4925-f5df-08d8fa99f95e x-ms-traffictypediagnostic: CY4PR11MB1656: x-ms-exchange-transport-forked: True x-microsoft-antispam-prvs: x-ms-oob-tlc-oobclassifiers: OLM:9508; x-ms-exchange-senderadcheck: 1 x-microsoft-antispam: BCL:0; x-microsoft-antispam-message-info: lTxzXMjjyYKbrPeHXWUOqPXNtLievpxnK3nzih8fnaXvcTj4nL/U21wI6frSdnkGOjxRE5wNTVVS67LnbPAqnUaugs0KWjT3uPfamLmpVJvMZVbBVG61v6V9ILqseXJS5/lk7Bf1e7MaUZN7sbNy39E0mue5wFN/fZVrAxGkVnBSIw2aB43KSxIpNmMKyFAMv6lsNHsjHELcgDb4IegteiLTytt16MmahVzIyEZiUDdSWVaaL1UZpNx0lK28WVhjZEEgZ02mDuB885VnaaK7o3O+mbL+8KSIx8+7WaqhGJi1RxdvbyKI3CVJirGeGGSP//vHHJ2O0Ont5ftALSj9zdxSML/8v7as0bBQPuAPmj3iF4OO7J6KG8C1TCG35N5oij49IyPIn6yETlzli8n6Vec3rUtw1SJdFse8wGSJEcLM6e/n9KkUeW+Q2YFZ9m9oV8TesULyBWGaOVKu+mhYAMhPqvnHxZZdUBqN6RJE0J7CHSMT1BSiN4rJAaZHyC/cxiOOYFZJ6J0DVLEdEbPeDXMokPz3a7tPczWBN6BAh4wKSkrP5IyXibM82Pvek2cN029DknAAmSIQtloby74vswxNibjSqZ4aM52VC3tDb7yGnCPpogVwK3IM2MqUzAfxYPIUpcYRDvRddGZ9wMky7g1J3sndbx9f+1WQNpeNQWc= x-forefront-antispam-report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:CY4PR11MB1272.namprd11.prod.outlook.com;PTR:;CAT:NONE;SFS:(6029001)(136003)(366004)(39860400002)(396003)(346002)(376002)(107886003)(38100700001)(76116006)(4326008)(19627235002)(33656002)(64756008)(86362001)(186003)(55016002)(110136005)(54906003)(6506007)(52536014)(30864003)(71200400001)(66446008)(5660300002)(53546011)(316002)(9686003)(83380400001)(2906002)(8936002)(26005)(66556008)(66476007)(66946007)(7696005)(8676002)(478600001)(579004)(559001);DIR:OUT;SFP:1102; x-ms-exchange-antispam-messagedata: =?us-ascii?Q?narjz1afbf8XcyJz7psOx62nMgVCTlimfkz6sJjTXnw0V5wTlgeUIbFEo2ZI?= =?us-ascii?Q?JLp414XpoPXfd0W0mC22d3CbGZ8IOWRIb74zFNJPApUroMJC/Q3eyixsI5Kr?= =?us-ascii?Q?jxkenFmN+Dj8xcY5q+iX4ae1Xg78Z4vHojzvSRbC8DjVG+ymgYQIe6fPSGWa?= =?us-ascii?Q?k7Qeb+GvraOIerO8uYnQQ2RfqjKEfUik583sOu1z5hQzZuFiZWF6v7pIHpjC?= =?us-ascii?Q?g2VJviCcKCFAZQrn0id+ppAM8A2qWYzskqtKLB6IWEahuIqBcTOQOh046zAP?= =?us-ascii?Q?wzEAE/KRgHENY6uldV2SsatXnHVwwar7mt7hJLJeFteC1LJkGpSpotmytnnB?= =?us-ascii?Q?xL3LB0A/Pp8wz8QmQHqZcMCdhtgTiZZG46Wvh7ov6LMwSNNhbOS4CS7xVCrl?= =?us-ascii?Q?u+NCS6K8ybZRIHARgcRbg84sZYa31PoC4qhT6z11ItRVAu5Uc7RbtKgeSm87?= =?us-ascii?Q?RInO0YLNthA2b5BrAo0KPenDWCBXYqKn4CTFntZpcBlvTWl72XVDqlC/qb0T?= =?us-ascii?Q?qco9YI4keeA24CHGCpoCUHgpbPeWYRuh7yOdXk7bdHmAnmE+aPg6F5Y7KZkI?= =?us-ascii?Q?sDL7T/EcrjqjC6Mw5CGWRWYcsTK3BxZ5Dl3JIv3uCN6zD66SCr6/eDDsuqxA?= =?us-ascii?Q?2ahHdWvRHEDqr8q3tClumwfVjKafjyUzGhVBJOuGQaN6INrMSpYMPD87Ia4x?= =?us-ascii?Q?KTF+o7E/3KnG6GKJtTQNW68JruXqYAUbISp5LWN1HuT/fKOC1KMWlSs4jybi?= =?us-ascii?Q?KRRAgfAHKjSpGo1abAtaZE0k7FgEHiHJIqSLPXzFCQrciXH8U29r3wc2IvS4?= =?us-ascii?Q?HL0jFXaOps6URDlG0/AD3Hmv8x1Q7ebZGnyAsc8EK+vosf3+P2ZdMDfAz5Tg?= =?us-ascii?Q?zsmr42LplcexvmIO5vBGQOWTAMDUb267GxWKJ+nXtKBau9aabQSQm2xQK7p1?= =?us-ascii?Q?TIpO5Zrw64xUX4yM9ivbtwJIhBrnwaEYJXAsVm2RZ+LSwvMmae6JsX+zHSS4?= =?us-ascii?Q?9sVf1s29OBwPY09XGK/RnSTUjZBxul3XhiXB8QvUyPw3u25/enfTQ3NKc/g1?= =?us-ascii?Q?hBxRXRVUmuvQPb5oz+S0kxHEPqkPGLfBeagKiIV9I0AURLH0pap/pEkwInO/?= =?us-ascii?Q?vPV8GxG9xLQ54wHKTxpZHRaohMyhPeetDaxLmQmI32iyzyvPTc8JgWrNC0Va?= =?us-ascii?Q?k60485xMm1/fviVBLuXvvYmh00ZunmniZZMU5VrJ/5PfgIAkG++NuVOLMpv8?= =?us-ascii?Q?oi+rj1jAGYZ/FosFXN/gvKvTVhBKoZrwQvc4ijbZjcUQE5wJETR3WvUR3S8P?= =?us-ascii?Q?VcXzuUdrJBxdfjIezzAKQSXL?= MIME-Version: 1.0 X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-AuthSource: CY4PR11MB1272.namprd11.prod.outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: b98759e5-dbaf-4925-f5df-08d8fa99f95e X-MS-Exchange-CrossTenant-originalarrivaltime: 08 Apr 2021 14:24:09.2316 (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: 3EnkG+rlT87swlS5/9W6CWbFRbRBV5uQzNy1mLfLMm8VdiWpe51EB6VO8sqw6Nm8ouiiPkdLkl1m0ZcaGJv1fQ== X-MS-Exchange-Transport-CrossTenantHeadersStamped: CY4PR11MB1656 Return-Path: eric.dong@intel.com X-OriginatorOrg: intel.com Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Reviewed-by: Eric Dong -----Original Message----- From: Ni, Ray =20 Sent: Friday, April 2, 2021 1:58 PM To: devel@edk2.groups.io Cc: Dong, Eric ; Laszlo Ersek ; Kum= ar, Rahul1 Subject: [PATCH 4/4] UefiCpuPkg/MpInitLib: Consume MicrocodeLib to remove d= uplicated code Signed-off-by: Ray Ni Cc: Eric Dong Cc: Laszlo Ersek Cc: Rahul Kumar --- UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf | 1 + UefiCpuPkg/Library/MpInitLib/Microcode.c | 484 ++++-------------- UefiCpuPkg/Library/MpInitLib/MpLib.h | 1 + UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf | 1 + 4 files changed, 96 insertions(+), 391 deletions(-) diff --git a/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf b/UefiCpuPkg/Lib= rary/MpInitLib/DxeMpInitLib.inf index 860a9750e2..d34419c2a5 100644 --- a/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf +++ b/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf @@ -52,6 +52,7 @@ [LibraryClasses] SynchronizationLib PcdLib VmgExitLib + MicrocodeLib =20 [Protocols] gEfiTimerArchProtocolGuid ## SOMETIMES_CONSUMES diff --git a/UefiCpuPkg/Library/MpInitLib/Microcode.c b/UefiCpuPkg/Library/= MpInitLib/Microcode.c index 297c2abcd1..105a9f84bf 100644 --- a/UefiCpuPkg/Library/MpInitLib/Microcode.c +++ b/UefiCpuPkg/Library/MpInitLib/Microcode.c @@ -1,70 +1,16 @@ /** @file Implementation of loading microcode on processors. =20 - Copyright (c) 2015 - 2020, Intel Corporation. All rights reserved.
+ Copyright (c) 2015 - 2021, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent =20 **/ =20 #include "MpLib.h" =20 -/** - Get microcode update signature of currently loaded microcode update. - - @return Microcode signature. -**/ -UINT32 -GetCurrentMicrocodeSignature ( - VOID - ) -{ - MSR_IA32_BIOS_SIGN_ID_REGISTER BiosSignIdMsr; - - AsmWriteMsr64 (MSR_IA32_BIOS_SIGN_ID, 0); - AsmCpuid (CPUID_VERSION_INFO, NULL, NULL, NULL, NULL); - BiosSignIdMsr.Uint64 =3D AsmReadMsr64 (MSR_IA32_BIOS_SIGN_ID); - return BiosSignIdMsr.Bits.MicrocodeUpdateSignature; -} - /** Detect whether specified processor can find matching microcode patch and= load it. =20 - Microcode Payload as the following format: - +----------------------------------------+------------------+ - | CPU_MICROCODE_HEADER | | - +----------------------------------------+ CheckSum Part1 | - | Microcode Binary | | - +----------------------------------------+------------------+ - | CPU_MICROCODE_EXTENDED_TABLE_HEADER | | - +----------------------------------------+ CheckSum Part2 | - | CPU_MICROCODE_EXTENDED_TABLE | | - | ... | | - +----------------------------------------+------------------+ - - There may by multiple CPU_MICROCODE_EXTENDED_TABLE in this format. - The count of CPU_MICROCODE_EXTENDED_TABLE is indicated by ExtendedSignat= ureCount - of CPU_MICROCODE_EXTENDED_TABLE_HEADER structure. - - When we are trying to verify the CheckSum32 with extended table. - We should use the fields of exnteded table to replace the corresponding - fields in CPU_MICROCODE_HEADER structure, and recalculate the - CheckSum32 with CPU_MICROCODE_HEADER + Microcode Binary. We named - it as CheckSum Part3. - - The CheckSum Part2 is used to verify the CPU_MICROCODE_EXTENDED_TABLE_HE= ADER - and CPU_MICROCODE_EXTENDED_TABLE parts. We should make sure CheckSum Par= t2 - is correct before we are going to verify each CPU_MICROCODE_EXTENDED_TAB= LE. - - Only ProcessorSignature, ProcessorFlag and CheckSum are different betwee= n - CheckSum Part1 and CheckSum Part3. To avoid multiple computing CheckSum = Part3. - Save an in-complete CheckSum32 from CheckSum Part1 for common parts. - When we are going to calculate CheckSum32, just should use the correspon= ding part - of the ProcessorSignature, ProcessorFlag and CheckSum with in-complete C= heckSum32. - - Notes: CheckSum32 is not a strong verification. - It does not guarantee that the data has not been modified. - CPU has its own mechanism to verify Microcode Binary part. - @param[in] CpuMpData The pointer to CPU MP Data structure. @param[in] ProcessorNumber The handle number of the processor. The ran= ge is from 0 to the total number of logical proce= ssors @@ -76,26 +22,13 @@ MicrocodeDetect ( IN UINTN ProcessorNumber ) { - UINT32 ExtendedTableLength; - UINT32 ExtendedTableCount; - CPU_MICROCODE_EXTENDED_TABLE *ExtendedTable; - CPU_MICROCODE_EXTENDED_TABLE_HEADER *ExtendedTableHeader; - CPU_MICROCODE_HEADER *MicrocodeEntryPoint; + CPU_MICROCODE_HEADER *Microcode; UINTN MicrocodeEnd; - UINTN Index; - UINT8 PlatformId; - CPUID_VERSION_INFO_EAX Eax; - CPU_AP_DATA *CpuData; - UINT32 CurrentRevision; + CPU_AP_DATA *BspData; UINT32 LatestRevision; - UINTN TotalSize; - UINT32 CheckSum32; - UINT32 InCompleteCheckSum32; - BOOLEAN CorrectMicrocode; - VOID *MicrocodeData; - MSR_IA32_PLATFORM_ID_REGISTER PlatformIdMsr; + CPU_MICROCODE_HEADER *LatestMicrocode; UINT32 ThreadId; - BOOLEAN IsBspCallIn; + EDKII_PEI_MICROCODE_CPU_ID MicrocodeCpuId; =20 if (CpuMpData->MicrocodePatchRegionSize =3D=3D 0) { // @@ -104,9 +37,6 @@ MicrocodeDetect ( return; } =20 - CurrentRevision =3D GetCurrentMicrocodeSignature (); - IsBspCallIn =3D (ProcessorNumber =3D=3D (UINTN)CpuMpData->BspNumber)= ? TRUE : FALSE; - GetProcessorLocationByApicId (GetInitialApicId (), NULL, NULL, &ThreadId= ); if (ThreadId !=3D 0) { // @@ -115,156 +45,35 @@ MicrocodeDetect ( return; } =20 - ExtendedTableLength =3D 0; - // - // Here data of CPUID leafs have not been collected into context buffer,= so - // GetProcessorCpuid() cannot be used here to retrieve CPUID data. - // - AsmCpuid (CPUID_VERSION_INFO, &Eax.Uint32, NULL, NULL, NULL); + GetProcessorMicrocodeCpuId (&MicrocodeCpuId); =20 - // - // The index of platform information resides in bits 50:52 of MSR IA32_P= LATFORM_ID - // - PlatformIdMsr.Uint64 =3D AsmReadMsr64 (MSR_IA32_PLATFORM_ID); - PlatformId =3D (UINT8) PlatformIdMsr.Bits.PlatformId; - - - // - // Check whether AP has same processor with BSP. - // If yes, direct use microcode info saved by BSP. - // - if (!IsBspCallIn) { + if (ProcessorNumber !=3D (UINTN) CpuMpData->BspNumber) { // - // Get the CPU data for BSP + // Direct use microcode of BSP if AP is the same as BSP. + // Assume BSP calls this routine() before AP. // - CpuData =3D &(CpuMpData->CpuData[CpuMpData->BspNumber]); - if ((CpuData->ProcessorSignature =3D=3D Eax.Uint32) && - (CpuData->PlatformId =3D=3D PlatformId) && - (CpuData->MicrocodeEntryAddr !=3D 0)) { - MicrocodeEntryPoint =3D (CPU_MICROCODE_HEADER *)(UINTN) CpuData->Mic= rocodeEntryAddr; - MicrocodeData =3D (VOID *) (MicrocodeEntryPoint + 1); - LatestRevision =3D MicrocodeEntryPoint->UpdateRevision; - goto Done; + BspData =3D &(CpuMpData->CpuData[CpuMpData->BspNumber]); + if ((BspData->ProcessorSignature =3D=3D MicrocodeCpuId.ProcessorSignat= ure) && + (BspData->PlatformId =3D=3D MicrocodeCpuId.PlatformId) && + (BspData->MicrocodeEntryAddr !=3D 0)) { + LatestMicrocode =3D (CPU_MICROCODE_HEADER *)(UINTN) BspData->Microco= deEntryAddr; + LatestRevision =3D LatestMicrocode->UpdateRevision; + goto LoadMicrocode; } } =20 - LatestRevision =3D 0; - MicrocodeData =3D NULL; - MicrocodeEnd =3D (UINTN) (CpuMpData->MicrocodePatchAddress + CpuMpData->= MicrocodePatchRegionSize); - MicrocodeEntryPoint =3D (CPU_MICROCODE_HEADER *) (UINTN) CpuMpData->Micr= ocodePatchAddress; + // + // BSP or AP which is different from BSP runs here + // Use 0 as the starting revision to search for microcode because Microc= odePatchInfo HOB needs + // the latest microcode location even it's loaded to the processor. + // + LatestRevision =3D 0; + LatestMicrocode =3D NULL; + Microcode =3D (CPU_MICROCODE_HEADER *) (UINTN) CpuMpData->Microcod= ePatchAddress; + MicrocodeEnd =3D (UINTN) Microcode + (UINTN) CpuMpData->MicrocodePatc= hRegionSize; =20 do { - // - // Check if the microcode is for the Cpu and the version is newer - // and the update can be processed on the platform - // - CorrectMicrocode =3D FALSE; - - if (MicrocodeEntryPoint->DataSize =3D=3D 0) { - TotalSize =3D sizeof (CPU_MICROCODE_HEADER) + 2000; - } else { - TotalSize =3D sizeof (CPU_MICROCODE_HEADER) + MicrocodeEntryPoint->D= ataSize; - } - - /// - /// 0x0 MicrocodeBegin MicrocodeEntry MicrocodeEnd 0xffff= ffff - /// |--------------|---------------|---------------|---------------| - /// valid TotalSize - /// TotalSize is only valid between 0 and (MicrocodeEnd - MicrocodeEnt= ry). - /// And it should be aligned with 4 bytes. - /// If the TotalSize is invalid, skip 1KB to check next entry. - /// - if ( (UINTN)MicrocodeEntryPoint > (MAX_ADDRESS - TotalSize) || - ((UINTN)MicrocodeEntryPoint + TotalSize) > MicrocodeEnd || - (TotalSize & 0x3) !=3D 0 - ) { - MicrocodeEntryPoint =3D (CPU_MICROCODE_HEADER *) (((UINTN) Microcode= EntryPoint) + SIZE_1KB); - continue; - } - - // - // Save an in-complete CheckSum32 from CheckSum Part1 for common parts= . - // - InCompleteCheckSum32 =3D CalculateSum32 ( - (UINT32 *) MicrocodeEntryPoint, - TotalSize - ); - InCompleteCheckSum32 -=3D MicrocodeEntryPoint->ProcessorSignature.Uint= 32; - InCompleteCheckSum32 -=3D MicrocodeEntryPoint->ProcessorFlags; - InCompleteCheckSum32 -=3D MicrocodeEntryPoint->Checksum; - - if (MicrocodeEntryPoint->HeaderVersion =3D=3D 0x1) { - // - // It is the microcode header. It is not the padding data between mi= crocode patches - // because the padding data should not include 0x00000001 and it sho= uld be the repeated - // byte format (like 0xXYXYXYXY....). - // - if (MicrocodeEntryPoint->ProcessorSignature.Uint32 =3D=3D Eax.Uint32= && - MicrocodeEntryPoint->UpdateRevision > LatestRevision && - (MicrocodeEntryPoint->ProcessorFlags & (1 << PlatformId)) - ) { - // - // Calculate CheckSum Part1. - // - CheckSum32 =3D InCompleteCheckSum32; - CheckSum32 +=3D MicrocodeEntryPoint->ProcessorSignature.Uint32; - CheckSum32 +=3D MicrocodeEntryPoint->ProcessorFlags; - CheckSum32 +=3D MicrocodeEntryPoint->Checksum; - if (CheckSum32 =3D=3D 0) { - CorrectMicrocode =3D TRUE; - } - } else if ((MicrocodeEntryPoint->DataSize !=3D 0) && - (MicrocodeEntryPoint->UpdateRevision > LatestRevision)) { - ExtendedTableLength =3D MicrocodeEntryPoint->TotalSize - (Microcod= eEntryPoint->DataSize + - sizeof (CPU_MICROCODE_HEADER)); - if (ExtendedTableLength !=3D 0) { - // - // Extended Table exist, check if the CPU in support list - // - ExtendedTableHeader =3D (CPU_MICROCODE_EXTENDED_TABLE_HEADER *) = ((UINT8 *) (MicrocodeEntryPoint) - + MicrocodeEntryPoint->DataSize + sizeof= (CPU_MICROCODE_HEADER)); - // - // Calculate Extended Checksum - // - if ((ExtendedTableLength % 4) =3D=3D 0) { - // - // Calculate CheckSum Part2. - // - CheckSum32 =3D CalculateSum32 ((UINT32 *) ExtendedTableHeader,= ExtendedTableLength); - if (CheckSum32 =3D=3D 0) { - // - // Checksum correct - // - ExtendedTableCount =3D ExtendedTableHeader->ExtendedSignatur= eCount; - ExtendedTable =3D (CPU_MICROCODE_EXTENDED_TABLE *) (Ext= endedTableHeader + 1); - for (Index =3D 0; Index < ExtendedTableCount; Index ++) { - // - // Calculate CheckSum Part3. - // - CheckSum32 =3D InCompleteCheckSum32; - CheckSum32 +=3D ExtendedTable->ProcessorSignature.Uint32; - CheckSum32 +=3D ExtendedTable->ProcessorFlag; - CheckSum32 +=3D ExtendedTable->Checksum; - if (CheckSum32 =3D=3D 0) { - // - // Verify Header - // - if ((ExtendedTable->ProcessorSignature.Uint32 =3D=3D Eax= .Uint32) && - (ExtendedTable->ProcessorFlag & (1 << PlatformId)) )= { - // - // Find one - // - CorrectMicrocode =3D TRUE; - break; - } - } - ExtendedTable ++; - } - } - } - } - } - } else { + if (!IsValidMicrocode (Microcode, MicrocodeEnd - (UINTN) Microcode, La= testRevision, &MicrocodeCpuId, 1, TRUE)) { // // It is the padding data between the microcode patches for microcod= e patches alignment. // Because the microcode patch is the multiple of 1-KByte, the paddi= ng data should not @@ -272,156 +81,40 @@ MicrocodeDetect ( // alignment value should be larger than 1-KByte. We could skip SIZE= _1KB padding data to // find the next possible microcode patch header. // - MicrocodeEntryPoint =3D (CPU_MICROCODE_HEADER *) (((UINTN) Microcode= EntryPoint) + SIZE_1KB); + Microcode =3D (CPU_MICROCODE_HEADER *) ((UINTN) Microcode + SIZE_1KB= ); continue; } - // - // Get the next patch. - // - if (MicrocodeEntryPoint->DataSize =3D=3D 0) { - TotalSize =3D 2048; - } else { - TotalSize =3D MicrocodeEntryPoint->TotalSize; - } + LatestMicrocode =3D Microcode; + LatestRevision =3D LatestMicrocode->UpdateRevision; =20 - if (CorrectMicrocode) { - LatestRevision =3D MicrocodeEntryPoint->UpdateRevision; - MicrocodeData =3D (VOID *) ((UINTN) MicrocodeEntryPoint + sizeof (CP= U_MICROCODE_HEADER)); - } - - MicrocodeEntryPoint =3D (CPU_MICROCODE_HEADER *) (((UINTN) MicrocodeEn= tryPoint) + TotalSize); - } while (((UINTN) MicrocodeEntryPoint < MicrocodeEnd)); + Microcode =3D (CPU_MICROCODE_HEADER *) (((UINTN) Microcode) + GetMicro= codeLength (Microcode)); + } while ((UINTN) Microcode < MicrocodeEnd); =20 -Done: +LoadMicrocode: if (LatestRevision !=3D 0) { // - // Save the detected microcode patch entry address (including the - // microcode patch header) for each processor. + // Save the detected microcode patch entry address (including the micr= ocode + // patch header) for each processor even it's the same as the loaded o= ne. // It will be used when building the microcode patch cache HOB. // - CpuMpData->CpuData[ProcessorNumber].MicrocodeEntryAddr =3D - (UINTN) MicrocodeData - sizeof (CPU_MICROCODE_HEADER); + CpuMpData->CpuData[ProcessorNumber].MicrocodeEntryAddr =3D (UINTN) Lat= estMicrocode; } =20 - if (LatestRevision > CurrentRevision) { + if (LatestRevision > GetProcessorMicrocodeSignature ()) { // // BIOS only authenticate updates that contain a numerically larger re= vision // than the currently loaded revision, where Current Signature < New U= pdate // Revision. A processor with no loaded update is considered to have a // revision equal to zero. // - ASSERT (MicrocodeData !=3D NULL); - AsmWriteMsr64 ( - MSR_IA32_BIOS_UPDT_TRIG, - (UINT64) (UINTN) MicrocodeData - ); - } - CpuMpData->CpuData[ProcessorNumber].MicrocodeRevision =3D GetCurrentMicr= ocodeSignature (); -} - -/** - Determine if a microcode patch matchs the specific processor signature a= nd flag. - - @param[in] CpuMpData The pointer to CPU MP Data structure. - @param[in] ProcessorSignature The processor signature field value - supported by a microcode patch. - @param[in] ProcessorFlags The prcessor flags field value support= ed by - a microcode patch. - - @retval TRUE The specified microcode patch will be loaded. - @retval FALSE The specified microcode patch will not be loaded. -**/ -BOOLEAN -IsProcessorMatchedMicrocodePatch ( - IN CPU_MP_DATA *CpuMpData, - IN UINT32 ProcessorSignature, - IN UINT32 ProcessorFlags - ) -{ - UINTN Index; - CPU_AP_DATA *CpuData; - - for (Index =3D 0; Index < CpuMpData->CpuCount; Index++) { - CpuData =3D &CpuMpData->CpuData[Index]; - if ((ProcessorSignature =3D=3D CpuData->ProcessorSignature) && - (ProcessorFlags & (1 << CpuData->PlatformId)) !=3D 0) { - return TRUE; - } + LoadMicrocode (LatestMicrocode); } - - return FALSE; -} - -/** - Check the 'ProcessorSignature' and 'ProcessorFlags' of the microcode - patch header with the CPUID and PlatformID of the processors within - system to decide if it will be copied into memory. - - @param[in] CpuMpData The pointer to CPU MP Data structure. - @param[in] MicrocodeEntryPoint The pointer to the microcode patch hea= der. - - @retval TRUE The specified microcode patch need to be loaded. - @retval FALSE The specified microcode patch dosen't need to be loaded= . -**/ -BOOLEAN -IsMicrocodePatchNeedLoad ( - IN CPU_MP_DATA *CpuMpData, - CPU_MICROCODE_HEADER *MicrocodeEntryPoint - ) -{ - BOOLEAN NeedLoad; - UINTN DataSize; - UINTN TotalSize; - CPU_MICROCODE_EXTENDED_TABLE_HEADER *ExtendedTableHeader; - UINT32 ExtendedTableCount; - CPU_MICROCODE_EXTENDED_TABLE *ExtendedTable; - UINTN Index; - // - // Check the 'ProcessorSignature' and 'ProcessorFlags' in microcode patc= h header. + // It's possible that the microcode fails to load. Just capture the CPU = microcode revision after loading. // - NeedLoad =3D IsProcessorMatchedMicrocodePatch ( - CpuMpData, - MicrocodeEntryPoint->ProcessorSignature.Uint32, - MicrocodeEntryPoint->ProcessorFlags - ); - - // - // If the Extended Signature Table exists, check if the processor is in = the - // support list - // - DataSize =3D MicrocodeEntryPoint->DataSize; - TotalSize =3D (DataSize =3D=3D 0) ? 2048 : MicrocodeEntryPoint->TotalSiz= e; - if ((!NeedLoad) && (DataSize !=3D 0) && - (TotalSize - DataSize > sizeof (CPU_MICROCODE_HEADER) + - sizeof (CPU_MICROCODE_EXTENDED_TABLE_HEADER)= )) { - ExtendedTableHeader =3D (CPU_MICROCODE_EXTENDED_TABLE_HEADER *) ((UINT= 8 *) (MicrocodeEntryPoint) - + DataSize + sizeof (CPU_MICROCODE_HEADER)); - ExtendedTableCount =3D ExtendedTableHeader->ExtendedSignatureCount; - ExtendedTable =3D (CPU_MICROCODE_EXTENDED_TABLE *) (ExtendedTabl= eHeader + 1); - - for (Index =3D 0; Index < ExtendedTableCount; Index ++) { - // - // Check the 'ProcessorSignature' and 'ProcessorFlag' of the Extende= d - // Signature Table entry with the CPUID and PlatformID of the proces= sors - // within system to decide if it will be copied into memory - // - NeedLoad =3D IsProcessorMatchedMicrocodePatch ( - CpuMpData, - ExtendedTable->ProcessorSignature.Uint32, - ExtendedTable->ProcessorFlag - ); - if (NeedLoad) { - break; - } - ExtendedTable ++; - } - } - - return NeedLoad; + CpuMpData->CpuData[ProcessorNumber].MicrocodeRevision =3D GetProcessorMi= crocodeSignature (); } =20 - /** Actual worker function that shadows the required microcode patches into = memory. =20 @@ -491,14 +184,16 @@ ShadowMicrocodePatchByPcd ( IN OUT CPU_MP_DATA *CpuMpData ) { + UINTN Index; CPU_MICROCODE_HEADER *MicrocodeEntryPoint; UINTN MicrocodeEnd; - UINTN DataSize; UINTN TotalSize; MICROCODE_PATCH_INFO *PatchInfoBuffer; UINTN MaxPatchNumber; UINTN PatchCount; UINTN TotalLoadSize; + EDKII_PEI_MICROCODE_CPU_ID *MicrocodeCpuIds; + BOOLEAN Valid; =20 // // Initialize the microcode patch related fields in CpuMpData as the val= ues @@ -526,12 +221,34 @@ ShadowMicrocodePatchByPcd ( return; } =20 + MicrocodeCpuIds =3D AllocatePages ( + EFI_SIZE_TO_PAGES (CpuMpData->CpuCount * sizeof (EDK= II_PEI_MICROCODE_CPU_ID)) + ); + if (MicrocodeCpuIds =3D=3D NULL) { + FreePool (PatchInfoBuffer); + return; + } + + for (Index =3D 0; Index < CpuMpData->CpuCount; Index++) { + MicrocodeCpuIds[Index].PlatformId =3D CpuMpData->CpuData[Index= ].PlatformId; + MicrocodeCpuIds[Index].ProcessorSignature =3D CpuMpData->CpuData[Index= ].ProcessorSignature; + } + // // Process the header of each microcode patch within the region. // The purpose is to decide which microcode patch(es) will be loaded int= o memory. + // Microcode checksum is not verified because it's slow when performing = on flash. // do { - if (MicrocodeEntryPoint->HeaderVersion !=3D 0x1) { + Valid =3D IsValidMicrocode ( + MicrocodeEntryPoint, + MicrocodeEnd - (UINTN) MicrocodeEntryPoint, + 0, + MicrocodeCpuIds, + CpuMpData->CpuCount, + FALSE + ); + if (!Valid) { // // Padding data between the microcode patches, skip 1KB to check nex= t entry. // @@ -539,59 +256,44 @@ ShadowMicrocodePatchByPcd ( continue; } =20 - DataSize =3D MicrocodeEntryPoint->DataSize; - TotalSize =3D (DataSize =3D=3D 0) ? 2048 : MicrocodeEntryPoint->TotalS= ize; - if ( (UINTN)MicrocodeEntryPoint > (MAX_ADDRESS - TotalSize) || - ((UINTN)MicrocodeEntryPoint + TotalSize) > MicrocodeEnd || - (DataSize & 0x3) !=3D 0 || - (TotalSize & (SIZE_1KB - 1)) !=3D 0 || - TotalSize < DataSize - ) { + PatchCount++; + if (PatchCount > MaxPatchNumber) { // - // Not a valid microcode header, skip 1KB to check next entry. + // Current 'PatchInfoBuffer' cannot hold the information, double the= size + // and allocate a new buffer. // - MicrocodeEntryPoint =3D (CPU_MICROCODE_HEADER *) (((UINTN) Microcode= EntryPoint) + SIZE_1KB); - continue; - } - - if (IsMicrocodePatchNeedLoad (CpuMpData, MicrocodeEntryPoint)) { - PatchCount++; - if (PatchCount > MaxPatchNumber) { + if (MaxPatchNumber > MAX_UINTN / 2 / sizeof (MICROCODE_PATCH_INFO)) = { // - // Current 'PatchInfoBuffer' cannot hold the information, double t= he size - // and allocate a new buffer. + // Overflow check for MaxPatchNumber // - if (MaxPatchNumber > MAX_UINTN / 2 / sizeof (MICROCODE_PATCH_INFO)= ) { - // - // Overflow check for MaxPatchNumber - // - goto OnExit; - } - - PatchInfoBuffer =3D ReallocatePool ( - MaxPatchNumber * sizeof (MICROCODE_PATCH_INFO)= , - 2 * MaxPatchNumber * sizeof (MICROCODE_PATCH_I= NFO), - PatchInfoBuffer - ); - if (PatchInfoBuffer =3D=3D NULL) { - goto OnExit; - } - MaxPatchNumber =3D MaxPatchNumber * 2; + goto OnExit; } =20 - // - // Store the information of this microcode patch - // - PatchInfoBuffer[PatchCount - 1].Address =3D (UINTN) MicrocodeEntryPo= int; - PatchInfoBuffer[PatchCount - 1].Size =3D TotalSize; - TotalLoadSize +=3D TotalSize; + PatchInfoBuffer =3D ReallocatePool ( + MaxPatchNumber * sizeof (MICROCODE_PATCH_INFO), + 2 * MaxPatchNumber * sizeof (MICROCODE_PATCH_INF= O), + PatchInfoBuffer + ); + if (PatchInfoBuffer =3D=3D NULL) { + goto OnExit; + } + MaxPatchNumber =3D MaxPatchNumber * 2; } =20 + TotalSize =3D GetMicrocodeLength (MicrocodeEntryPoint); + + // + // Store the information of this microcode patch + // + PatchInfoBuffer[PatchCount - 1].Address =3D (UINTN) MicrocodeEntryPoin= t; + PatchInfoBuffer[PatchCount - 1].Size =3D TotalSize; + TotalLoadSize +=3D TotalSize; + // // Process the next microcode patch // - MicrocodeEntryPoint =3D (CPU_MICROCODE_HEADER *) (((UINTN) MicrocodeEn= tryPoint) + TotalSize); - } while (((UINTN) MicrocodeEntryPoint < MicrocodeEnd)); + MicrocodeEntryPoint =3D (CPU_MICROCODE_HEADER *) ((UINTN) MicrocodeEnt= ryPoint + TotalSize); + } while ((UINTN) MicrocodeEntryPoint < MicrocodeEnd); =20 if (PatchCount !=3D 0) { DEBUG (( @@ -607,7 +309,7 @@ OnExit: if (PatchInfoBuffer !=3D NULL) { FreePool (PatchInfoBuffer); } - return; + FreePages (MicrocodeCpuIds, EFI_SIZE_TO_PAGES (CpuMpData->CpuCount * siz= eof (EDKII_PEI_MICROCODE_CPU_ID))); } =20 /** diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.h b/UefiCpuPkg/Library/MpIn= itLib/MpLib.h index 66f9eb2304..e88a5355c9 100644 --- a/UefiCpuPkg/Library/MpInitLib/MpLib.h +++ b/UefiCpuPkg/Library/MpInitLib/MpLib.h @@ -32,6 +32,7 @@ #include #include #include +#include =20 #include =20 diff --git a/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf b/UefiCpuPkg/Lib= rary/MpInitLib/PeiMpInitLib.inf index 49b0ffe8be..36fcb96b58 100644 --- a/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf +++ b/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf @@ -51,6 +51,7 @@ [LibraryClasses] PeiServicesLib PcdLib VmgExitLib + MicrocodeLib =20 [Pcd] gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber ## CONS= UMES --=20 2.27.0.windows.1