From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) by mx.groups.io with SMTP id smtpd.web11.4672.1609915710290802959 for ; Tue, 05 Jan 2021 22:48:30 -0800 Authentication-Results: mx.groups.io; dkim=missing; spf=pass (domain: intel.com, ip: 192.55.52.115, mailfrom: star.zeng@intel.com) IronPort-SDR: 3BvoNFwNi2q22u+7COtbNbyD629aRu9qvE7VSYjoHmv1DxhYaTIGr+pXJ5lYP0zrFU7dMWaQsh GShRM2JhOkPw== X-IronPort-AV: E=McAfee;i="6000,8403,9855"; a="176457293" X-IronPort-AV: E=Sophos;i="5.78,479,1599548400"; d="scan'208";a="176457293" Received: from fmsmga006.fm.intel.com ([10.253.24.20]) by fmsmga103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jan 2021 22:48:29 -0800 IronPort-SDR: J3Co/40r9ncnlF4lNKzsezwOf/BYtL7MFv7wuMeoFVRumhUvYid/1csI8RvgUsPLTFr3hre4rf 4S+ElIh6uh7Q== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.78,479,1599548400"; d="scan'208";a="567328714" Received: from shwdeopenpsi068.ccr.corp.intel.com ([10.239.158.37]) by fmsmga006.fm.intel.com with ESMTP; 05 Jan 2021 22:48:27 -0800 From: "Zeng, Star" To: devel@edk2.groups.io Cc: Star Zeng , Ray Ni , Eric Dong , Laszlo Ersek Subject: [PATCH V2] UefiCpuPkg PiSmmCpuDxeSmm: Reduce SMRAM consumption in CpuS3.c Date: Wed, 6 Jan 2021 14:48:25 +0800 Message-Id: <20210106064825.18984-1-star.zeng@intel.com> X-Mailer: git-send-email 2.21.0.windows.1 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit This patch makes two refinements to reduce SMRAM consumption in CpuS3.c. 1. Only do CopyRegisterTable() when register table is not empty, IsRegisterTableEmpty() is created to check whether the register table is empty or not. Take empty PreSmmInitRegisterTable as example, about 24K SMRAM consumption could be reduced when mAcpiCpuData.NumberOfCpus=1024. sizeof (CPU_REGISTER_TABLE) = 24 mAcpiCpuData.NumberOfCpus = 1024 = 1K mAcpiCpuData.NumberOfCpus * sizeof (CPU_REGISTER_TABLE) = 24K 2. Only copy table entries buffer instead of whole buffer. AllocatedSize in SourceRegisterTableList is the whole buffer size. Actually, only the table entries buffer needs to be copied, and the size is TableLength * sizeof (CPU_REGISTER_TABLE_ENTRY). Take AllocatedSize=0x1000=4096, TableLength=100 and NumberOfCpus=1024 as example, about 1696K SMRAM consumption could be reduced. sizeof (CPU_REGISTER_TABLE_ENTRY) = 24 TableLength = 100 TableLength * sizeof (CPU_REGISTER_TABLE_ENTRY) = 2400 AllocatedSize = 0x1000 = 4096 AllocatedSize - TableLength * sizeof (CPU_REGISTER_TABLE_ENTRY) = 4096 - 2400 = 1696 NumberOfCpus = 1024 = 1K NumberOfCpus * (AllocatedSize - TableLength * sizeof (CPU_REGISTER_TABLE_ENTRY)) = 1696K This patch also corrects the CopyRegisterTable() function description. Signed-off-by: Star Zeng Cc: Ray Ni Cc: Eric Dong Cc: Laszlo Ersek --- UefiCpuPkg/PiSmmCpuDxeSmm/CpuS3.c | 71 +++++++++++++++++++++++-------- 1 file changed, 54 insertions(+), 17 deletions(-) diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/CpuS3.c b/UefiCpuPkg/PiSmmCpuDxeSmm/CpuS3.c index 9592430636ec..9b1f952c8a74 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/CpuS3.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/CpuS3.c @@ -1,7 +1,7 @@ /** @file Code for Processor S3 restoration -Copyright (c) 2006 - 2020, Intel Corporation. All rights reserved.
+Copyright (c) 2006 - 2021, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -487,6 +487,9 @@ SetRegister ( } else { RegisterTables = (CPU_REGISTER_TABLE *)(UINTN)mAcpiCpuData.RegisterTable; } + if (RegisterTables == NULL) { + return; + } InitApicId = GetInitialApicId (); RegisterTable = NULL; @@ -948,7 +951,7 @@ InitSmmS3ResumeState ( } /** - Copy register table from ACPI NVS memory into SMRAM. + Copy register table from non-SMRAM into SMRAM. @param[in] DestinationRegisterTableList Points to destination register table. @param[in] SourceRegisterTableList Points to source register table. @@ -967,7 +970,8 @@ CopyRegisterTable ( CopyMem (DestinationRegisterTableList, SourceRegisterTableList, NumberOfCpus * sizeof (CPU_REGISTER_TABLE)); for (Index = 0; Index < NumberOfCpus; Index++) { - if (DestinationRegisterTableList[Index].AllocatedSize != 0) { + if (DestinationRegisterTableList[Index].TableLength != 0) { + DestinationRegisterTableList[Index].AllocatedSize = DestinationRegisterTableList[Index].TableLength * sizeof (CPU_REGISTER_TABLE_ENTRY); RegisterTableEntry = AllocateCopyPool ( DestinationRegisterTableList[Index].AllocatedSize, (VOID *)(UINTN)SourceRegisterTableList[Index].RegisterTableEntry @@ -978,6 +982,31 @@ CopyRegisterTable ( } } +/** + Check whether the register table is empty or not. + + @param[in] RegisterTable Point to the register table. + + @retval TRUE The register table is empty. + @retval FALSE The register table is not empty. +**/ +BOOLEAN +IsRegisterTableEmpty ( + IN CPU_REGISTER_TABLE *RegisterTable, + IN UINT32 NumberOfCpus + ) +{ + UINTN Index; + + for (Index = 0; Index < NumberOfCpus; Index++) { + if (RegisterTable[Index].TableLength != 0) { + return FALSE; + } + } + + return TRUE; +} + /** Get ACPI CPU data. @@ -1032,23 +1061,31 @@ GetAcpiCpuData ( CopyMem ((VOID *)(UINTN)mAcpiCpuData.IdtrProfile, (VOID *)(UINTN)AcpiCpuData->IdtrProfile, sizeof (IA32_DESCRIPTOR)); - mAcpiCpuData.PreSmmInitRegisterTable = (EFI_PHYSICAL_ADDRESS)(UINTN)AllocatePool (mAcpiCpuData.NumberOfCpus * sizeof (CPU_REGISTER_TABLE)); - ASSERT (mAcpiCpuData.PreSmmInitRegisterTable != 0); + if (!IsRegisterTableEmpty ((CPU_REGISTER_TABLE *)(UINTN)AcpiCpuData->PreSmmInitRegisterTable, mAcpiCpuData.NumberOfCpus)) { + mAcpiCpuData.PreSmmInitRegisterTable = (EFI_PHYSICAL_ADDRESS)(UINTN)AllocatePool (mAcpiCpuData.NumberOfCpus * sizeof (CPU_REGISTER_TABLE)); + ASSERT (mAcpiCpuData.PreSmmInitRegisterTable != 0); - CopyRegisterTable ( - (CPU_REGISTER_TABLE *)(UINTN)mAcpiCpuData.PreSmmInitRegisterTable, - (CPU_REGISTER_TABLE *)(UINTN)AcpiCpuData->PreSmmInitRegisterTable, - mAcpiCpuData.NumberOfCpus - ); + CopyRegisterTable ( + (CPU_REGISTER_TABLE *)(UINTN)mAcpiCpuData.PreSmmInitRegisterTable, + (CPU_REGISTER_TABLE *)(UINTN)AcpiCpuData->PreSmmInitRegisterTable, + mAcpiCpuData.NumberOfCpus + ); + } else { + mAcpiCpuData.PreSmmInitRegisterTable = 0; + } - mAcpiCpuData.RegisterTable = (EFI_PHYSICAL_ADDRESS)(UINTN)AllocatePool (mAcpiCpuData.NumberOfCpus * sizeof (CPU_REGISTER_TABLE)); - ASSERT (mAcpiCpuData.RegisterTable != 0); + if (!IsRegisterTableEmpty ((CPU_REGISTER_TABLE *)(UINTN)AcpiCpuData->RegisterTable, mAcpiCpuData.NumberOfCpus)) { + mAcpiCpuData.RegisterTable = (EFI_PHYSICAL_ADDRESS)(UINTN)AllocatePool (mAcpiCpuData.NumberOfCpus * sizeof (CPU_REGISTER_TABLE)); + ASSERT (mAcpiCpuData.RegisterTable != 0); - CopyRegisterTable ( - (CPU_REGISTER_TABLE *)(UINTN)mAcpiCpuData.RegisterTable, - (CPU_REGISTER_TABLE *)(UINTN)AcpiCpuData->RegisterTable, - mAcpiCpuData.NumberOfCpus - ); + CopyRegisterTable ( + (CPU_REGISTER_TABLE *)(UINTN)mAcpiCpuData.RegisterTable, + (CPU_REGISTER_TABLE *)(UINTN)AcpiCpuData->RegisterTable, + mAcpiCpuData.NumberOfCpus + ); + } else { + mAcpiCpuData.RegisterTable = 0; + } // // Copy AP's GDT, IDT and Machine Check handler into SMRAM. -- 2.21.0.windows.1