diff options
author | Laszlo Ersek <lersek@redhat.com> | 2014-06-19 06:13:22 +0000 |
---|---|---|
committer | jljusten <jljusten@6f19259b-4bc3-4df7-8a09-765794883524> | 2014-06-19 06:13:22 +0000 |
commit | 374df8fc59622f78de0cefaf073c44076cc44f7e (patch) | |
tree | 7f287bf4167e7e560c062cc4ea2074058129e9b1 | |
parent | 2d1fe95066fb11e30f9028d70349669c24f6c289 (diff) | |
download | edk2-platforms-374df8fc59622f78de0cefaf073c44076cc44f7e.tar.xz |
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 <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@15573 6f19259b-4bc3-4df7-8a09-765794883524
-rw-r--r-- | OvmfPkg/AcpiPlatformDxe/Qemu.c | 104 |
1 files changed, 104 insertions, 0 deletions
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;
|