diff -Naur -X exclude linux-2.6.3/arch/i386/kernel/acpi/boot.c linux-2.6.3-acpi-table-fix/arch/i386/kernel/acpi/boot.c --- linux-2.6.3/arch/i386/kernel/acpi/boot.c 2004-02-19 14:01:00.000000000 +0000 +++ linux-2.6.3-acpi-table-fix/arch/i386/kernel/acpi/boot.c 2004-02-19 20:41:03.000000000 +0000 @@ -341,7 +341,10 @@ for (offset = 0; offset < length; offset += 16) { if (strncmp((char *) (start + offset), "RSD PTR ", sig_len)) continue; - return (start + offset); + + /* Check for valid checksum */ + if (acpi_checksum_rsdp((struct acpi_table_rsdp *)(start+offset)) == 0) + return (start + offset); } return 0; @@ -388,8 +391,9 @@ return __pa(efi.acpi); } /* - * Scan memory looking for the RSDP signature. First search EBDA (low - * memory) paragraphs and then search upper memory (E0000-FFFFF). + * Scan memory looking for the RSDP signature and valid checksum. + * First search EBDA (low memory) paragraphs and then search + * upper memory (E0000-FFFFF). */ rsdp_phys = acpi_scan_rsdp (0, 0x400); if (!rsdp_phys) @@ -437,6 +441,7 @@ */ result = acpi_table_init(); if (result) { + printk(KERN_WARNING PREFIX "Malformed ACPI tables, disabling ACPI support\n"); acpi_disabled = 1; return result; } diff -Naur -X exclude linux-2.6.3/drivers/acpi/tables.c linux-2.6.3-acpi-table-fix/drivers/acpi/tables.c --- linux-2.6.3/drivers/acpi/tables.c 2004-02-19 14:01:09.000000000 +0000 +++ linux-2.6.3-acpi-table-fix/drivers/acpi/tables.c 2004-02-19 16:29:47.000000000 +0000 @@ -550,13 +550,24 @@ return 0; } +int __init +acpi_checksum_rsdp(struct acpi_table_rsdp *rsdp) +{ + int result = 0; + + if (rsdp->revision < 2) + result = acpi_table_compute_checksum(rsdp, sizeof(struct acpi_table_rsdp)); + else + result = acpi_table_compute_checksum(rsdp, ((struct acpi20_table_rsdp *)rsdp)->length); + + return result; +} int __init acpi_table_init (void) { struct acpi_table_rsdp *rsdp = NULL; unsigned long rsdp_phys = 0; - int result = 0; /* Locate and map the Root System Description Table (RSDP) */ @@ -575,12 +586,7 @@ printk(KERN_INFO PREFIX "RSDP (v%3.3d %6.6s ) @ 0x%p\n", rsdp->revision, rsdp->oem_id, (void *) rsdp_phys); - if (rsdp->revision < 2) - result = acpi_table_compute_checksum(rsdp, sizeof(struct acpi_table_rsdp)); - else - result = acpi_table_compute_checksum(rsdp, ((struct acpi20_table_rsdp *)rsdp)->length); - - if (result) { + if (acpi_checksum_rsdp(rsdp)) { printk(KERN_WARNING " >>> ERROR: Invalid checksum\n"); return -ENODEV; } diff -Naur -X exclude linux-2.6.3/include/linux/acpi.h linux-2.6.3-acpi-table-fix/include/linux/acpi.h --- linux-2.6.3/include/linux/acpi.h 2004-02-19 14:01:40.000000000 +0000 +++ linux-2.6.3-acpi-table-fix/include/linux/acpi.h 2004-02-19 18:13:11.000000000 +0000 @@ -349,6 +349,7 @@ char * __acpi_map_table (unsigned long phys_addr, unsigned long size); unsigned long acpi_find_rsdp (void); +int acpi_checksum_rsdp(struct acpi_table_rsdp *rsdp); int acpi_boot_init (void); int acpi_numa_init (void);