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>
---
 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


------------------------------------------------------------------------------
"Accelerate Dev Cycles with Automated Cross-Browser Testing - For FREE
Instantly run your Selenium tests across 300+ browser/OS combos.
Get unparalleled scalability from the best Selenium testing platform available
Simple to use. Nothing to install. Get started now for free."
http://p.sf.net/sfu/SauceLabs
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/edk2-devel

Reply via email to