From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: mx.groups.io; dkim=missing; spf=pass (domain: intel.com, ip: 192.55.52.115, mailfrom: michael.d.kinney@intel.com) Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) by groups.io with SMTP; Mon, 22 Apr 2019 07:42:17 -0700 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga005.fm.intel.com ([10.253.24.32]) by fmsmga103.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 22 Apr 2019 07:42:16 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.60,382,1549958400"; d="scan'208";a="339697370" Received: from orsmsx103.amr.corp.intel.com ([10.22.225.130]) by fmsmga005.fm.intel.com with ESMTP; 22 Apr 2019 07:42:16 -0700 Received: from orsmsx123.amr.corp.intel.com (10.22.240.116) by ORSMSX103.amr.corp.intel.com (10.22.225.130) with Microsoft SMTP Server (TLS) id 14.3.408.0; Mon, 22 Apr 2019 07:42:15 -0700 Received: from orsmsx113.amr.corp.intel.com ([169.254.9.24]) by ORSMSX123.amr.corp.intel.com ([169.254.1.141]) with mapi id 14.03.0415.000; Mon, 22 Apr 2019 07:42:15 -0700 From: "Michael D Kinney" To: "Jin, Eric" , "devel@edk2.groups.io" , "Kinney, Michael D" Subject: Re: [Staging/Bug_1525_FmpDevicePkg_MultipleControllers][PATCH] MdeModulePkg/EsrtFmpDxe: Detect duplicate GUID/HardwareInstance Thread-Topic: [Staging/Bug_1525_FmpDevicePkg_MultipleControllers][PATCH] MdeModulePkg/EsrtFmpDxe: Detect duplicate GUID/HardwareInstance Thread-Index: AQHU+M8JbuPiDqqphkiRH9V2FrHBDaZIQWUg Date: Mon, 22 Apr 2019 14:42:14 +0000 Message-ID: References: <20190422054818.1468-1-eric.jin@intel.com> In-Reply-To: <20190422054818.1468-1-eric.jin@intel.com> Accept-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: dlp-product: dlpe-windows dlp-version: 11.0.600.7 dlp-reaction: no-action x-originating-ip: [10.22.254.138] MIME-Version: 1.0 Return-Path: michael.d.kinney@intel.com Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Reviewed-by: Michael D Kinney > -----Original Message----- > From: Jin, Eric > Sent: Sunday, April 21, 2019 10:48 PM > To: devel@edk2.groups.io > Cc: Kinney, Michael D > Subject: > [Staging/Bug_1525_FmpDevicePkg_MultipleControllers][PAT > CH] MdeModulePkg/EsrtFmpDxe: Detect duplicate > GUID/HardwareInstance >=20 > https://bugzilla.tianocore.org/show_bug.cgi?id=3D1525 >=20 > 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. >=20 > 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. >=20 > 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. >=20 > CC: Eric Jin > CC: Michael D Kinney > Contributed-under: TianoCore Contribution Agreement 1.1 > Signed-off-by: Eric Jin > --- > MdeModulePkg/Universal/EsrtFmpDxe/EsrtFmp.c | 461 > ++++++++++---------- > 1 file changed, 238 insertions(+), 223 deletions(-) >=20 > diff --git > a/MdeModulePkg/Universal/EsrtFmpDxe/EsrtFmp.c > b/MdeModulePkg/Universal/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 the > + /// system for devices that may have multiple > instances whenever possible. > + /// > + 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 ESRT > - 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 the ESRT. > - On output, same as > input or pointer to the pointer > - to new enlarged > ESRT. > - @param[in] FmpImageInfoBuf Pointer to the > EFI_FIRMWARE_IMAGE_DESCRIPTOR. > - @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 ESRT > + 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_DESCRIPTORs. > + @param[in] FmpImageInfoBuf Pointer to the > EFI_FIRMWARE_IMAGE_DESCRIPTOR. > + @param[in] FmpVersion FMP Version. > + > + @retval EFI_SUCCESS FmpImageInfoBuf was use to > fill in a new ESRT entry > + in Table. > + @retval EFI_SUCCESS The ImageTypeId GUID in > FmpImageInfoBuf matches an > + existing ESRT entry in > Table, and the information > + from FmpImageInfoBuf was > merged into the the existing > + 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 FMP 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, > &FmpImageInfoBuf->ImageTypeId)) { > + if (HardwareInstances[Index].HardwareInstance =3D=3D > FmpHardwareInstance) { > + DEBUG ((DEBUG_ERROR, "EsrtFmpDxe: Duplicate > firmware image descriptor with GUID %g > HardwareInstance:0x%x\n", &FmpImageInfoBuf- > >ImageTypeId, FmpHardwareInstance)); > + ASSERT ( > + !CompareGuid > (&HardwareInstances[Index].ImageTypeGuid, > &FmpImageInfoBuf->ImageTypeId) || > + HardwareInstances[Index].HardwareInstance !=3D > FmpHardwareInstance > + ); > return EFI_UNSUPPORTED; > } > - > - DEBUG ((DEBUG_INFO, "EsrtFmpDxe: ESRT Entry > already exists for FMP Instance 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 values > - // > - 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 attempt > - // version from the first FMP instance whose > last attempt status is not > - // SUCCESS. If all FMP instances are SUCCESS, > then set version to the > - // 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->LastAttemptStatus; > - Entry->LastAttemptVersion =3D > FmpImageInfoBuf->LastAttemptVersion; > - } 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 (EFI_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 table 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 > , &FmpImageInfoBuf->ImageTypeId); > + > HardwareInstances[*NumberOfDescriptors].HardwareInstanc > e =3D FmpHardwareInstance; > + *NumberOfDescriptors =3D *NumberOfDescriptors + 1; > + > + DEBUG ((DEBUG_INFO, "EsrtFmpDxe: Add new image > descriptor with GUID %g HardwareInstance: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 table 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 Instance 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 attempt > + // version from the first FMP instance whose > last attempt status is not > + // SUCCESS. If all FMP instances are SUCCESS, > then set version to the > + // 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- > >LastAttemptStatus; > + Entry->LastAttemptVersion =3D FmpImageInfoBuf- > >LastAttemptVersion; > + } 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 (EFI_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->FwResourceCount; >=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->HardwareInstance; > + Table->FwResourceCount++; > + > + return EFI_SUCCESS; > +} > + > +/** > + Function to retrieve the > EFI_FIRMWARE_IMAGE_DESCRIPTOR from an FMP Instance. > + The returned buffer is allocated using > AllocatePool() and must be freed by the > + caller using FreePool(). > + > + @param[in] Fmp Pointer to an > EFI_FIRMWARE_MANAGEMENT_PROTOCOL. > + @param[out] FmpImageInfoDescriptorVer Pointer to > the version number associated > + with the > returned EFI_FIRMWARE_IMAGE_DESCRIPTOR. > + @param[out] FmpImageInfoCount Pointer to > the number of the returned > + > EFI_FIRMWARE_IMAGE_DESCRIPTORs. > + @param[out] DescriptorSize Pointer to > the size, in bytes, of each > + returned > EFI_FIRMWARE_IMAGE_DESCRIPTOR. > + > + @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 descriptor.\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 > (GUID_HARDWAREINSTANCE_PAIR)); > if (HardwareInstances =3D=3D NULL) { > DEBUG ((DEBUG_ERROR, "EsrtFmpDxe: Failed to > allocate memory for HW Instance 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_RESOURCE_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 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)); > - 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 descriptors.\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 otherwise ignore. > @@ -459,7 +477,7 @@ CreateFmpBasedEsrt ( > // > // Create ESRT entry > // > - CreateEsrtEntry (&Table, &HardwareInstances, > FmpImageInfoBuf, FmpImageInfoDescriptorVer); > + CreateEsrtEntry (Table, HardwareInstances, > &NumberOfDescriptors, FmpImageInfoBuf, > FmpImageInfoDescriptorVer); > } > FmpImageInfoCount--; > // > @@ -468,15 +486,12 @@ CreateFmpBasedEsrt ( > FmpImageInfoBuf =3D (EFI_FIRMWARE_IMAGE_DESCRIPTOR > *)(((UINT8 *)FmpImageInfoBuf) + 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 > -- > 2.20.1.windows.1