diff options
author | jhb <jhb@FreeBSD.org> | 2004-05-10 18:33:08 +0000 |
---|---|---|
committer | jhb <jhb@FreeBSD.org> | 2004-05-10 18:33:08 +0000 |
commit | c11a15c8fe9ac745f0f4b87952f955700c7f98f7 (patch) | |
tree | a69f744f84a9f3f229f7900242561e7145bcc4fe /sys/i386/acpica/madt.c | |
parent | 0b8070442395dbd4af0afa0a8a6d965eb3c2af3c (diff) | |
download | FreeBSD-src-c11a15c8fe9ac745f0f4b87952f955700c7f98f7.zip FreeBSD-src-c11a15c8fe9ac745f0f4b87952f955700c7f98f7.tar.gz |
- Change madt_map_table() to verify the checksum of any table it is asked
to map. If the checksum fails, the table is unmapped and a NULL pointer
returned.
- For ACPI version >= 2.0, check the extended checksum of the RSDP.
AcpiOsGetRootPointer() already checks the version 1.0 checksum.
- Remap the full MADT table at the end of madt_probe() so that we verify
its checksum before saying it is really there.
Requested by: njl
Diffstat (limited to 'sys/i386/acpica/madt.c')
-rw-r--r-- | sys/i386/acpica/madt.c | 32 |
1 files changed, 30 insertions, 2 deletions
diff --git a/sys/i386/acpica/madt.c b/sys/i386/acpica/madt.c index 09bfdb6..81dd058 100644 --- a/sys/i386/acpica/madt.c +++ b/sys/i386/acpica/madt.c @@ -49,6 +49,7 @@ __FBSDID("$FreeBSD$"); #include <machine/specialreg.h> #include "acpi.h" +#include <contrib/dev/acpica/actables.h> #include <dev/acpica/acpivar.h> #include <dev/pci/pcivar.h> @@ -158,6 +159,7 @@ madt_map_table(vm_paddr_t pa, int offset, const char *sig) { ACPI_TABLE_HEADER *header; vm_offset_t length; + void *table; header = madt_map(pa, offset, sizeof(ACPI_TABLE_HEADER)); if (strncmp(header->Signature, sig, 4) != 0) { @@ -166,7 +168,14 @@ madt_map_table(vm_paddr_t pa, int offset, const char *sig) } length = header->Length; madt_unmap(header, sizeof(ACPI_TABLE_HEADER)); - return (madt_map(pa, offset, length)); + table = madt_map(pa, offset, length); + if (ACPI_FAILURE(AcpiTbVerifyTableChecksum(table))) { + if (bootverbose) + printf("MADT: Failed checksum for table %s\n", sig); + madt_unmap(table, length); + return (NULL); + } + return (table); } static void @@ -216,6 +225,16 @@ madt_probe(void) * Page 0 is used to map in the headers of candidate ACPI tables. */ if (rsdp->Revision >= 2) { + /* + * AcpiOsGetRootPointer only verifies the checksum for + * the version 1.0 portion of the RSDP. Version 2.0 has + * an additional checksum that we verify first. + */ + if (AcpiTbChecksum(rsdp, ACPI_RSDP_XCHECKSUM_LENGTH) != 0) { + if (bootverbose) + printf("MADT: RSDP failed extended checksum\n"); + return (ENXIO); + } xsdt = madt_map_table(rsdp->XsdtPhysicalAddress, 1, XSDT_SIG); if (xsdt == NULL) { if (bootverbose) @@ -252,6 +271,16 @@ madt_probe(void) printf("MADT: Found table at 0x%jx\n", (uintmax_t)madt_physaddr); + /* + * Verify that we can map the full table and that its checksum is + * correct, etc. + */ + madt = madt_map_table(madt_physaddr, 0, APIC_SIG); + if (madt == NULL) + return (ENXIO); + madt_unmap_table(madt); + madt = NULL; + return (0); } @@ -274,7 +303,6 @@ madt_probe_table(vm_paddr_t address) printf("Table '%.4s' at 0x%jx\n", table->Signature, (uintmax_t)address); - /* XXX: Verify checksum? */ if (strncmp(table->Signature, APIC_SIG, 4) != 0) { madt_unmap(table, sizeof(ACPI_TABLE_HEADER)); return (0); |