diff options
author | Laszlo Ersek <lersek@redhat.com> | 2014-06-19 06:13:29 +0000 |
---|---|---|
committer | jljusten <jljusten@6f19259b-4bc3-4df7-8a09-765794883524> | 2014-06-19 06:13:29 +0000 |
commit | a618eaa1f45d53073784460ec2c8d9c3d097b789 (patch) | |
tree | 773de2c5903544ff093cce15190552bff4da9ec2 /OvmfPkg/AcpiPlatformDxe/Qemu.c | |
parent | 374df8fc59622f78de0cefaf073c44076cc44f7e (diff) | |
download | edk2-platforms-a618eaa1f45d53073784460ec2c8d9c3d097b789.tar.xz |
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
Diffstat (limited to 'OvmfPkg/AcpiPlatformDxe/Qemu.c')
-rw-r--r-- | OvmfPkg/AcpiPlatformDxe/Qemu.c | 54 |
1 files changed, 49 insertions, 5 deletions
diff --git a/OvmfPkg/AcpiPlatformDxe/Qemu.c b/OvmfPkg/AcpiPlatformDxe/Qemu.c index 5a96d76a1f..70f3ff6426 100644 --- a/OvmfPkg/AcpiPlatformDxe/Qemu.c +++ b/OvmfPkg/AcpiPlatformDxe/Qemu.c @@ -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;
}
|