From nobody Mon Apr 29 22:06:32 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of groups.io designates 66.175.222.12 as permitted sender) client-ip=66.175.222.12; envelope-from=bounce+27952+41553+1787277+3901457@groups.io; helo=web01.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zoho.com: domain of groups.io designates 66.175.222.12 as permitted sender) smtp.mailfrom=bounce+27952+41553+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1559090765; cv=none; d=zoho.com; s=zohoarc; b=Qzl40MK32CbhJDWa/rKqDHE0E7k5G4xtSmJ8uab4/4G1JdFpyDZa23KL9VueMyP2nOgb2cJrxwksOGsmXx2xuc9hXLj+r4YZWpprz/eliGTWMyb6fgD2hGwJo1uM5Fej8sTgiKl4mOyJYqPZaNkhE1keG56nPCyurhA/0tDgOk4= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1559090765; h=Content-Transfer-Encoding:Cc:Date:From:List-Id:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:Sender:Subject:To:ARC-Authentication-Results; bh=la1gmtpPjYuVHIe7XcyGeKE75V8h0FvcVKbJ2nGyR8A=; b=obsklDLZ02EuKdpEmYXEgUhVHxqV8fggBv++p72tC0OVSAzQl8gZ7nBYie1xYodbyu9tlJO7Q3txsn/eYntYauLoCHwXojMt5oU5P3jbB/Z9/p9HGjkeshMuMUV32PBlR+PY6CbeWOQNZlvX9nDq9670rO17iDs4ROXeK9d+SRw= ARC-Authentication-Results: i=1; mx.zoho.com; dkim=pass; spf=pass (zoho.com: domain of groups.io designates 66.175.222.12 as permitted sender) smtp.mailfrom=bounce+27952+41553+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) header.from= Received: from web01.groups.io (web01.groups.io [66.175.222.12]) by mx.zohomail.com with SMTPS id 1559090765552246.47398736652065; Tue, 28 May 2019 17:46:05 -0700 (PDT) Return-Path: X-Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) by groups.io with SMTP; Tue, 28 May 2019 17:46:04 -0700 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False X-Received: from fmsmga006.fm.intel.com ([10.253.24.20]) by fmsmga104.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 28 May 2019 17:46:04 -0700 X-ExtLoop1: 1 X-Received: from fieedk001.ccr.corp.intel.com ([10.239.33.119]) by fmsmga006.fm.intel.com with ESMTP; 28 May 2019 17:46:02 -0700 From: "Gao, Zhichao" To: devel@edk2.groups.io Cc: Bret Barkelew , Jian J Wang , Hao A Wu , Ray Ni , Star Zeng , Liming Gao , Sean Brogan , Michael Turner , Zhichao gao Subject: [edk2-devel] [PATCH] MdeModulePkg/CapsulePei: Optimize the CapsulePei Date: Wed, 29 May 2019 08:45:55 +0800 Message-Id: <20190529004555.45364-1-zhichao.gao@intel.com> MIME-Version: 1.0 Precedence: Bulk List-Unsubscribe: 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,zhichao.gao@intel.com Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1559090764; bh=X3eX5SCDPMvCilonCi9Jv60f4TdnvvnKFuNtMbXoYgQ=; h=Cc:Date:From:Reply-To:Subject:To; b=gXG6LXmMJ4GFpuZcI+AkQ2t9DGkZxE1FvpWNT0X9fQkJzwRWP5yDXipSY6h+t/wWbzs vyl+2ZvwQ4TzOHlWlG5jpXPtmBoAeApnJZgYDNnyiQDuT/Zsvmp0zLNw7nZDLIp+9pobz V+HYVclCN/8nvvPktv5eL3TyW4eCSFfdplQ= X-ZohoMail-DKIM: pass (identity @groups.io) Content-Type: text/plain; charset="utf-8" From: Bret Barkelew REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3D1853 Sperate the capsule check function from GetCapsuleDescriptors and name it to AreCapsulesStaged. Rename GetCapsuleDescriptors to GetScatterGatherHeadEntries. And optimize its to remove the duplicated code. Cc: Jian J Wang Cc: Hao A Wu Cc: Ray Ni Cc: Star Zeng Cc: Liming Gao Cc: Sean Brogan Cc: Michael Turner Cc: Bret Barkelew Signed-off-by: Zhichao gao --- MdeModulePkg/Universal/CapsulePei/Capsule.h | 3 +- .../Universal/CapsulePei/CapsulePei.inf | 3 +- .../Universal/CapsulePei/UefiCapsule.c | 357 ++++++++++-------- 3 files changed, 194 insertions(+), 169 deletions(-) diff --git a/MdeModulePkg/Universal/CapsulePei/Capsule.h b/MdeModulePkg/Uni= versal/CapsulePei/Capsule.h index baf40423af..fc20dd8b92 100644 --- a/MdeModulePkg/Universal/CapsulePei/Capsule.h +++ b/MdeModulePkg/Universal/CapsulePei/Capsule.h @@ -1,6 +1,6 @@ /** @file =20 -Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
+Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.
=20 SPDX-License-Identifier: BSD-2-Clause-Patent =20 @@ -30,6 +30,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include #include +#include #include #include "Common/CommonHeader.h" =20 diff --git a/MdeModulePkg/Universal/CapsulePei/CapsulePei.inf b/MdeModulePk= g/Universal/CapsulePei/CapsulePei.inf index 5d43df3075..9c88b3986f 100644 --- a/MdeModulePkg/Universal/CapsulePei/CapsulePei.inf +++ b/MdeModulePkg/Universal/CapsulePei/CapsulePei.inf @@ -6,7 +6,7 @@ # This external input must be validated carefully to avoid security issue= like # buffer overflow, integer overflow. # -# Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
+# Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.
# Copyright (c) 2017, AMD Incorporated. All rights reserved.
# # SPDX-License-Identifier: BSD-2-Clause-Patent @@ -43,6 +43,7 @@ BaseLib HobLib BaseMemoryLib + MemoryAllocationLib PeiServicesLib PeimEntryPoint DebugLib diff --git a/MdeModulePkg/Universal/CapsulePei/UefiCapsule.c b/MdeModulePkg= /Universal/CapsulePei/UefiCapsule.c index e967599e96..2d003369ca 100644 --- a/MdeModulePkg/Universal/CapsulePei/UefiCapsule.c +++ b/MdeModulePkg/Universal/CapsulePei/UefiCapsule.c @@ -1,7 +1,7 @@ /** @file Capsule update PEIM for UEFI2.0 =20 -Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
+Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.
Copyright (c) 2017, AMD Incorporated. All rights reserved.
=20 SPDX-License-Identifier: BSD-2-Clause-Patent @@ -10,6 +10,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent =20 #include "Capsule.h" =20 +#define DEFAULT_SG_LIST_HEADS (20) + #ifdef MDE_CPU_IA32 // // Global Descriptor Table (GDT) @@ -791,30 +793,89 @@ BuildMemoryResourceDescriptor ( } =20 /** - Checks for the presence of capsule descriptors. - Get capsule descriptors from variable CapsuleUpdateData, CapsuleUpdateDa= ta1, CapsuleUpdateData2... - and save to DescriptorBuffer. + Check if the capsules are staged. =20 - @param DescriptorBuffer Pointer to the capsule descriptors + @retval TRUE The capsules are staged. + @retval FALSE The capsules are not staged. + +**/ +BOOLEAN +EFIAPI +AreCapsulesStaged ( + VOID + ) +{ + EFI_STATUS Status; + UINTN Size; + EFI_PEI_READ_ONLY_VARIABLE2_PPI *PPIVariableServices; + EFI_PHYSICAL_ADDRESS CapsuleDataPtr64; + + CapsuleDataPtr64 =3D 0; + + Status =3D PeiServicesLocatePpi ( + &gEfiPeiReadOnlyVariable2PpiGuid, + 0, + NULL, + (VOID **)&PPIVariableServices + ); + + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Failed to find ReadOnlyVariable2PPI\n")); + return FALSE; + } + + // + // Check for Update capsule + // + Size =3D sizeof (CapsuleDataPtr64); + Status =3D PPIVariableServices->GetVariable( + PPIVariableServices, + EFI_CAPSULE_VARIABLE_NAME, + &gEfiCapsuleVendorGuid, + NULL, + &Size, + (VOID *)&CapsuleDataPtr64 + ); + + if (!EFI_ERROR (Status)) { + return TRUE; + } + + return FALSE; +} + +/** + Check all the variables for SG list heads and get the count and addresse= s. + + @param ListLength A pointer would return the SG list lengt= h. + @param HeadList A ponter to the capsule SG list. + + @retval EFI_SUCCESS a valid capsule is present + @retval EFI_NOT_FOUND if a valid capsule is not present + @retval EFI_INVALID_PARAMETER the input parameter is invalid + @retval EFI_OUT_OF_RESOURCE fail to allocate memory =20 - @retval EFI_SUCCESS a valid capsule is present - @retval EFI_NOT_FOUND if a valid capsule is not present **/ EFI_STATUS -GetCapsuleDescriptors ( - IN EFI_PHYSICAL_ADDRESS *DescriptorBuffer +EFIAPI +GetScatterGatherHeadEntries ( + OUT UINTN *ListLength, + OUT EFI_PHYSICAL_ADDRESS **HeadList ) { - EFI_STATUS Status; - UINTN Size; - UINTN Index; - UINTN TempIndex; - UINTN ValidIndex; - BOOLEAN Flag; - CHAR16 CapsuleVarName[30]; - CHAR16 *TempVarName; - EFI_PHYSICAL_ADDRESS CapsuleDataPtr64; - EFI_PEI_READ_ONLY_VARIABLE2_PPI *PPIVariableServices; + EFI_STATUS Status; + UINTN Size; + UINTN Index; + UINTN TempIndex; + UINTN ValidIndex; + BOOLEAN Flag; + CHAR16 CapsuleVarName[30]; + CHAR16 *TempVarName; + EFI_PHYSICAL_ADDRESS CapsuleDataPtr64; + EFI_PEI_READ_ONLY_VARIABLE2_PPI *PPIVariableServices; + EFI_PHYSICAL_ADDRESS *TempList; + EFI_PHYSICAL_ADDRESS *EnlargedTempList; + UINTN TempListLength; =20 Index =3D 0; TempVarName =3D NULL; @@ -822,87 +883,118 @@ GetCapsuleDescriptors ( ValidIndex =3D 0; CapsuleDataPtr64 =3D 0; =20 + if ((ListLength =3D=3D NULL) || (HeadList =3D=3D NULL)) { + DEBUG ((DEBUG_ERROR, "%a Invalid parameters. Inputs can't be NULL\n",= __FUNCTION__)); + ASSERT (ListLength !=3D NULL); + ASSERT (HeadList !=3D NULL); + return EFI_INVALID_PARAMETER; + } + + *ListLength =3D 0; + *HeadList =3D NULL; + Status =3D PeiServicesLocatePpi ( &gEfiPeiReadOnlyVariable2PpiGuid, 0, NULL, (VOID **) &PPIVariableServices ); - if (Status =3D=3D EFI_SUCCESS) { - StrCpyS (CapsuleVarName, sizeof(CapsuleVarName)/sizeof(CHAR16), EFI_CA= PSULE_VARIABLE_NAME); - TempVarName =3D CapsuleVarName + StrLen (CapsuleVarName); + + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Failed to find ReadOnlyVariable2PPI: %r\n", Stat= us)); + return Status; + } + + // + // Allocate memory for sg list head + // + TempListLength =3D DEFAULT_SG_LIST_HEADS * sizeof (EFI_PHYSICAL_ADDRESS); + TempList =3D AllocateZeroPool (TempListLength); + if (TempList =3D=3D NULL) { + DEBUG((DEBUG_ERROR, "Failed to allocate memory\n")); + return EFI_OUT_OF_RESOURCES; + } + + // + // Setup var name buffer for update capsules + // + StrCpyS (CapsuleVarName, sizeof (CapsuleVarName) / sizeof (CHAR16), EFI_= CAPSULE_VARIABLE_NAME); + TempVarName =3D CapsuleVarName + StrLen (CapsuleVarName); + while (TRUE) { + if (Index !=3D 0) { + UnicodeValueToStringS ( + TempVarName, + (sizeof(CapsuleVarName) - ((StrLen(CapsuleVarName) + 1) * sizeof(C= HAR16))), + 0, + Index, + 0 + ); + } + Size =3D sizeof (CapsuleDataPtr64); - while (1) { - if (Index =3D=3D 0) { - // - // For the first Capsule Image - // - Status =3D PPIVariableServices->GetVariable ( - PPIVariableServices, - CapsuleVarName, - &gEfiCapsuleVendorGuid, - NULL, - &Size, - (VOID *) &CapsuleDataPtr64 - ); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_INFO, "Capsule -- capsule variable not set\n")); - return EFI_NOT_FOUND; - } - // - // We have a chicken/egg situation where the memory init code need= s to - // know the boot mode prior to initializing memory. For this case,= our - // validate function will fail. We can detect if this is the case = if blocklist - // pointer is null. In that case, return success since we know tha= t the - // variable is set. - // - if (DescriptorBuffer =3D=3D NULL) { - return EFI_SUCCESS; - } - } else { - UnicodeValueToStringS ( - TempVarName, - sizeof (CapsuleVarName) - ((UINTN)TempVarName - (UINTN)CapsuleVa= rName), - 0, - Index, - 0 - ); - Status =3D PPIVariableServices->GetVariable ( - PPIVariableServices, - CapsuleVarName, - &gEfiCapsuleVendorGuid, - NULL, - &Size, - (VOID *) &CapsuleDataPtr64 - ); - if (EFI_ERROR (Status)) { - break; - } + Status =3D PPIVariableServices->GetVariable ( + PPIVariableServices, + CapsuleVarName, + &gEfiCapsuleVendorGuid, + NULL, + &Size, + (VOID *)&CapsuleDataPtr64 + ); =20 - // - // If this BlockList has been linked before, skip this variable - // - Flag =3D FALSE; - for (TempIndex =3D 0; TempIndex < ValidIndex; TempIndex++) { - if (DescriptorBuffer[TempIndex] =3D=3D CapsuleDataPtr64) { - Flag =3D TRUE; - break; - } - } - if (Flag) { - Index ++; - continue; - } + if (EFI_ERROR (Status)) { + if (Status !=3D EFI_NOT_FOUND) { + DEBUG ((DEBUG_ERROR, "Unexpected error getting Capsule Update vari= able. Status =3D %r\n")); } + break; + } =20 - // - // Cache BlockList which has been processed - // - DescriptorBuffer[ValidIndex++] =3D CapsuleDataPtr64; - Index ++; + // + // If this BlockList has been linked before, skip this variable + // + Flag =3D FALSE; + for (TempIndex =3D 0; TempIndex < ValidIndex; TempIndex++) { + if (TempList[TempIndex] =3D=3D CapsuleDataPtr64) { + Flag =3D TRUE; + break; + } } + if (Flag) { + Index++; + continue; + } + + // + // The TempList is full, enlarge it + // + if ((ValidIndex + 1) >=3D TempListLength) { + EnlargedTempList =3D AllocateZeroPool (TempListLength * 2); + CopyMem (EnlargedTempList, TempList, TempListLength); + FreePool (TempList); + TempList =3D EnlargedTempList; + TempListLength *=3D 2; + } + + // + // Cache BlockList which has been processed + // + TempList[ValidIndex++] =3D CapsuleDataPtr64; + Index++; + } + + if (ValidIndex =3D=3D 0) { + DEBUG((DEBUG_ERROR, "%a didn't find any SG lists in variables\n", __FU= NCTION__)); + return EFI_NOT_FOUND; } =20 + *HeadList =3D AllocateZeroPool ((ValidIndex + 1) * sizeof (EFI_PHYSICAL_= ADDRESS)); + if (*HeadList =3D=3D NULL) { + DEBUG((DEBUG_ERROR, "Failed to allocate memory\n")); + return EFI_OUT_OF_RESOURCES; + } + + CopyMem (*HeadList, TempList, (ValidIndex) * sizeof (EFI_PHYSICAL_ADDRES= S)); + *ListLength =3D ValidIndex;=20 + return EFI_SUCCESS; } =20 @@ -937,17 +1029,11 @@ CapsuleCoalesce ( IN OUT UINTN *MemorySize ) { - UINTN Index; - UINTN Size; - UINTN VariableCount; - CHAR16 CapsuleVarName[30]; - CHAR16 *TempVarName; - EFI_PHYSICAL_ADDRESS CapsuleDataPtr64; EFI_STATUS Status; EFI_BOOT_MODE BootMode; - EFI_PEI_READ_ONLY_VARIABLE2_PPI *PPIVariableServices; EFI_PHYSICAL_ADDRESS *VariableArrayAddress; MEMORY_RESOURCE_DESCRIPTOR *MemoryResource; + UINTN ListLength; #ifdef MDE_CPU_IA32 UINT16 CoalesceImageMachineType; EFI_PHYSICAL_ADDRESS CoalesceImageEntryPoint; @@ -955,10 +1041,8 @@ CapsuleCoalesce ( EFI_CAPSULE_LONG_MODE_BUFFER LongModeBuffer; #endif =20 - Index =3D 0; - VariableCount =3D 0; - CapsuleVarName[0] =3D 0; - CapsuleDataPtr64 =3D 0; + ListLength =3D 0; + VariableArrayAddress =3D NULL; =20 // // Someone should have already ascertained the boot mode. If it's not @@ -972,74 +1056,11 @@ CapsuleCoalesce ( } =20 // - // User may set the same ScatterGatherList with several different variab= les, - // so cache all ScatterGatherList for check later. + // Get ScatterGatherList // - Status =3D PeiServicesLocatePpi ( - &gEfiPeiReadOnlyVariable2PpiGuid, - 0, - NULL, - (VOID **) &PPIVariableServices - ); + Status =3D GetScatterGatherHeadEntries (&ListLength, &VariableArrayAddre= ss); if (EFI_ERROR (Status)) { - goto Done; - } - Size =3D sizeof (CapsuleDataPtr64); - StrCpyS (CapsuleVarName, sizeof(CapsuleVarName)/sizeof(CHAR16), EFI_CAPS= ULE_VARIABLE_NAME); - TempVarName =3D CapsuleVarName + StrLen (CapsuleVarName); - while (TRUE) { - if (Index > 0) { - UnicodeValueToStringS ( - TempVarName, - sizeof (CapsuleVarName) - ((UINTN)TempVarName - (UINTN)CapsuleVarN= ame), - 0, - Index, - 0 - ); - } - Status =3D PPIVariableServices->GetVariable ( - PPIVariableServices, - CapsuleVarName, - &gEfiCapsuleVendorGuid, - NULL, - &Size, - (VOID *) &CapsuleDataPtr64 - ); - if (EFI_ERROR (Status)) { - // - // There is no capsule variables, quit - // - DEBUG ((DEBUG_INFO,"Capsule variable Index =3D %d\n", Index)); - break; - } - VariableCount++; - Index++; - } - - DEBUG ((DEBUG_INFO,"Capsule variable count =3D %d\n", VariableCount)); - - // - // The last entry is the end flag. - // - Status =3D PeiServicesAllocatePool ( - (VariableCount + 1) * sizeof (EFI_PHYSICAL_ADDRESS), - (VOID **)&VariableArrayAddress - ); - - if (Status !=3D EFI_SUCCESS) { - DEBUG ((DEBUG_ERROR, "AllocatePages Failed!, Status =3D %x\n", Status)= ); - goto Done; - } - - ZeroMem (VariableArrayAddress, (VariableCount + 1) * sizeof (EFI_PHYSICA= L_ADDRESS)); - - // - // Find out if we actually have a capsule. - // GetCapsuleDescriptors depends on variable PPI, so it should run in 32= -bit environment. - // - Status =3D GetCapsuleDescriptors (VariableArrayAddress); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "Fail to find capsule variables.\n")); + DEBUG ((DEBUG_ERROR, "%a failed to get Scatter Gather List Head Entrie= s. Status =3D %r\n", __FUNCTION__, Status)); goto Done; } =20 @@ -1117,9 +1138,11 @@ CheckCapsuleUpdate ( IN EFI_PEI_SERVICES **PeiServices ) { - EFI_STATUS Status; - Status =3D GetCapsuleDescriptors (NULL); - return Status; + if (AreCapsulesStaged ()) { + return EFI_SUCCESS; + } else { + return EFI_NOT_FOUND; + } } /** This function will look at a capsule and determine if it's a test patter= n. --=20 2.21.0.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 (#41553): https://edk2.groups.io/g/devel/message/41553 Mute This Topic: https://groups.io/mt/31828852/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-