From nobody Fri May 10 21:58:22 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+97748+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+97748+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1671867155; cv=none; d=zohomail.com; s=zohoarc; b=QDCQBhyg6jOybskim9SFeAOyb99QOT2rON262Z1jNK0+VW4eHN8dzATBLYCOsGqa8whAicATAKAzLgAaUYXWGXKfbLKRfjRf89hI7L5G932CLYRiWAF4bVSGFsy/FEtzaGB7/mYdRsA93KNdSThqOEKU5Is3oZk5VZHK+89J3V0= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1671867155; h=Cc:Date:From:List-Subscribe:List-Id:List-Help:List-Unsubscribe:Message-ID:Reply-To:Sender:Subject:To; bh=9fHtv9A7A+crWBZJOYkD3J6LxYHxzKgThc5B6sQ6fNw=; b=apdooE9X0HuZWhZ0dnERwdNt6x2YyByWhaWt5wY5ZJLrlk9dEmCucOzrvyQlcspXyp/Denhxrh9+CaECZJL6HNQXkLGoZkaWiHun7dRUhH2AswoyP7QPwb9VkYaTCJECnWGh/ezKdief7FVQ8wZfehXqB4//PRlnToWnJw/QGLY= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+97748+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 167186715418393.5742328642367; Fri, 23 Dec 2022 23:32:34 -0800 (PST) Return-Path: X-Received: by 127.0.0.2 with SMTP id ZB1gYY1788612xnWlWbemwLR; Fri, 23 Dec 2022 23:32:33 -0800 X-Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by mx.groups.io with SMTP id smtpd.web11.92321.1671867152224664411 for ; Fri, 23 Dec 2022 23:32:32 -0800 X-IronPort-AV: E=McAfee;i="6500,9779,10570"; a="322357092" X-IronPort-AV: E=Sophos;i="5.96,270,1665471600"; d="scan'208";a="322357092" X-Received: from orsmga007.jf.intel.com ([10.7.209.58]) by orsmga103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Dec 2022 23:32:29 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6500,9779,10570"; a="645746587" X-IronPort-AV: E=Sophos;i="5.96,270,1665471600"; d="scan'208";a="645746587" X-Received: from sh1gapp1009.ccr.corp.intel.com ([10.239.189.79]) by orsmga007.jf.intel.com with ESMTP; 23 Dec 2022 23:32:27 -0800 From: "Wu, Jiaxin" To: devel@edk2.groups.io Cc: Eric Dong , Ray Ni , Zeng Star Subject: [edk2-devel] [PATCH v1] UefiCpuPkg: Support SMM Relocated SmBase handling Date: Sat, 24 Dec 2022 15:32:25 +0800 Message-Id: <20221224073225.5124-1-jiaxin.wu@intel.com> Precedence: Bulk List-Unsubscribe: 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,jiaxin.wu@intel.com X-Gm-Message-State: IMJEZ4nVzlCje9vDIJctxrsox1787277AA= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1671867153; bh=gLBOoBmXEVSX4FeJ/Jseec7usUI581KE8kf5o1Hw0bQ=; h=Cc:Date:From:Reply-To:Subject:To; b=u/0pFA30vRr+txBIo6cwNTgo34p1h76E88gxtTWYYur76TvjbMKc41tpt+F+uBcTaNR hSloLvbR45Zk54WJ5FCTDQKs4ERjJijpIDuQiudi7TB5Ydk7oi2rbNvo4gZYIEaoecK7d AKM/82BKlcnBWl+2tv78CGCBNBvAPRfbRZ4= X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1671867158176100001 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Mainly changes as below: 1. Add Smm Relocation Info HOB, which is used to store the information of Smm Relocated SmBase array for each Processors; 2. Combine 2 SMIs (SmmInitHandler & gcSmiHandlerTemplate) into one (gcSmiHandlerTemplate), the new SMI handler needs to run to 2 paths: one to SmmCpuFeaturesInitializeProcessor(), the other to SMM Core Entry Point. 3. Issue SMI IPI (All Excluding Self SMM IPI + BSP SMM IPI) for SMM init before normal SMI sources happen. 4. Call SmmCpuFeaturesInitializeProcessor() in parallel. Change-Id: Iec7bf25166bfeefb44a202285465a35b5debbce4 Cc: Eric Dong Cc: Ray Ni Cc: Zeng Star Signed-off-by: Jiaxin Wu --- UefiCpuPkg/Include/Guid/SmmRelocationInfoHob.h | 36 +++ .../Library/SmmCpuFeaturesLib/CpuFeaturesLib.h | 1 + .../SmmCpuFeaturesLib/IntelSmmCpuFeaturesLib.c | 29 +- .../SmmCpuFeaturesLib/SmmCpuFeaturesLib.inf | 3 + .../SmmCpuFeaturesLib/SmmCpuFeaturesLibStm.inf | 1 + .../StandaloneMmCpuFeaturesLib.inf | 3 + UefiCpuPkg/PiSmmCpuDxeSmm/CpuS3.c | 23 +- UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c | 60 ++++- UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c | 292 +++++++++++++----= ---- UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h | 11 +- UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf | 1 + UefiCpuPkg/UefiCpuPkg.dec | 3 + 12 files changed, 338 insertions(+), 125 deletions(-) create mode 100644 UefiCpuPkg/Include/Guid/SmmRelocationInfoHob.h diff --git a/UefiCpuPkg/Include/Guid/SmmRelocationInfoHob.h b/UefiCpuPkg/In= clude/Guid/SmmRelocationInfoHob.h new file mode 100644 index 0000000000..a612537975 --- /dev/null +++ b/UefiCpuPkg/Include/Guid/SmmRelocationInfoHob.h @@ -0,0 +1,36 @@ +/** @file + The Smm Relocation Info HOB is used to store the information of: + A. Smm Relocated SmBase array for each Processors; + + Copyright (c) 2022, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _SMM_RELOCATION_INFO_HOB_H_ +#define _SMM_RELOCATION_INFO_HOB_H_ + +#include +#include + +#define SMM_RELOCATION_INFO_HOB_DATA_GUID \ + { \ + 0xc2217ba7, 0x03bb, 0x4f63, {0xa6, 0x47, 0x7c, 0x25, 0xc5, 0xfc, 0x9d,= 0x73} \ + } + +#pragma pack(1) +typedef struct { + /// + /// Describes the Number of all max supported processors. + /// + UINT64 NumberOfProcessors; + /// + /// Pointer to SmBase array for each Processors. + /// + UINT64 SmBase[]; +} SMM_RELOCATION_INFO_HOB_DATA; +#pragma pack() + +extern EFI_GUID gSmmRelocationInfoHobGuid; + +#endif diff --git a/UefiCpuPkg/Library/SmmCpuFeaturesLib/CpuFeaturesLib.h b/UefiCp= uPkg/Library/SmmCpuFeaturesLib/CpuFeaturesLib.h index fd3e902547..cf82b89d5e 100644 --- a/UefiCpuPkg/Library/SmmCpuFeaturesLib/CpuFeaturesLib.h +++ b/UefiCpuPkg/Library/SmmCpuFeaturesLib/CpuFeaturesLib.h @@ -7,10 +7,11 @@ **/ =20 #ifndef CPU_FEATURES_LIB_H_ #define CPU_FEATURES_LIB_H_ =20 +#include #include #include #include #include #include diff --git a/UefiCpuPkg/Library/SmmCpuFeaturesLib/IntelSmmCpuFeaturesLib.c = b/UefiCpuPkg/Library/SmmCpuFeaturesLib/IntelSmmCpuFeaturesLib.c index d5eaaa7a99..862ff921f9 100644 --- a/UefiCpuPkg/Library/SmmCpuFeaturesLib/IntelSmmCpuFeaturesLib.c +++ b/UefiCpuPkg/Library/SmmCpuFeaturesLib/IntelSmmCpuFeaturesLib.c @@ -36,10 +36,15 @@ SPDX-License-Identifier: BSD-2-Clause-Patent // Set default value to assume IA-32 Architectural MSRs are used // UINT32 mSmrrPhysBaseMsr =3D SMM_FEATURES_LIB_IA32_SMRR_PHYSBASE; UINT32 mSmrrPhysMaskMsr =3D SMM_FEATURES_LIB_IA32_SMRR_PHYSMASK; =20 +// +// Indicate Smm Relocation done or not +// +BOOLEAN mSmmRelocationDone; + // // Set default value to assume MTRRs need to be configured on each SMI // BOOLEAN mNeedConfigureMtrrs =3D TRUE; =20 @@ -63,10 +68,14 @@ CpuFeaturesLibInitialization ( UINT32 RegEax; UINT32 RegEdx; UINTN FamilyId; UINTN ModelId; =20 + EFI_HOB_GUID_TYPE* GuidHob; + + GuidHob =3D NULL; + // // Retrieve CPU Family and Model // AsmCpuid (CPUID_VERSION_INFO, &RegEax, NULL, NULL, &RegEdx); FamilyId =3D (RegEax >> 8) & 0xf; @@ -142,10 +151,18 @@ CpuFeaturesLibInitialization ( // // Allocate array for state of SMRR enable on all CPUs // mSmrrEnabled =3D (BOOLEAN *)AllocatePool (sizeof (BOOLEAN) * GetCpuMaxLo= gicalProcessorNumber ()); ASSERT (mSmrrEnabled !=3D NULL); + + // + // If gSmmRelocationInfoHobGuid found, means Smm Relocation has been don= e. + // + GuidHob =3D GetFirstGuidHob (&gSmmRelocationInfoHobGuid); + if (GuidHob !=3D NULL) { + mSmmRelocationDone =3D TRUE; + } } =20 /** Called during the very first SMI into System Management Mode to initiali= ze CPU features, including SMBASE, for the currently executing CPU. Since = this @@ -184,15 +201,17 @@ SmmCpuFeaturesInitializeProcessor ( UINT32 RegEax; UINT32 RegEdx; UINTN FamilyId; UINTN ModelId; =20 - // - // Configure SMBASE. - // - CpuState =3D (SMRAM_SAVE_STATE_MAP *)(UINTN)(SMM_DEFAULT_SMB= ASE + SMRAM_SAVE_STATE_MAP_OFFSET); - CpuState->x86.SMBASE =3D (UINT32)CpuHotPlugData->SmBase[CpuIndex]; + if (!mSmmRelocationDone) { + // + // Configure SMBASE. + // + CpuState =3D (SMRAM_SAVE_STATE_MAP *)(UINTN)(SMM_DEFAULT_S= MBASE + SMRAM_SAVE_STATE_MAP_OFFSET); + CpuState->x86.SMBASE =3D (UINT32)CpuHotPlugData->SmBase[CpuIndex]; + } =20 // // Intel(R) 64 and IA-32 Architectures Software Developer's Manual // Volume 3C, Section 35.2 MSRs in the Intel(R) Core(TM) 2 Processor Fam= ily // diff --git a/UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.inf b/U= efiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.inf index 9ac7dde78f..082e142580 100644 --- a/UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.inf +++ b/UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.inf @@ -32,10 +32,13 @@ BaseLib PcdLib MemoryAllocationLib DebugLib =20 +[Guids] + gSmmRelocationInfoHobGuid ## CONSUMES + [Pcd] gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber ## SOME= TIMES_CONSUMES =20 [FeaturePcd] gUefiCpuPkgTokenSpaceGuid.PcdSmrrEnable ## CONSUMES diff --git a/UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLibStm.inf = b/UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLibStm.inf index 86d367e0a0..a9d9ab4972 100644 --- a/UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLibStm.inf +++ b/UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLibStm.inf @@ -62,10 +62,11 @@ =20 [Guids] gMsegSmramGuid ## SOMETIMES_CONSUMES ## HOB gEfiAcpi20TableGuid ## SOMETIMES_CONSUMES ## System= Table gEfiAcpi10TableGuid ## SOMETIMES_CONSUMES ## System= Table + gSmmRelocationInfoHobGuid ## CONSUMES =20 [Pcd] gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber ## SOME= TIMES_CONSUMES gUefiCpuPkgTokenSpaceGuid.PcdCpuMsegSize ## SOME= TIMES_CONSUMES gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmStmExceptionStackSize ## SOME= TIMES_CONSUMES diff --git a/UefiCpuPkg/Library/SmmCpuFeaturesLib/StandaloneMmCpuFeaturesLi= b.inf b/UefiCpuPkg/Library/SmmCpuFeaturesLib/StandaloneMmCpuFeaturesLib.inf index b1f60a5505..3a23e62be3 100644 --- a/UefiCpuPkg/Library/SmmCpuFeaturesLib/StandaloneMmCpuFeaturesLib.inf +++ b/UefiCpuPkg/Library/SmmCpuFeaturesLib/StandaloneMmCpuFeaturesLib.inf @@ -33,10 +33,13 @@ BaseLib DebugLib MemoryAllocationLib PcdLib =20 +[Guids] + gSmmRelocationInfoHobGuid ## CONSUMES + [FixedPcd] gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber ## SOME= TIMES_CONSUMES =20 [FeaturePcd] gUefiCpuPkgTokenSpaceGuid.PcdSmrrEnable ## CONSUMES diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/CpuS3.c b/UefiCpuPkg/PiSmmCpuDxeSmm/= CpuS3.c index fb4a44eab6..32eaa62fd4 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/CpuS3.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/CpuS3.c @@ -765,10 +765,13 @@ SmmRestoreCpu ( SMM_S3_RESUME_STATE *SmmS3ResumeState; IA32_DESCRIPTOR Ia32Idtr; IA32_DESCRIPTOR X64Idtr; IA32_IDT_GATE_DESCRIPTOR IdtEntryTable[EXCEPTION_VECTOR_NUMBER]; EFI_STATUS Status; + EFI_HOB_GUID_TYPE* GuidHob; + + GuidHob =3D NULL; =20 DEBUG ((DEBUG_INFO, "SmmRestoreCpu()\n")); =20 mSmmS3Flag =3D TRUE; =20 @@ -822,13 +825,29 @@ SmmRestoreCpu ( // InitializeCpuBeforeRebase (); } =20 // - // Restore SMBASE for BSP and all APs + // Retrive the allocated SmmBase from gSmmRelocationInfoHobGuid + // + GuidHob =3D GetFirstGuidHob (&gSmmRelocationInfoHobGuid); + if (GuidHob !=3D NULL) { + mSmmRelocated =3D TRUE; + } else { + mSmmRelocated =3D FALSE; + } + // - SmmRelocateBases (); + // Check whether Smm Relocation is done or not. + // If not, will do the SmmBases Relocation here!!! + // + if (!mSmmRelocated) { + // + // Restore SMBASE for BSP and all APs + // + SmmRelocateBases (); + } =20 // // Skip initialization if mAcpiCpuData is not valid // if (mAcpiCpuData.NumberOfCpus > 0) { diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c b/UefiCpuPkg/PiSmmCpuDxe= Smm/MpService.c index a0967eb69c..bc670c1baa 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c @@ -1700,10 +1700,45 @@ CpuSmmDebugExit ( CpuSaveState->x64._DR6 =3D AsmReadDr6 (); } } } =20 +/** + Perform SmbaseRelocationPostSmmInit for CpuIndex, this should be done be= fore + normal SMI sources happen. + + @param[in] CpuIndex CPU Index + +**/ +VOID +SmbaseRelocationPostSmmInit ( + IN UINTN CpuIndex + ) +{ + // + // Update SMM IDT entries' code segment and load IDT + // + AsmWriteIdtr (&gcSmiIdtr); + + // + // Initialize SMM specific features on the currently executing CPU + // + SmmCpuFeaturesInitializeProcessor ( + CpuIndex, + (mBspApicId =3D=3D GetApicId ()) ? TRUE : FALSE, + gSmmCpuPrivate->ProcessorInfo, + &mCpuHotPlugData + ); + + if (!mSmmS3Flag) { + // + // Check XD and BTS features on each processor on normal boot + // + CheckFeatureSupported (); + } +} + /** C function for SMI entry, each processor comes here upon SMI trigger. =20 @param CpuIndex CPU Index =20 @@ -1728,10 +1763,29 @@ SmiRendezvous ( // when using on-demand paging for above 4G memory. // Cr2 =3D 0; SaveCr2 (&Cr2); =20 + if (mSmmRelocated && !mSmmInitialized[CpuIndex]) { + // + // Perform SmbaseRelocationPostSmmInit for CpuIndex + // + SmbaseRelocationPostSmmInit (CpuIndex); + + // + // Restore Cr2 + // + RestoreCr2 (Cr2); + + // + // Mark the first SMI init for CpuIndex has been done so as to avoid t= he reentry. + // + mSmmInitialized[CpuIndex] =3D TRUE; + + return; + } + // // Call the user register Startup function first. // if (mSmmMpSyncData->StartupProcedure !=3D NULL) { mSmmMpSyncData->StartupProcedure (mSmmMpSyncData->StartupProcArgs); @@ -1882,13 +1936,13 @@ Exit: // RestoreCr2 (Cr2); } =20 /** - Initialize PackageBsp Info. Processor specified by mPackageFirstThreadIn= dex[PackageIndex] - will do the package-scope register programming. Set default CpuIndex to = (UINT32)-1, which - means not specified yet. + Initialize mPackageFirstThreadIndex Info. Processor specified by mPackag= eFirstThreadIndex[PackageIndex] + will do the package-scope register programming. Set default CpuIndex to = (UINT32)-1, which means not + specified yet. =20 **/ VOID InitPackageFirstThreadIndexInfo ( VOID diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c b/UefiCpuPkg/PiSmmC= puDxeSmm/PiSmmCpuDxeSmm.c index 655175a2c6..c8606f3bd4 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c @@ -83,10 +83,14 @@ EDKII_SMM_MEMORY_ATTRIBUTE_PROTOCOL mSmmMemoryAttribut= e =3D { EdkiiSmmClearMemoryAttributes }; =20 EFI_CPU_INTERRUPT_HANDLER mExternalVectorTable[EXCEPTION_VECTOR_NUMBER]; =20 +BOOLEAN mSmmRelocated =3D FALSE; +BOOLEAN *mSmmInitialized =3D NULL; +UINT32 mBspApicId =3D 0; + // // SMM stack information // UINTN mSmmStackArrayBase; UINTN mSmmStackArrayEnd; @@ -543,28 +547,33 @@ EFIAPI PiCpuSmmEntry ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { - EFI_STATUS Status; - EFI_MP_SERVICES_PROTOCOL *MpServices; - UINTN NumberOfEnabledProcessors; - UINTN Index; - VOID *Buffer; - UINTN BufferPages; - UINTN TileCodeSize; - UINTN TileDataSize; - UINTN TileSize; - UINT8 *Stacks; - VOID *Registration; - UINT32 RegEax; - UINT32 RegEbx; - UINT32 RegEcx; - UINT32 RegEdx; - UINTN FamilyId; - UINTN ModelId; - UINT32 Cr3; + EFI_STATUS Status; + EFI_MP_SERVICES_PROTOCOL *MpServices; + UINTN NumberOfEnabledProcessors; + UINTN Index; + VOID *Buffer; + UINTN BufferPages; + UINTN TileCodeSize; + UINTN TileDataSize; + UINTN TileSize; + UINT8 *Stacks; + VOID *Registration; + UINT32 RegEax; + UINT32 RegEbx; + UINT32 RegEcx; + UINT32 RegEdx; + UINTN FamilyId; + UINTN ModelId; + UINT32 Cr3; + EFI_HOB_GUID_TYPE* GuidHob; + SMM_RELOCATION_INFO_HOB_DATA *SmmRelocationInfoHobData; + + GuidHob =3D NULL; + SmmRelocationInfoHobData =3D NULL; =20 // // Initialize address fixup // PiSmmCpuSmmInitFixupAddress (); @@ -634,18 +643,80 @@ PiCpuSmmEntry ( mMaxNumberOfCpus =3D mNumberOfCpus; } =20 gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus =3D mMaxNumberOfCpus; =20 + // + // Retrieve CPU Family + // + AsmCpuid (CPUID_VERSION_INFO, &RegEax, NULL, NULL, NULL); + FamilyId =3D (RegEax >> 8) & 0xf; + ModelId =3D (RegEax >> 4) & 0xf; + if ((FamilyId =3D=3D 0x06) || (FamilyId =3D=3D 0x0f)) { + ModelId =3D ModelId | ((RegEax >> 12) & 0xf0); + } + + RegEdx =3D 0; + AsmCpuid (CPUID_EXTENDED_FUNCTION, &RegEax, NULL, NULL, NULL); + if (RegEax >=3D CPUID_EXTENDED_CPU_SIG) { + AsmCpuid (CPUID_EXTENDED_CPU_SIG, NULL, NULL, NULL, &RegEdx); + } + + // + // Determine the mode of the CPU at the time an SMI occurs + // Intel(R) 64 and IA-32 Architectures Software Developer's Manual + // Volume 3C, Section 34.4.1.1 + // + mSmmSaveStateRegisterLma =3D EFI_SMM_SAVE_STATE_REGISTER_LMA_32BIT; + if ((RegEdx & BIT29) !=3D 0) { + mSmmSaveStateRegisterLma =3D EFI_SMM_SAVE_STATE_REGISTER_LMA_64BIT; + } + + if (FamilyId =3D=3D 0x06) { + if ((ModelId =3D=3D 0x17) || (ModelId =3D=3D 0x0f) || (ModelId =3D=3D = 0x1c)) { + mSmmSaveStateRegisterLma =3D EFI_SMM_SAVE_STATE_REGISTER_LMA_64BIT; + } + } + + DEBUG ((DEBUG_INFO, "PcdControlFlowEnforcementPropertyMask =3D %d\n", Pc= dGet32 (PcdControlFlowEnforcementPropertyMask))); + if (PcdGet32 (PcdControlFlowEnforcementPropertyMask) !=3D 0) { + AsmCpuid (CPUID_SIGNATURE, &RegEax, NULL, NULL, NULL); + if (RegEax >=3D CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS) { + AsmCpuidEx (CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS, CPUID_STRUCTURE= D_EXTENDED_FEATURE_FLAGS_SUB_LEAF_INFO, NULL, NULL, &RegEcx, &RegEdx); + DEBUG ((DEBUG_INFO, "CPUID[7/0] ECX - 0x%08x\n", RegEcx)); + DEBUG ((DEBUG_INFO, " CET_SS - 0x%08x\n", RegEcx & CPUID_CET_SS)); + DEBUG ((DEBUG_INFO, " CET_IBT - 0x%08x\n", RegEdx & CPUID_CET_IBT)); + if ((RegEcx & CPUID_CET_SS) =3D=3D 0) { + mCetSupported =3D FALSE; + PatchInstructionX86 (mPatchCetSupported, mCetSupported, 1); + } + + if (mCetSupported) { + AsmCpuidEx (CPUID_EXTENDED_STATE, CPUID_EXTENDED_STATE_SUB_LEAF, N= ULL, &RegEbx, &RegEcx, NULL); + DEBUG ((DEBUG_INFO, "CPUID[D/1] EBX - 0x%08x, ECX - 0x%08x\n", Reg= Ebx, RegEcx)); + AsmCpuidEx (CPUID_EXTENDED_STATE, 11, &RegEax, NULL, &RegEcx, NULL= ); + DEBUG ((DEBUG_INFO, "CPUID[D/11] EAX - 0x%08x, ECX - 0x%08x\n", Re= gEax, RegEcx)); + AsmCpuidEx (CPUID_EXTENDED_STATE, 12, &RegEax, NULL, &RegEcx, NULL= ); + DEBUG ((DEBUG_INFO, "CPUID[D/12] EAX - 0x%08x, ECX - 0x%08x\n", Re= gEax, RegEcx)); + } + } else { + mCetSupported =3D FALSE; + PatchInstructionX86 (mPatchCetSupported, mCetSupported, 1); + } + } else { + mCetSupported =3D FALSE; + PatchInstructionX86 (mPatchCetSupported, mCetSupported, 1); + } + // // The CPU save state and code for the SMI entry point are tiled within = an SMRAM // allocated buffer. The minimum size of this buffer for a uniprocessor= system - // is 32 KB, because the entry point is SMBASE + 32KB, and CPU save stat= e area - // just below SMBASE + 64KB. If more than one CPU is present in the pla= tform, + // is 32 KB, because the entry point is SMBASE + 32KB (8000h), and CPU s= ave state area + // just below SMBASE + 64KB (from FC00 to FFFFh). If more than one CPU = is present in the platform, // then the SMI entry point and the CPU save state areas can be tiles to= minimize // the total amount SMRAM required for all the CPUs. The tile size can = be computed - // by adding the // CPU save state size, any extra CPU specific contex= t, and + // by adding the CPU save state size, any extra CPU specific context, and // the size of code that must be placed at the SMI entry point to transf= er // control to a C function in the native SMM execution mode. This size = is // rounded up to the nearest power of 2 to give the tile size for a each= CPU. // The total amount of memory required is the maximum number of CPUs that // platform supports times the tile size. The picture below shows the t= iling, @@ -657,11 +728,11 @@ PiCpuSmmEntry ( // | CPU m+1 Extra Data | // +-----------------------------+ // | Padding | // +-----------------------------+ // | CPU 2m SMI Entry | - // +#############################+ <-- Base of allocated buffer + 64 KB + // +#############################+ // | CPU m-1 Save State | // +-----------------------------+ // | CPU m-1 Extra Data | // +-----------------------------+ // | Padding | @@ -675,19 +746,19 @@ PiCpuSmmEntry ( // | CPU 2 Extra Data | // +-----------------------------+ // | Padding | // +-----------------------------+ // | CPU m+1 SMI Entry | - // +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D+ <-- Base of allocated buffer + 32 KB + // +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D+ <-- Base of allocated buffer + 32 KB + TileSize // | CPU 1 Save State | // +-----------------------------+ // | CPU 1 Extra Data | // +-----------------------------+ // | Padding | // +-----------------------------+ // | CPU m SMI Entry | - // +#############################+ <-- Base of allocated buffer + 32 K= B =3D=3D CPU 0 SMBASE + 64 KB + // +#############################+ <-- Base of allocated buffer + 32 K= B (0x8000) =3D=3D CPU 0 SMBASE + 64 KB // | CPU 0 Save State | // +-----------------------------+ // | CPU 0 Extra Data | // +-----------------------------+ // | Padding | @@ -703,73 +774,10 @@ PiCpuSmmEntry ( // | Padding | // +-----------------------------+ // | CPU 0 SMI Entry | // +#############################+ <-- Base of allocated buffer =3D=3D= CPU 0 SMBASE + 32 KB // - - // - // Retrieve CPU Family - // - AsmCpuid (CPUID_VERSION_INFO, &RegEax, NULL, NULL, NULL); - FamilyId =3D (RegEax >> 8) & 0xf; - ModelId =3D (RegEax >> 4) & 0xf; - if ((FamilyId =3D=3D 0x06) || (FamilyId =3D=3D 0x0f)) { - ModelId =3D ModelId | ((RegEax >> 12) & 0xf0); - } - - RegEdx =3D 0; - AsmCpuid (CPUID_EXTENDED_FUNCTION, &RegEax, NULL, NULL, NULL); - if (RegEax >=3D CPUID_EXTENDED_CPU_SIG) { - AsmCpuid (CPUID_EXTENDED_CPU_SIG, NULL, NULL, NULL, &RegEdx); - } - - // - // Determine the mode of the CPU at the time an SMI occurs - // Intel(R) 64 and IA-32 Architectures Software Developer's Manual - // Volume 3C, Section 34.4.1.1 - // - mSmmSaveStateRegisterLma =3D EFI_SMM_SAVE_STATE_REGISTER_LMA_32BIT; - if ((RegEdx & BIT29) !=3D 0) { - mSmmSaveStateRegisterLma =3D EFI_SMM_SAVE_STATE_REGISTER_LMA_64BIT; - } - - if (FamilyId =3D=3D 0x06) { - if ((ModelId =3D=3D 0x17) || (ModelId =3D=3D 0x0f) || (ModelId =3D=3D = 0x1c)) { - mSmmSaveStateRegisterLma =3D EFI_SMM_SAVE_STATE_REGISTER_LMA_64BIT; - } - } - - DEBUG ((DEBUG_INFO, "PcdControlFlowEnforcementPropertyMask =3D %d\n", Pc= dGet32 (PcdControlFlowEnforcementPropertyMask))); - if (PcdGet32 (PcdControlFlowEnforcementPropertyMask) !=3D 0) { - AsmCpuid (CPUID_SIGNATURE, &RegEax, NULL, NULL, NULL); - if (RegEax >=3D CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS) { - AsmCpuidEx (CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS, CPUID_STRUCTURE= D_EXTENDED_FEATURE_FLAGS_SUB_LEAF_INFO, NULL, NULL, &RegEcx, &RegEdx); - DEBUG ((DEBUG_INFO, "CPUID[7/0] ECX - 0x%08x\n", RegEcx)); - DEBUG ((DEBUG_INFO, " CET_SS - 0x%08x\n", RegEcx & CPUID_CET_SS)); - DEBUG ((DEBUG_INFO, " CET_IBT - 0x%08x\n", RegEdx & CPUID_CET_IBT)); - if ((RegEcx & CPUID_CET_SS) =3D=3D 0) { - mCetSupported =3D FALSE; - PatchInstructionX86 (mPatchCetSupported, mCetSupported, 1); - } - - if (mCetSupported) { - AsmCpuidEx (CPUID_EXTENDED_STATE, CPUID_EXTENDED_STATE_SUB_LEAF, N= ULL, &RegEbx, &RegEcx, NULL); - DEBUG ((DEBUG_INFO, "CPUID[D/1] EBX - 0x%08x, ECX - 0x%08x\n", Reg= Ebx, RegEcx)); - AsmCpuidEx (CPUID_EXTENDED_STATE, 11, &RegEax, NULL, &RegEcx, NULL= ); - DEBUG ((DEBUG_INFO, "CPUID[D/11] EAX - 0x%08x, ECX - 0x%08x\n", Re= gEax, RegEcx)); - AsmCpuidEx (CPUID_EXTENDED_STATE, 12, &RegEax, NULL, &RegEcx, NULL= ); - DEBUG ((DEBUG_INFO, "CPUID[D/12] EAX - 0x%08x, ECX - 0x%08x\n", Re= gEax, RegEcx)); - } - } else { - mCetSupported =3D FALSE; - PatchInstructionX86 (mPatchCetSupported, mCetSupported, 1); - } - } else { - mCetSupported =3D FALSE; - PatchInstructionX86 (mPatchCetSupported, mCetSupported, 1); - } - // // Compute tile size of buffer required to hold the CPU SMRAM Save State= Map, extra CPU // specific context start starts at SMBASE + SMM_PSD_OFFSET, and the SMI= entry point. // This size is rounded up to nearest power of 2. // @@ -789,30 +797,51 @@ PiCpuSmmEntry ( // context must be reduced. // ASSERT (TileSize <=3D (SMRAM_SAVE_STATE_MAP_OFFSET + sizeof (SMRAM_SAVE_= STATE_MAP) - SMM_HANDLER_OFFSET)); =20 // - // Allocate buffer for all of the tiles. + // Check whether the Required TileSize is enough. // - // Intel(R) 64 and IA-32 Architectures Software Developer's Manual - // Volume 3C, Section 34.11 SMBASE Relocation - // For Pentium and Intel486 processors, the SMBASE values must be - // aligned on a 32-KByte boundary or the processor will enter shutdown - // state during the execution of a RSM instruction. + if (TileSize > SIZE_8KB) { + DEBUG ((DEBUG_ERROR, "The Range of Smbase in SMRAM is not enough -- Re= quired TileSize =3D 0x%08x, Actual TileSize =3D 0x%08x\n", TileSize, SIZE_8= KB)); + ASSERT (TileSize <=3D SIZE_8KB); + return RETURN_BUFFER_TOO_SMALL; + } + // - // Intel486 processors: FamilyId is 4 - // Pentium processors : FamilyId is 5 + // Retrive the allocated SmmBase from gSmmRelocationInfoHobGuid // - BufferPages =3D EFI_SIZE_TO_PAGES (SIZE_32KB + TileSize * (mMaxNumberOfC= pus - 1)); - if ((FamilyId =3D=3D 4) || (FamilyId =3D=3D 5)) { - Buffer =3D AllocateAlignedCodePages (BufferPages, SIZE_32KB); + GuidHob =3D GetFirstGuidHob (&gSmmRelocationInfoHobGuid); + if (GuidHob !=3D NULL) { + SmmRelocationInfoHobData =3D GET_GUID_HOB_DATA (GuidHob); + + ASSERT (SmmRelocationInfoHobData->NumberOfProcessors =3D=3D mMaxNumber= OfCpus); + mSmmRelocated =3D TRUE; } else { - Buffer =3D AllocateAlignedCodePages (BufferPages, SIZE_4KB); - } + DEBUG ((DEBUG_INFO, "PiCpuStandaloneMmEntry: gSmmRelocationInfoHobGuid= not found!\n")); + // + // Allocate buffer for all of the tiles. + // + // Intel(R) 64 and IA-32 Architectures Software Developer's Manual + // Volume 3C, Section 34.11 SMBASE Relocation + // For Pentium and Intel486 processors, the SMBASE values must be + // aligned on a 32-KByte boundary or the processor will enter shutdo= wn + // state during the execution of a RSM instruction. + // + // Intel486 processors: FamilyId is 4 + // Pentium processors : FamilyId is 5 + // + BufferPages =3D EFI_SIZE_TO_PAGES (SIZE_32KB + TileSize * (mMaxNumberO= fCpus - 1)); + if ((FamilyId =3D=3D 4) || (FamilyId =3D=3D 5)) { + Buffer =3D AllocateAlignedCodePages (BufferPages, SIZE_32KB); + } else { + Buffer =3D AllocateAlignedCodePages (BufferPages, SIZE_4KB); + } =20 - ASSERT (Buffer !=3D NULL); - DEBUG ((DEBUG_INFO, "SMRAM SaveState Buffer (0x%08x, 0x%08x)\n", Buffer,= EFI_PAGES_TO_SIZE (BufferPages))); + ASSERT (Buffer !=3D NULL); + DEBUG ((DEBUG_INFO, "New Allcoated SMRAM SaveState Buffer (0x%08x, 0x%= 08x)\n", Buffer, EFI_PAGES_TO_SIZE (BufferPages))); + } =20 // // Allocate buffer for pointers to array in SMM_CPU_PRIVATE_DATA. // gSmmCpuPrivate->ProcessorInfo =3D (EFI_PROCESSOR_INFORMATION *)AllocateP= ool (sizeof (EFI_PROCESSOR_INFORMATION) * mMaxNumberOfCpus); @@ -843,11 +872,12 @@ PiCpuSmmEntry ( // Retrieve APIC ID of each enabled processor from the MP Services proto= col. // Also compute the SMBASE address, CPU Save State address, and CPU Save= state // size for each CPU in the platform // for (Index =3D 0; Index < mMaxNumberOfCpus; Index++) { - mCpuHotPlugData.SmBase[Index] =3D (UINTN)Buffer + Index * Ti= leSize - SMM_HANDLER_OFFSET; + mCpuHotPlugData.SmBase[Index] =3D mSmmRelocated ? SmmRelocationInfoHob= Data->SmBase[Index] : (UINTN)Buffer + Index * TileSize - SMM_HANDLER_OFFSET; + gSmmCpuPrivate->CpuSaveStateSize[Index] =3D sizeof (SMRAM_SAVE_STATE_M= AP); gSmmCpuPrivate->CpuSaveState[Index] =3D (VOID *)(mCpuHotPlugData.S= mBase[Index] + SMRAM_SAVE_STATE_MAP_OFFSET); gSmmCpuPrivate->Operation[Index] =3D SmmCpuNone; =20 if (Index < mNumberOfCpus) { @@ -956,21 +986,27 @@ PiCpuSmmEntry ( // Initialize IDT // InitializeSmmIdt (); =20 // - // Relocate SMM Base addresses to the ones allocated from SMRAM + // Check whether Smm Relocation is done or not. + // If not, will do the SmmBases Relocation here!!! // - mRebased =3D (BOOLEAN *)AllocateZeroPool (sizeof (BOOLEAN) * mMaxNumberO= fCpus); - ASSERT (mRebased !=3D NULL); - SmmRelocateBases (); + if (!mSmmRelocated) { + // + // Relocate SMM Base addresses to the ones allocated from SMRAM + // + mRebased =3D (BOOLEAN*)AllocateZeroPool (sizeof (BOOLEAN) * mMaxNumber= OfCpus); + ASSERT (mRebased !=3D NULL); + SmmRelocateBases (); =20 - // - // Call hook for BSP to perform extra actions in normal mode after all - // SMM base addresses have been relocated on all CPUs - // - SmmCpuFeaturesSmmRelocationComplete (); + // + // Call hook for BSP to perform extra actions in normal mode after all + // SMM base addresses have been relocated on all CPUs + // + SmmCpuFeaturesSmmRelocationComplete (); + } =20 DEBUG ((DEBUG_INFO, "mXdSupported - 0x%x\n", mXdSupported)); =20 // // SMM Time initialization @@ -997,10 +1033,42 @@ PiCpuSmmEntry ( ); } } } =20 + // + // For relocated SMBASE, some MSRs & CSRs are still required to be confi= gured in SMM Mode for SMM Initialization. + // Those MSRs & CSRs must be configured before normal SMI sources happen. + // So, here is to issue SMI IPI (All Excluding Self SMM IPI + BSP SMM I= PI) for SMM init + // + if (mSmmRelocated) { + mSmmInitialized =3D (BOOLEAN *)AllocateZeroPool (sizeof (BOOLEAN) * mM= axNumberOfCpus); + ASSERT (mSmmInitialized !=3D NULL); + + mBspApicId =3D GetApicId (); + + // + // Issue SMI IPI (All Excluding Self SMM IPI + BSP SMM IPI) for SMM in= it + // + SendSmiIpi (mBspApicId); + SendSmiIpiAllExcludingSelf (); + + // + // Wait for all processors to finish its 1st SMI + // + for (Index =3D 0; Index < mNumberOfCpus; Index++) { + while (!mSmmInitialized[Index]) { + } + } + + // + // Call hook for BSP to perform extra actions in normal mode after all + // SMM base addresses have been relocated on all CPUs + // + SmmCpuFeaturesSmmRelocationComplete (); + } + // // Fill in SMM Reserved Regions // gSmmCpuPrivate->SmmReservedSmramRegion[0].SmramReservedStart =3D 0; gSmmCpuPrivate->SmmReservedSmramRegion[0].SmramReservedSize =3D 0; diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h b/UefiCpuPkg/PiSmmC= puDxeSmm/PiSmmCpuDxeSmm.h index 5f0a38e400..4ccaba82f5 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h @@ -23,10 +23,11 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include =20 #include #include #include +#include =20 #include #include #include #include @@ -400,10 +401,14 @@ WriteSaveStateRegister ( IN EFI_SMM_SAVE_STATE_REGISTER Register, IN UINTN Width, IN CONST VOID *Buffer ); =20 +extern BOOLEAN mSmmRelocated; +extern BOOLEAN *mSmmInitialized; +extern UINT32 mBspApicId; + extern CONST UINT8 gcSmmInitTemplate[]; extern CONST UINT16 gcSmmInitSize; X86_ASSEMBLY_PATCH_LABEL gPatchSmmCr0; extern UINT32 mSmmCr0; X86_ASSEMBLY_PATCH_LABEL gPatchSmmCr3; @@ -1486,13 +1491,13 @@ RegisterStartupProcedure ( IN EFI_AP_PROCEDURE Procedure, IN OUT VOID *ProcedureArguments OPTIONAL ); =20 /** - Initialize PackageBsp Info. Processor specified by mPackageFirstThreadIn= dex[PackageIndex] - will do the package-scope register programming. Set default CpuIndex to = (UINT32)-1, which - means not specified yet. + Initialize mPackageFirstThreadIndex Info. Processor specified by mPackag= eFirstThreadIndex[PackageIndex] + will do the package-scope register programming. Set default CpuIndex to = (UINT32)-1, which means not + specified yet. =20 **/ VOID InitPackageFirstThreadIndexInfo ( VOID diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf b/UefiCpuPkg/PiSm= mCpuDxeSmm/PiSmmCpuDxeSmm.inf index b4b327f60c..7b6f52ef6f 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf @@ -112,10 +112,11 @@ =20 [Guids] gEfiAcpiVariableGuid ## SOMETIMES_CONSUMES ## HOB # = it is used for S3 boot. gEdkiiPiSmmMemoryAttributesTableGuid ## CONSUMES ## SystemTable gEfiMemoryAttributesTableGuid ## CONSUMES ## SystemTable + gSmmRelocationInfoHobGuid ## CONSUMES =20 [FeaturePcd] gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmDebug ## CONS= UMES gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmBlockStartupThisAp ## CONS= UMES gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmEnableBspElection ## CONS= UMES diff --git a/UefiCpuPkg/UefiCpuPkg.dec b/UefiCpuPkg/UefiCpuPkg.dec index cff239d528..d46791eb81 100644 --- a/UefiCpuPkg/UefiCpuPkg.dec +++ b/UefiCpuPkg/UefiCpuPkg.dec @@ -76,10 +76,13 @@ gEdkiiCpuFeaturesInitDoneGuid =3D { 0xc77c3a41, 0x61ab, 0x4143, { 0x98,= 0x3e, 0x33, 0x39, 0x28, 0x6, 0x28, 0xe5 }} =20 ## Include/Guid/MicrocodePatchHob.h gEdkiiMicrocodePatchHobGuid =3D { 0xd178f11d, 0x8716, 0x418e, { 0xa1,= 0x31, 0x96, 0x7d, 0x2a, 0xc4, 0x28, 0x43 }} =20 + ## Include/Guid/SmmRelocationInfoHob.h + gSmmRelocationInfoHobGuid =3D { 0xc2217ba7, 0x03bb, 0x4f63, {0xa6, = 0x47, 0x7c, 0x25, 0xc5, 0xfc, 0x9d, 0x73 }} + [Protocols] ## Include/Protocol/SmmCpuService.h gEfiSmmCpuServiceProtocolGuid =3D { 0x1d202cab, 0xc8ab, 0x4d5c, { 0x94= , 0xf7, 0x3c, 0xfc, 0xc0, 0xd3, 0xd3, 0x35 }} gEdkiiSmmCpuRendezvousProtocolGuid =3D { 0xaa00d50b, 0x4911, 0x428f, { 0= xb9, 0x1a, 0xa5, 0x9d, 0xdb, 0x13, 0xe2, 0x4c }} =20 --=20 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 (#97748): https://edk2.groups.io/g/devel/message/97748 Mute This Topic: https://groups.io/mt/95858804/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-