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 <ler...@redhat.com> Reviewed-by: Jordan Justen <jordan.l.jus...@intel.com> --- Notes: v2: - patch is unchanged from v1 (2/3) OvmfPkg/AcpiPlatformDxe/Qemu.c | 104 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) diff --git a/OvmfPkg/AcpiPlatformDxe/Qemu.c b/OvmfPkg/AcpiPlatformDxe/Qemu.c index df912c2..5a96d76 100644 --- a/OvmfPkg/AcpiPlatformDxe/Qemu.c +++ b/OvmfPkg/AcpiPlatformDxe/Qemu.c @@ -515,8 +515,82 @@ 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). // @@ -601,11 +675,41 @@ 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; } -- 1.8.3.1 ------------------------------------------------------------------------------ HPCC Systems Open Source Big Data Platform from LexisNexis Risk Solutions Find What Matters Most in Your Big Data with HPCC Systems Open Source. Fast. Scalable. Simple. Ideal for Dirty Data. Leverages Graph Analysis for Fast Processing & Easy Data Exploration http://p.sf.net/sfu/hpccsystems _______________________________________________ edk2-devel mailing list edk2-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/edk2-devel