OvmfPkg: AcpiPlatformDxe: don't rely on unstable QEMU interface
The fw_cfg file "etc/acpi/tables" is not a stable guest interface -- QEMU could rename it in the future, and/or introduce additional fw_cfg files with ACPI payload. Only the higher-level "etc/table-loader" file is considered stable, which contains a sequence of commands to assist firmware with reading QEMU ACPI tables from the FwCfg interface. Because edk2 provides publishing support for ACPI tables, OVMF only uses the Allocate command to find the names of FwCfg files to read and publish as ACPI tables. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Laszlo Ersek <lersek@redhat.com> Reviewed-by: Jordan Justen <jordan.l.justen@intel.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@15574 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
@@ -16,6 +16,7 @@
|
||||
**/
|
||||
|
||||
#include "AcpiPlatform.h"
|
||||
#include "QemuLoader.h"
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/MemoryAllocationLib.h>
|
||||
#include <Library/QemuFwCfgLib.h>
|
||||
@@ -795,8 +796,7 @@ InstallQemuLinkedTables (
|
||||
@retval EFI_OUT_OF_RESOURCES Memory allocation failed, or more than
|
||||
INSTALLED_TABLES_MAX tables found.
|
||||
|
||||
@retval EFI_PROTOCOL_ERROR Found truncated or invalid ACPI table header
|
||||
in the fw_cfg contents.
|
||||
@retval EFI_PROTOCOL_ERROR Found invalid fw_cfg contents.
|
||||
|
||||
@return Status codes returned by
|
||||
AcpiProtocol->InstallAcpiTable().
|
||||
@@ -812,6 +812,10 @@ InstallAllQemuLinkedTables (
|
||||
UINTN *InstalledKey;
|
||||
INT32 Installed;
|
||||
EFI_STATUS Status;
|
||||
FIRMWARE_CONFIG_ITEM LoaderItem;
|
||||
UINTN LoaderSize;
|
||||
UINT8 *Loader;
|
||||
QEMU_LOADER_ENTRY *Entry, *End;
|
||||
|
||||
InstalledKey = AllocatePool (INSTALLED_TABLES_MAX * sizeof *InstalledKey);
|
||||
if (InstalledKey == NULL) {
|
||||
@@ -819,10 +823,49 @@ InstallAllQemuLinkedTables (
|
||||
}
|
||||
Installed = 0;
|
||||
|
||||
Status = InstallQemuLinkedTables ("etc/acpi/tables", AcpiProtocol,
|
||||
InstalledKey, &Installed);
|
||||
Status = QemuFwCfgFindFile ("etc/table-loader", &LoaderItem, &LoaderSize);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto FreeInstalledKey;
|
||||
}
|
||||
if (LoaderSize % sizeof *Entry != 0) {
|
||||
Status = EFI_PROTOCOL_ERROR;
|
||||
goto FreeInstalledKey;
|
||||
}
|
||||
|
||||
Loader = AllocatePool (LoaderSize);
|
||||
if (Loader == NULL) {
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
goto FreeInstalledKey;
|
||||
}
|
||||
|
||||
QemuFwCfgSelectItem (LoaderItem);
|
||||
QemuFwCfgReadBytes (LoaderSize, Loader);
|
||||
|
||||
Entry = (QEMU_LOADER_ENTRY *)Loader;
|
||||
End = (QEMU_LOADER_ENTRY *)(Loader + LoaderSize);
|
||||
while (Entry < End) {
|
||||
if (Entry->Type == QemuLoaderCmdAllocate) {
|
||||
QEMU_LOADER_ALLOCATE *Allocate;
|
||||
|
||||
Allocate = &Entry->Command.Allocate;
|
||||
if (Allocate->File[sizeof Allocate->File - 1] != '\0') {
|
||||
Status = EFI_PROTOCOL_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
Status = InstallQemuLinkedTables ((CHAR8 *)Allocate->File, AcpiProtocol,
|
||||
InstalledKey, &Installed);
|
||||
if (EFI_ERROR (Status)) {
|
||||
ASSERT (Status != EFI_INVALID_PARAMETER);
|
||||
break;
|
||||
}
|
||||
}
|
||||
++Entry;
|
||||
}
|
||||
|
||||
FreePool (Loader);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
ASSERT (Status != EFI_INVALID_PARAMETER);
|
||||
//
|
||||
// Roll back partial installation.
|
||||
//
|
||||
@@ -834,6 +877,7 @@ InstallAllQemuLinkedTables (
|
||||
DEBUG ((EFI_D_INFO, "%a: installed %d tables\n", __FUNCTION__, Installed));
|
||||
}
|
||||
|
||||
FreeInstalledKey:
|
||||
FreePool (InstalledKey);
|
||||
return Status;
|
||||
}
|
||||
|
Reference in New Issue
Block a user