Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Prototype fix for multiple add-pointer acpi table linker commands usi…
…ng memoisation.
  • Loading branch information
pmj committed Feb 7, 2017
1 parent 0bed3a6 commit 58e0510
Showing 1 changed file with 65 additions and 2 deletions.
67 changes: 65 additions & 2 deletions OvmfPkg/AcpiPlatformDxe/QemuFwCfgAcpi.c
Expand Up @@ -98,6 +98,39 @@ BlobCompare (
}


/**
Comparator function for two opaque pointers, ordering on pointer value
itself.
Can be used as both Key and UserStruct comparator.
@param[in] Pointer1 First pointer.
@param[in] Pointer2 Second pointer.
@retval <0 If Pointer1 compares less than Pointer2.
@retval 0 If Pointer1 compares equal to Pointer2.
@retval >0 If Pointer1 compares greater than Pointer2.
**/
STATIC
INTN
EFIAPI
PointerCompare(
IN CONST VOID *Pointer1,
IN CONST VOID *Pointer2
)
{
if (Pointer1 == Pointer2) {
return 0;
} else if ((INTN)Pointer1 < (INTN)Pointer2) {
return -1;
} else {
return 1;
}
}


/**
Process a QEMU_LOADER_ALLOCATE command.
Expand Down Expand Up @@ -387,6 +420,11 @@ ProcessCmdAddChecksum (
command identified an ACPI table that is
different from RSDT and XSDT.
@param[in,out] InstalledTables The ORDERED_COLLECTION tracking the ACPI tables
which have already been installed. If a new
table is encountered by the function, it is
added; existing ones will not be installed again.
@retval EFI_INVALID_PARAMETER NumInstalled was outside the allowed range on
input.
Expand Down Expand Up @@ -414,7 +452,8 @@ Process2ndPassCmdAddPointer (
IN CONST ORDERED_COLLECTION *Tracker,
IN EFI_ACPI_TABLE_PROTOCOL *AcpiProtocol,
IN OUT UINTN InstalledKey[INSTALLED_TABLES_MAX],
IN OUT INT32 *NumInstalled
IN OUT INT32 *NumInstalled,
IN OUT ORDERED_COLLECTION *InstalledTables
)
{
CONST ORDERED_COLLECTION_ENTRY *TrackerEntry;
Expand Down Expand Up @@ -509,6 +548,16 @@ Process2ndPassCmdAddPointer (
return EFI_SUCCESS;
}

Status = OrderedCollectionInsert(InstalledTables, NULL, (VOID *)(UINTN)PointerValue);
if (EFI_ERROR (Status)) {
if (Status == RETURN_ALREADY_STARTED) {
// Already seen a pointer to this table, skip installing it.
DEBUG ((EFI_D_VERBOSE, "%a: AcpiProtocol->InstallAcpiTable reports table already installed, skipping. PointerValue=0x%Lx\n", __FUNCTION__, PointerValue));
Status = EFI_SUCCESS;
}
return Status;
}

if (*NumInstalled == INSTALLED_TABLES_MAX) {
DEBUG ((EFI_D_ERROR, "%a: can't install more than %d tables\n",
__FUNCTION__, INSTALLED_TABLES_MAX));
Expand Down Expand Up @@ -567,6 +616,8 @@ InstallQemuFwCfgTables (
UINTN *InstalledKey;
INT32 Installed;
ORDERED_COLLECTION_ENTRY *TrackerEntry, *TrackerEntry2;
ORDERED_COLLECTION *InstalledTables;
ORDERED_COLLECTION_ENTRY *InstalledTableEntry;

Status = QemuFwCfgFindFile ("etc/table-loader", &FwCfgItem, &FwCfgSize);
if (EFI_ERROR (Status)) {
Expand Down Expand Up @@ -630,14 +681,20 @@ InstallQemuFwCfgTables (
goto FreeTracker;
}

InstalledTables = OrderedCollectionInit(PointerCompare, PointerCompare);
if (InstalledTables == NULL) {
Status = EFI_OUT_OF_RESOURCES;
goto FreeKeys;
}

//
// second pass: identify and install ACPI tables
//
Installed = 0;
for (LoaderEntry = LoaderStart; LoaderEntry < LoaderEnd; ++LoaderEntry) {
if (LoaderEntry->Type == QemuLoaderCmdAddPointer) {
Status = Process2ndPassCmdAddPointer (&LoaderEntry->Command.AddPointer,
Tracker, AcpiProtocol, InstalledKey, &Installed);
Tracker, AcpiProtocol, InstalledKey, &Installed, InstalledTables);
if (EFI_ERROR (Status)) {
break;
}
Expand All @@ -656,6 +713,12 @@ InstallQemuFwCfgTables (
DEBUG ((EFI_D_INFO, "%a: installed %d tables\n", __FUNCTION__, Installed));
}

while (((InstalledTableEntry = OrderedCollectionMax(InstalledTables))) != NULL) {
OrderedCollectionDelete(InstalledTables, InstalledTableEntry, NULL);
}
OrderedCollectionUninit(InstalledTables);

FreeKeys:
FreePool (InstalledKey);

FreeTracker:
Expand Down

0 comments on commit 58e0510

Please sign in to comment.