From 374df8fc59622f78de0cefaf073c44076cc44f7e Mon Sep 17 00:00:00 2001 From: Laszlo Ersek Date: Thu, 19 Jun 2014 06:13:22 +0000 Subject: [PATCH] OvmfPkg: AcpiPlatformDxe: exclude RSD PTR from QEMU's fw_cfg payload In one of the next patches we'll start scanning all fw_cfg files that QEMU advertises as carrying ACPI tables, not just "etc/acpi/tables". The RSD PTR table is known to occur in the "etc/acpi/rsdp" fw_cfg file. Since edk2 handles RSD PTR automatically, similarly to RSDT and XSDT, let's exclude RSD PTR too from the manually installed tables. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Laszlo Ersek Reviewed-by: Jordan Justen git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@15573 6f19259b-4bc3-4df7-8a09-765794883524 --- OvmfPkg/AcpiPlatformDxe/Qemu.c | 104 +++++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) diff --git a/OvmfPkg/AcpiPlatformDxe/Qemu.c b/OvmfPkg/AcpiPlatformDxe/Qemu.c index df912c20f8..5a96d76a1f 100644 --- a/OvmfPkg/AcpiPlatformDxe/Qemu.c +++ b/OvmfPkg/AcpiPlatformDxe/Qemu.c @@ -516,6 +516,80 @@ QemuInstallAcpiTable ( } +/** + Check if an array of bytes starts with an RSD PTR structure. + + Checksum is ignored. + + @param[in] Buffer The array to check. + + @param[in] Size Number of bytes in Buffer. + + @param[out] RsdpSize If the function returns EFI_SUCCESS, this parameter + contains the size of the detected RSD PTR structure. + + @retval EFI_SUCCESS RSD PTR structure detected at the beginning of + Buffer, and its advertised size does not exceed + Size. + + @retval EFI_PROTOCOL_ERROR RSD PTR structure detected at the beginning of + Buffer, but it has inconsistent size. + + @retval EFI_NOT_FOUND RSD PTR structure not found. + +**/ + +STATIC +EFI_STATUS +CheckRsdp ( + IN CONST VOID *Buffer, + IN UINTN Size, + OUT UINTN *RsdpSize + ) +{ + CONST UINT64 *Signature; + CONST EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER *Rsdp1; + CONST EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER *Rsdp2; + + if (Size < sizeof *Signature) { + return EFI_NOT_FOUND; + } + Signature = Buffer; + + if (*Signature != EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER_SIGNATURE) { + return EFI_NOT_FOUND; + } + + // + // Signature found -- from this point on we can only report + // EFI_PROTOCOL_ERROR or EFI_SUCCESS. + // + if (Size < sizeof *Rsdp1) { + return EFI_PROTOCOL_ERROR; + } + Rsdp1 = Buffer; + + if (Rsdp1->Reserved == 0) { + // + // ACPI 1.0 doesn't include the Length field + // + *RsdpSize = sizeof *Rsdp1; + return EFI_SUCCESS; + } + + if (Size < sizeof *Rsdp2) { + return EFI_PROTOCOL_ERROR; + } + Rsdp2 = Buffer; + + if (Size < Rsdp2->Length || Rsdp2->Length < sizeof *Rsdp2) { + return EFI_PROTOCOL_ERROR; + } + + *RsdpSize = Rsdp2->Length; + return EFI_SUCCESS; +} + // // We'll be saving the keys of installed tables so that we can roll them back // in case of failure. 128 tables should be enough for anyone (TM). @@ -602,9 +676,39 @@ InstallQemuLinkedTables ( Processed = 0; while (Processed < TablesFileSize) { UINTN Remaining; + UINTN RsdpSize; EFI_ACPI_DESCRIPTION_HEADER *Probe; Remaining = TablesFileSize - Processed; + + // + // See if we're looking at an RSD PTR structure. + // + RsdpSize = 0; + Status = CheckRsdp (Tables + Processed, Remaining, &RsdpSize); + if (Status == EFI_PROTOCOL_ERROR) { + // + // RSD PTR found but its size is inconsistent; abort processing. (Note + // that "RSD PTR found" excludes the NUL-padding case by definition.) + // + break; + } + if (!EFI_ERROR (Status)) { + // + // Consistent RSD PTR found, skip it. + // + DEBUG ((EFI_D_VERBOSE, "%a: \"%a\" offset 0x%016Lx: RSD PTR " + "Length=0x%08x\n", __FUNCTION__, FwCfgFile, (UINT64)Processed, + (UINT32)RsdpSize)); + Processed += RsdpSize; + continue; + } + ASSERT (Status == EFI_NOT_FOUND); + + // + // What we're looking at is not an RSD PTR structure; attempt to parse it + // as an ACPI table. + // if (Remaining < sizeof *Probe) { Status = EFI_PROTOCOL_ERROR; break; -- 2.39.2