From nobody Fri May 3 21:03:35 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+39358+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+39358+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1555912296; cv=none; d=zoho.com; s=zohoarc; b=B9V3UVuiFRj6h3d/NgR+eD3f3CruT963KyMydIBZD58rWs+VZm4FtDvCF57BnGm4gfepjPIewXf6DQfPa0oRXEH/RWNPlslqKDM5lsKkY2gDYGX1v7w0Shpj3g2yF5RpmRWhTNo7U1zvtwLLG6bT9ovwxnKEjMFQtC4C3aRNVDc= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1555912296; h=Content-Transfer-Encoding:Cc:Date:From:List-Id:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:Sender:Subject:To:ARC-Authentication-Results; bh=9Xdw8MwE16bsSmU54Y+SithlcMcyPnl69I/eANbp2c0=; b=dVWlfuxceCNBppNETcxalsDDMMCGBGccv9/UvOQCqq1v8EmYsrcTeI1hkUN6Zye1kj7nwfA/6wJBJiQH1tbkFxRpPd16AW4HQtxgGisLrzjiseiAI//SI39MNKuoeDtzTWXiPmldJPtdPz+tVV/zO6pTJmb+A71lJKvTHVLFqqU= 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+39358+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 1555912296361662.8113834224579; Sun, 21 Apr 2019 22:51:36 -0700 (PDT) Return-Path: X-Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) by groups.io with SMTP; Sun, 21 Apr 2019 22:48:35 -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 fmsmga103.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 21 Apr 2019 22:48:34 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.60,380,1549958400"; d="scan'208";a="339558185" X-Received: from jjin9-mobl.ccr.corp.intel.com ([10.239.192.246]) by fmsmga006.fm.intel.com with ESMTP; 21 Apr 2019 22:48:33 -0700 From: "Eric Jin" To: devel@edk2.groups.io Cc: Michael D Kinney Subject: [edk2-devel] [Staging/Bug_1525_FmpDevicePkg_MultipleControllers][PATCH] MdeModulePkg/EsrtFmpDxe: Detect duplicate GUID/HardwareInstance Date: Mon, 22 Apr 2019 13:48:18 +0800 Message-Id: <20190422054818.1468-1-eric.jin@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,eric.jin@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=1555912295; bh=s5WvyqNv+9P+s+OVEWsvAOqq+sJwoVLGxQ7/AKQ2bA0=; h=Cc:Date:From:Reply-To:Subject:To; b=iuyoxfAWGiSkhSrERICimbF/zVsPz/vrlEVGSAhv77oivg6EzgX2ZKDWUP4ufKH8+eO QMED+Bi2dMSh5x/+fXxZunrZm8qhB6i6bbi8Oqj3QiT+5gIaNQcYoMT/QVfXX7tuq2anv sT/RusgsxG4wJbF1UryhTQfaF+QCwIVHoh8= X-ZohoMail-DKIM: pass (identity @groups.io) Content-Type: text/plain; charset="utf-8" https://bugzilla.tianocore.org/show_bug.cgi?id=3D1525 Fix the following issues identified in #1525: EsrtFmpDxe - The check for more than one instance of the same GUID/HardwareInstance is not being done at the right point. It is being done as EFI_FIRMWARE_IMAGE_DESCRIPTORs are being merged into an ESRT Table Entry. This means a case will be missed if there are 3 EFI_FIRMWARE_IMAGE_DESCRIPTORs with the first and 3rd one being having the same GUID/HardwareInstance. Instead, this check should be performed across all EFI_FIRMWARE_IMAGE_DESCRIPTORs in the entire handle database. Build a table of GUID/HardwareInstance pairs from all the EFI_FIRMWARE_IMAGE_DESCRIPTORs from all FMP instances. If a duplicate is found, then generate a DEBUG_ERROR message, generate an ASSERT(), and ignore the duplicate EFI_FIRMWARE_IMAGE_DESCRIPTOR. Add an internal worker function called FmpGetFirmwareImageDescriptor() that retrieves the list of EFI_FIRMWARE_IMAGE_DESCRIPTORs from a single FMP instance and returns the descriptors in an allocated buffer. This function is used to get the descriptors used to build the table of unique GUID/HardwareInstance pairs. It is then used again to generate the ESRT Table from all the EFI_FIRMWARE_IMAGE_DESCRIPTORs from all the FMP instances. 2 passes are performed so the total number of descriptors is known. This allows the correct sized buffers to always be allocated and the extra logic to grow tables is removed. CC: Eric Jin CC: Michael D Kinney Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Eric Jin Reviewed-by: Michael D Kinney --- MdeModulePkg/Universal/EsrtFmpDxe/EsrtFmp.c | 461 ++++++++++---------- 1 file changed, 238 insertions(+), 223 deletions(-) diff --git a/MdeModulePkg/Universal/EsrtFmpDxe/EsrtFmp.c b/MdeModulePkg/Uni= versal/EsrtFmpDxe/EsrtFmp.c index 848bd44e9d..9c273fe79e 100644 --- a/MdeModulePkg/Universal/EsrtFmpDxe/EsrtFmp.c +++ b/MdeModulePkg/Universal/EsrtFmpDxe/EsrtFmp.c @@ -38,6 +38,22 @@ #include #include =20 +/// +/// Structure for array of unique GUID/HardwareInstance pairs from the +/// current set of EFI_FIRMWARE_IMAGE_DESCRIPTORs from all FMP Protocols. +/// +typedef struct { + /// + /// A unique GUID identifying the firmware image type. + /// + EFI_GUID ImageTypeGuid; + /// + /// An optional number to identify the unique hardware instance within t= he + /// system for devices that may have multiple instances whenever possibl= e. + /// + UINT64 HardwareInstance; +} GUID_HARDWAREINSTANCE_PAIR; + /** Print ESRT to debug console. =20 @@ -50,11 +66,6 @@ PrintTable ( IN EFI_SYSTEM_RESOURCE_TABLE *Table ); =20 -// -// Number of ESRT entries to grow by each time we run out of room -// -#define GROWTH_STEP 10 - /** Install EFI System Resource Table into the UEFI Configuration Table =20 @@ -118,172 +129,129 @@ IsSystemFmp ( } =20 /** - Function to create a single ESRT Entry and add it to the ESRT - given a FMP descriptor. If the guid is already in the ESRT, then the ES= RT - entry is updated. The ESRT will grow if it does not have enough room. - - @param[in, out] Table On input, pointer to the pointer to th= e ESRT. - On output, same as input or pointer to= the pointer - to new enlarged ESRT. - @param[in] FmpImageInfoBuf Pointer to the EFI_FIRMWARE_IMAGE_DESC= RIPTOR. - @param[in] FmpVersion FMP Version. - - @return Status code. + Function to create a single ESRT Entry and add it to the ESRT with + a given FMP descriptor. If the GUID is already in the ESRT, then the ES= RT + entry is updated. + + @param[in,out] Table Pointer to the ESRT Table. + @param[in,out] HardwareInstances Pointer to the GUID_HARDWAREINSTANCE= _PAIR. + @param[in,out] NumberOfDescriptors The number of EFI_FIRMWARE_IMAGE_DES= CRIPTORs. + @param[in] FmpImageInfoBuf Pointer to the EFI_FIRMWARE_IMAGE_DE= SCRIPTOR. + @param[in] FmpVersion FMP Version. + + @retval EFI_SUCCESS FmpImageInfoBuf was use to fill in a new ESRT e= ntry + in Table. + @retval EFI_SUCCESS The ImageTypeId GUID in FmpImageInfoBuf matches= an + existing ESRT entry in Table, and the informati= on + from FmpImageInfoBuf was merged into the the ex= isting + ESRT entry. + @retval EFI_UNSPOORTED The GUID/HardareInstance in FmpImageInfoBuf has= is a + duplicate. =20 **/ EFI_STATUS CreateEsrtEntry ( - IN OUT EFI_SYSTEM_RESOURCE_TABLE **Table, - IN OUT UINT64 **HardwareInstances, - IN EFI_FIRMWARE_IMAGE_DESCRIPTOR *FmpImageInfoBuf, - IN UINT32 FmpVersion + IN OUT EFI_SYSTEM_RESOURCE_TABLE *Table, + IN OUT GUID_HARDWAREINSTANCE_PAIR *HardwareInstances, + IN OUT UINT32 *NumberOfDescriptors, + IN EFI_FIRMWARE_IMAGE_DESCRIPTOR *FmpImageInfoBuf, + IN UINT32 FmpVersion ) { UINTN Index; EFI_SYSTEM_RESOURCE_ENTRY *Entry; - UINTN NewSize; - EFI_SYSTEM_RESOURCE_TABLE *NewTable; - UINT64 *NewHardwareInstances; UINT64 FmpHardwareInstance; =20 - Index =3D 0; - Entry =3D NULL; + FmpHardwareInstance =3D 0; + if (FmpVersion >=3D 3) { + FmpHardwareInstance =3D FmpImageInfoBuf->HardwareInstance; + } =20 - Entry =3D (EFI_SYSTEM_RESOURCE_ENTRY *)((*Table) + 1); // - // Check to see if GUID is already in the table + // Check to see of FmpImageInfoBuf GUID/HardwareInstance is unique // - for (Index =3D 0; Index < (*Table)->FwResourceCount; Index++) { - if (CompareGuid (&Entry->FwClass, &FmpImageInfoBuf->ImageTypeId)) { - // - // If HardwareInstance in ESRT and FmpImageInfoBuf are the same value - // for the same ImageTypeId GUID, then there is more than one FMP - // instance for the same FW device, which is an error condition. - // If FmpVersion is less than 3, then assume HardwareInstance is 0. - // - FmpHardwareInstance =3D 0; - if (FmpVersion >=3D 3) { - FmpHardwareInstance =3D FmpImageInfoBuf->HardwareInstance; - } - if ((*HardwareInstances)[Index] =3D=3D FmpHardwareInstance) { - DEBUG ((DEBUG_ERROR, "EsrtFmpDxe: ESRT Entry already exists for FM= P Instance with GUID %g and HardwareInstance %016lx\n", &Entry->FwClass, (*= HardwareInstances)[Index])); - ASSERT ((*HardwareInstances)[Index] !=3D FmpHardwareInstance); + for (Index =3D 0; Index < *NumberOfDescriptors; Index++) { + if (CompareGuid (&HardwareInstances[Index].ImageTypeGuid, &FmpImageInf= oBuf->ImageTypeId)) { + if (HardwareInstances[Index].HardwareInstance =3D=3D FmpHardwareInst= ance) { + DEBUG ((DEBUG_ERROR, "EsrtFmpDxe: Duplicate firmware image descrip= tor with GUID %g HardwareInstance:0x%x\n", &FmpImageInfoBuf->ImageTypeId, F= mpHardwareInstance)); + ASSERT ( + !CompareGuid (&HardwareInstances[Index].ImageTypeGuid, &FmpImage= InfoBuf->ImageTypeId) || + HardwareInstances[Index].HardwareInstance !=3D FmpHardwareInstan= ce + ); return EFI_UNSUPPORTED; } - - DEBUG ((DEBUG_INFO, "EsrtFmpDxe: ESRT Entry already exists for FMP I= nstance with GUID %g\n", &Entry->FwClass)); - - // - // Set ESRT FwVersion to the smaller of the two values - // - Entry->FwVersion =3D MIN (FmpImageInfoBuf->Version, Entry->FwVersion= ); - - // - // VERSION 2 has Lowest Supported - // - if (FmpVersion >=3D 2) { - // - // Set ESRT LowestSupportedFwVersion to the smaller of the two val= ues - // - Entry->LowestSupportedFwVersion =3D - MIN ( - FmpImageInfoBuf->LowestSupportedImageVersion, - Entry->LowestSupportedFwVersion - ); - } - - // - // VERSION 3 supports last attempt values - // - if (FmpVersion >=3D 3) { - // - // Update the ESRT entry with the last attempt status and last att= empt - // version from the first FMP instance whose last attempt status i= s not - // SUCCESS. If all FMP instances are SUCCESS, then set version to= the=20 - // smallest value from all FMP instances. - // - if (Entry->LastAttemptStatus =3D=3D LAST_ATTEMPT_STATUS_SUCCESS) { - if (FmpImageInfoBuf->LastAttemptStatus !=3D LAST_ATTEMPT_STATUS_= SUCCESS) { - Entry->LastAttemptStatus =3D FmpImageInfoBuf->LastAttemptStatu= s; - Entry->LastAttemptVersion =3D FmpImageInfoBuf->LastAttemptVers= ion; - } else { - Entry->LastAttemptVersion =3D - MIN ( - FmpImageInfoBuf->LastAttemptVersion, - Entry->LastAttemptVersion - ); - } - } - } - - return EFI_SUCCESS; } - Entry++; } =20 // - // Grow table if needed + // Record new GUID/HardwareInstance pair // - if ((*Table)->FwResourceCount >=3D (*Table)->FwResourceCountMax) { - NewSize =3D (((*Table)->FwResourceCountMax + GROWTH_STEP) * sizeof (E= FI_SYSTEM_RESOURCE_ENTRY)) + sizeof (EFI_SYSTEM_RESOURCE_TABLE); - NewTable =3D AllocateZeroPool (NewSize); - if (NewTable =3D=3D NULL) { - DEBUG ((DEBUG_ERROR, "EsrtFmpDxe: Failed to allocate memory larger t= able for ESRT. \n")); - return EFI_OUT_OF_RESOURCES; - } - // - // Copy the whole old table into new table buffer - // - CopyMem ( - NewTable, - (*Table), - (((*Table)->FwResourceCountMax) * sizeof (EFI_SYSTEM_RESOURCE_ENTRY)= ) + sizeof (EFI_SYSTEM_RESOURCE_TABLE) - ); - // - // Update max - // - NewTable->FwResourceCountMax =3D NewTable->FwResourceCountMax + GROWTH= _STEP; - // - // Free old table - // - FreePool ((*Table)); - // - // Reassign pointer to new table. - // - (*Table) =3D NewTable; + CopyGuid (&HardwareInstances[*NumberOfDescriptors].ImageTypeGuid, &FmpIm= ageInfoBuf->ImageTypeId); + HardwareInstances[*NumberOfDescriptors].HardwareInstance =3D FmpHardware= Instance; + *NumberOfDescriptors =3D *NumberOfDescriptors + 1; + + DEBUG ((DEBUG_INFO, "EsrtFmpDxe: Add new image descriptor with GUID %g H= ardwareInstance:0x%x\n", &FmpImageInfoBuf->ImageTypeId, FmpHardwareInstance= )); =20 - NewSize =3D ((*Table)->FwResourceCountMax) * sizeof (UINT64); - NewHardwareInstances =3D AllocateZeroPool (NewSize); - if (NewHardwareInstances =3D=3D NULL) { - DEBUG ((DEBUG_ERROR, "EsrtFmpDxe: Failed to allocate memory larger t= able for Hardware Instances.\n")); - return EFI_OUT_OF_RESOURCES; + // + // Check to see if GUID is already in the ESRT table + // + Entry =3D (EFI_SYSTEM_RESOURCE_ENTRY *)(Table + 1); + for (Index =3D 0; Index < Table->FwResourceCount; Index++, Entry++) { + if (!CompareGuid (&Entry->FwClass, &FmpImageInfoBuf->ImageTypeId)) { + continue; } + DEBUG ((DEBUG_INFO, "EsrtFmpDxe: ESRT Entry already exists for FMP Ins= tance with GUID %g\n", &Entry->FwClass)); + // - // Copy the whole old table into new table buffer + // Set ESRT FwVersion to the smaller of the two values // - CopyMem ( - NewHardwareInstances, - (*HardwareInstances), - ((*Table)->FwResourceCountMax) * sizeof (UINT64) - ); + Entry->FwVersion =3D MIN (FmpImageInfoBuf->Version, Entry->FwVersion); + // - // Free old table + // VERSION 2 has Lowest Supported // - FreePool ((*HardwareInstances)); + if (FmpVersion >=3D 2) { + // + // Set ESRT LowestSupportedFwVersion to the smaller of the two values + // + Entry->LowestSupportedFwVersion =3D + MIN ( + FmpImageInfoBuf->LowestSupportedImageVersion, + Entry->LowestSupportedFwVersion + ); + } + // - // Reassign pointer to new table. + // VERSION 3 supports last attempt values // - (*HardwareInstances) =3D NewHardwareInstances; + if (FmpVersion >=3D 3) { + // + // Update the ESRT entry with the last attempt status and last attem= pt + // version from the first FMP instance whose last attempt status is = not + // SUCCESS. If all FMP instances are SUCCESS, then set version to t= he + // smallest value from all FMP instances. + // + if (Entry->LastAttemptStatus =3D=3D LAST_ATTEMPT_STATUS_SUCCESS) { + if (FmpImageInfoBuf->LastAttemptStatus !=3D LAST_ATTEMPT_STATUS_SU= CCESS) { + Entry->LastAttemptStatus =3D FmpImageInfoBuf->LastAttemptStatus; + Entry->LastAttemptVersion =3D FmpImageInfoBuf->LastAttemptVersio= n; + } else { + Entry->LastAttemptVersion =3D + MIN ( + FmpImageInfoBuf->LastAttemptVersion, + Entry->LastAttemptVersion + ); + } + } + } + + return EFI_SUCCESS; } =20 // - // ESRT table has enough room for the new entry so add new entry - // - Entry =3D (EFI_SYSTEM_RESOURCE_ENTRY *)(((UINT8 *)(*Table)) + sizeof (EF= I_SYSTEM_RESOURCE_TABLE)); + // Add a new ESRT Table Entry // - // Move to the location of new entry - // - Entry =3D Entry + (*Table)->FwResourceCount; + Entry =3D (EFI_SYSTEM_RESOURCE_ENTRY *)(Table + 1) + Table->FwResourceCo= unt; =20 CopyGuid (&Entry->FwClass, &FmpImageInfoBuf->ImageTypeId); =20 @@ -316,19 +284,87 @@ CreateEsrtEntry ( } =20 // - // VERSION 3 supports hardware instance + // Increment the number of active ESRT Table Entries // - (*HardwareInstances)[(*Table)->FwResourceCount] =3D 0; - if (FmpVersion >=3D 3) { - (*HardwareInstances)[(*Table)->FwResourceCount] =3D FmpImageInfoBuf->H= ardwareInstance; + Table->FwResourceCount++; + + return EFI_SUCCESS; +} + +/** + Function to retrieve the EFI_FIRMWARE_IMAGE_DESCRIPTOR from an FMP Insta= nce. + The returned buffer is allocated using AllocatePool() and must be freed = by the + caller using FreePool(). + + @param[in] Fmp Pointer to an EFI_FIRMWARE_MANAGE= MENT_PROTOCOL. + @param[out] FmpImageInfoDescriptorVer Pointer to the version number ass= ociated + with the returned EFI_FIRMWARE_IM= AGE_DESCRIPTOR. + @param[out] FmpImageInfoCount Pointer to the number of the retu= rned + EFI_FIRMWARE_IMAGE_DESCRIPTORs. + @param[out] DescriptorSize Pointer to the size, in bytes, of= each + returned EFI_FIRMWARE_IMAGE_DESCR= IPTOR. + + @return Pointer to the retrieved EFI_FIRMWARE_IMAGE_DESCRIPTOR. If the + descriptor can not be retrieved, then NULL is returned. + +**/ +EFI_FIRMWARE_IMAGE_DESCRIPTOR * +FmpGetFirmwareImageDescriptor ( + IN EFI_FIRMWARE_MANAGEMENT_PROTOCOL *Fmp, + OUT UINT32 *FmpImageInfoDescriptorVer, + OUT UINT8 *FmpImageInfoCount, + OUT UINTN *DescriptorSize + ) +{ + EFI_STATUS Status; + UINTN ImageInfoSize; + UINT32 PackageVersion; + CHAR16 *PackageVersionName; + EFI_FIRMWARE_IMAGE_DESCRIPTOR *FmpImageInfoBuf; + + ImageInfoSize =3D 0; + Status =3D Fmp->GetImageInfo ( + Fmp, // FMP Pointer + &ImageInfoSize, // Buffer Size (in this case= 0) + NULL, // NULL so we can get size + FmpImageInfoDescriptorVer, // DescriptorVersion + FmpImageInfoCount, // DescriptorCount + DescriptorSize, // DescriptorSize + &PackageVersion, // PackageVersion + &PackageVersionName // PackageVersionName + ); + if (Status !=3D EFI_BUFFER_TOO_SMALL) { + DEBUG ((DEBUG_ERROR, "EsrtFmpDxe: Unexpected Failure in GetImageInfo. = Status =3D %r\n", Status)); + return NULL; } =20 - // - // Increment resource count - // - (*Table)->FwResourceCount++; + FmpImageInfoBuf =3D AllocateZeroPool (ImageInfoSize); + if (FmpImageInfoBuf =3D=3D NULL) { + DEBUG ((DEBUG_ERROR, "EsrtFmpDxe: Failed to get memory for FMP descrip= tor.\n")); + return NULL; + } =20 - return EFI_SUCCESS; + PackageVersionName =3D NULL; + Status =3D Fmp->GetImageInfo ( + Fmp, // FMP Pointer + &ImageInfoSize, // ImageInfoSize + FmpImageInfoBuf, // ImageInfo + FmpImageInfoDescriptorVer, // DescriptorVersion + FmpImageInfoCount, // DescriptorCount + DescriptorSize, // DescriptorSize + &PackageVersion, // PackageVersion + &PackageVersionName // PackageVersionName + ); + if (PackageVersionName !=3D NULL) { + FreePool (PackageVersionName); + } + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "EsrtFmpDxe: Failure in GetImageInfo. Status =3D= %r\n", Status)); + FreePool (FmpImageInfoBuf); + return NULL; + } + + return FmpImageInfoBuf; } =20 /** @@ -344,31 +380,26 @@ CreateFmpBasedEsrt ( VOID ) { - EFI_STATUS Status; - EFI_SYSTEM_RESOURCE_TABLE *Table; - UINT64 *HardwareInstances; - UINTN NoProtocols; - VOID **Buffer; - UINTN Index; - EFI_FIRMWARE_MANAGEMENT_PROTOCOL *Fmp; - UINTN DescriptorSize; - EFI_FIRMWARE_IMAGE_DESCRIPTOR *FmpImageInfoBuf; - EFI_FIRMWARE_IMAGE_DESCRIPTOR *FmpImageInfoBufOrg; - UINT8 FmpImageInfoCount; - UINT32 FmpImageInfoDescriptorVer; - UINTN ImageInfoSize; - UINT32 PackageVersion; - CHAR16 *PackageVersionName; + EFI_STATUS Status; + UINTN NoProtocols; + VOID **Buffer; + UINTN Index; + UINT32 FmpImageInfoDescriptorVer; + UINT8 FmpImageInfoCount; + UINTN DescriptorSize; + UINT32 NumberOfDescriptors; + EFI_FIRMWARE_IMAGE_DESCRIPTOR *FmpImageInfoBuf; + EFI_FIRMWARE_IMAGE_DESCRIPTOR *OrgFmpImageInfoBuf; + EFI_SYSTEM_RESOURCE_TABLE *Table; + GUID_HARDWAREINSTANCE_PAIR *HardwareInstances; =20 Status =3D EFI_SUCCESS; - Table =3D NULL; - HardwareInstances =3D NULL; NoProtocols =3D 0; Buffer =3D NULL; - PackageVersionName =3D NULL; FmpImageInfoBuf =3D NULL; - FmpImageInfoBufOrg =3D NULL; - Fmp =3D NULL; + OrgFmpImageInfoBuf =3D NULL; + Table =3D NULL; + HardwareInstances =3D NULL; =20 Status =3D EfiLocateProtocolBuffer ( &gEfiFirmwareManagementProtocolGuid, @@ -380,77 +411,64 @@ CreateFmpBasedEsrt ( } =20 // - // Allocate Memory for tables + // Count the total number of EFI_FIRMWARE_IMAGE_DESCRIPTORs + // + for (Index =3D 0, NumberOfDescriptors =3D 0; Index < NoProtocols; Index+= +) { + FmpImageInfoBuf =3D FmpGetFirmwareImageDescriptor ( + (EFI_FIRMWARE_MANAGEMENT_PROTOCOL *) Buffer[Index], + &FmpImageInfoDescriptorVer, + &FmpImageInfoCount, + &DescriptorSize + ); + if (FmpImageInfoBuf !=3D NULL) { + NumberOfDescriptors +=3D FmpImageInfoCount; + FreePool (FmpImageInfoBuf); + } + } + + // + // Allocate ESRT Table and GUID/HardwareInstance table // Table =3D AllocateZeroPool ( - (GROWTH_STEP * sizeof (EFI_SYSTEM_RESOURCE_ENTRY)) + sizeof (= EFI_SYSTEM_RESOURCE_TABLE) + (NumberOfDescriptors * sizeof (EFI_SYSTEM_RESOURCE_ENTRY)) + = sizeof (EFI_SYSTEM_RESOURCE_TABLE) ); if (Table =3D=3D NULL) { DEBUG ((DEBUG_ERROR, "EsrtFmpDxe: Failed to allocate memory for ESRT.\= n")); - gBS->FreePool (Buffer); + FreePool (Buffer); return NULL; } =20 - HardwareInstances =3D AllocateZeroPool (GROWTH_STEP * sizeof (UINT64)); + HardwareInstances =3D AllocateZeroPool (NumberOfDescriptors * sizeof (GU= ID_HARDWAREINSTANCE_PAIR)); if (HardwareInstances =3D=3D NULL) { DEBUG ((DEBUG_ERROR, "EsrtFmpDxe: Failed to allocate memory for HW Ins= tance Table.\n")); - gBS->FreePool (Table); - gBS->FreePool (Buffer); + FreePool (Table); + FreePool (Buffer); return NULL; } =20 + // + // Initialize ESRT Table + // Table->FwResourceCount =3D 0; - Table->FwResourceCountMax =3D GROWTH_STEP; + Table->FwResourceCountMax =3D NumberOfDescriptors; Table->FwResourceVersion =3D EFI_SYSTEM_RESOURCE_TABLE_FIRMWARE_RESOURC= E_VERSION; =20 + NumberOfDescriptors =3D 0; for (Index =3D 0; Index < NoProtocols; Index++) { - Fmp =3D (EFI_FIRMWARE_MANAGEMENT_PROTOCOL *) Buffer[Index]; - - ImageInfoSize =3D 0; - Status =3D Fmp->GetImageInfo ( - Fmp, // FMP Pointer - &ImageInfoSize, // Buffer Size (in this c= ase 0) - NULL, // NULL so we can get size - &FmpImageInfoDescriptorVer, // DescriptorVersion - &FmpImageInfoCount, // DescriptorCount - &DescriptorSize, // DescriptorSize - &PackageVersion, // PackageVersion - &PackageVersionName // PackageVersionName - ); - - if (Status !=3D EFI_BUFFER_TOO_SMALL) { - DEBUG ((DEBUG_ERROR, "EsrtFmpDxe: Unexpected Failure in GetImageInfo= . Status =3D %r\n", Status)); - continue; - } - - FmpImageInfoBuf =3D AllocateZeroPool (ImageInfoSize); + FmpImageInfoBuf =3D FmpGetFirmwareImageDescriptor ( + (EFI_FIRMWARE_MANAGEMENT_PROTOCOL *) Buffer[Index], + &FmpImageInfoDescriptorVer, + &FmpImageInfoCount, + &DescriptorSize + ); if (FmpImageInfoBuf =3D=3D NULL) { - DEBUG ((DEBUG_ERROR, "EsrtFmpDxe: Failed to get memory for descripto= rs.\n")); - continue; - } - - FmpImageInfoBufOrg =3D FmpImageInfoBuf; - PackageVersionName =3D NULL; - Status =3D Fmp->GetImageInfo ( - Fmp, - &ImageInfoSize, // ImageInfoSize - FmpImageInfoBuf, // ImageInfo - &FmpImageInfoDescriptorVer, // DescriptorVersion - &FmpImageInfoCount, // DescriptorCount - &DescriptorSize, // DescriptorSize - &PackageVersion, // PackageVersion - &PackageVersionName // PackageVersionName - ); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "EsrtFmpDxe: Failure in GetImageInfo. Status = =3D %r\n", Status)); - FreePool (FmpImageInfoBufOrg); - FmpImageInfoBufOrg =3D NULL; continue; } =20 // // Check each descriptor and read from the one specified // + OrgFmpImageInfoBuf =3D FmpImageInfoBuf; while (FmpImageInfoCount > 0) { // // If the descriptor has the IN USE bit set, create ESRT entry other= wise ignore. @@ -459,7 +477,7 @@ CreateFmpBasedEsrt ( // // Create ESRT entry // - CreateEsrtEntry (&Table, &HardwareInstances, FmpImageInfoBuf, FmpI= mageInfoDescriptorVer); + CreateEsrtEntry (Table, HardwareInstances, &NumberOfDescriptors, F= mpImageInfoBuf, FmpImageInfoDescriptorVer); } FmpImageInfoCount--; // @@ -468,15 +486,12 @@ CreateFmpBasedEsrt ( FmpImageInfoBuf =3D (EFI_FIRMWARE_IMAGE_DESCRIPTOR *)(((UINT8 *)FmpI= mageInfoBuf) + DescriptorSize); } =20 - if (PackageVersionName !=3D NULL) { - FreePool (PackageVersionName); - PackageVersionName =3D NULL; - } - FreePool (FmpImageInfoBufOrg); - FmpImageInfoBufOrg =3D NULL; + FreePool (OrgFmpImageInfoBuf); + OrgFmpImageInfoBuf =3D NULL; } =20 - gBS->FreePool (Buffer); + FreePool (Buffer); + FreePool (HardwareInstances); return Table; } =20 --=20 2.20.1.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 (#39358): https://edk2.groups.io/g/devel/message/39358 Mute This Topic: https://groups.io/mt/31271286/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-