lkml.org 
[lkml]   [2003]   [Feb]   [19]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Subject[PATCH] linux-2.5.62_acpitable-fix_A0
From
Date
Andy, All,
I've been working to boot up a 16way+HT box here on 2.5 with ACPI, and
have been getting consistent reboots before the console inits. I tracked
down the bug to some ACPI code where we map in the ACPI tables.

Unfortunately in a few cases we map in just the header, then immediately
start processing the table, rather then reading the table length and
remapping the entire table into memory. I guess with smaller boxes, we
never had ACPI tables that crossed page boundaries, so it was never
noticed. On this box however, we start calculating the table checksum
and run off the page causing the system to reboot. ouch!

Anyway, here is a patch that fixes the spot I was having troubles with,
along with two other instances of this mistake. Andy, you may have some
stylistic complaints, but something to this effect is needed.

thanks
-john

PS: Big thanks to James Cleverdon for confirming the cause of the
problem and pointing out the other instances of it as well.

diff -Nru a/drivers/acpi/tables.c b/drivers/acpi/tables.c
--- a/drivers/acpi/tables.c Wed Feb 19 19:46:04 2003
+++ b/drivers/acpi/tables.c Wed Feb 19 19:46:04 2003
@@ -379,6 +379,7 @@

sdt.pa = ((struct acpi20_table_rsdp*)rsdp)->xsdt_address;

+ /* map in just the header */
header = (struct acpi_table_header *)
__acpi_map_table(sdt.pa, sizeof(struct acpi_table_header));

@@ -387,6 +388,15 @@
return -ENODEV;
}

+ /* remap in the entire table before processing */
+ mapped_xsdt = (struct acpi_table_xsdt *)
+ __acpi_map_table(sdt.pa, header->length);
+ if (!mapped_xsdt) {
+ printk(KERN_WARNING PREFIX "Unable to map XSDT\n");
+ return -ENODEV;
+ }
+ header = &mapped_xsdt->header;
+
if (strncmp(header->signature, "XSDT", 4)) {
printk(KERN_WARNING PREFIX "XSDT signature incorrect\n");
return -ENODEV;
@@ -404,15 +414,6 @@
sdt.count = ACPI_MAX_TABLES;
}

- mapped_xsdt = (struct acpi_table_xsdt *)
- __acpi_map_table(sdt.pa, header->length);
- if (!mapped_xsdt) {
- printk(KERN_WARNING PREFIX "Unable to map XSDT\n");
- return -ENODEV;
- }
-
- header = &mapped_xsdt->header;
-
for (i = 0; i < sdt.count; i++)
sdt.entry[i].pa = (unsigned long) mapped_xsdt->entry[i];
}
@@ -425,6 +426,7 @@

sdt.pa = rsdp->rsdt_address;

+ /* map in just the header */
header = (struct acpi_table_header *)
__acpi_map_table(sdt.pa, sizeof(struct acpi_table_header));
if (!header) {
@@ -432,6 +434,15 @@
return -ENODEV;
}

+ /* remap in the entire table before processing */
+ mapped_rsdt = (struct acpi_table_rsdt *)
+ __acpi_map_table(sdt.pa, header->length);
+ if (!mapped_rsdt) {
+ printk(KERN_WARNING PREFIX "Unable to map RSDT\n");
+ return -ENODEV;
+ }
+ header = &mapped_rsdt->header;
+
if (strncmp(header->signature, "RSDT", 4)) {
printk(KERN_WARNING PREFIX "RSDT signature incorrect\n");
return -ENODEV;
@@ -449,15 +460,6 @@
sdt.count = ACPI_MAX_TABLES;
}

- mapped_rsdt = (struct acpi_table_rsdt *)
- __acpi_map_table(sdt.pa, header->length);
- if (!mapped_rsdt) {
- printk(KERN_WARNING PREFIX "Unable to map RSDT\n");
- return -ENODEV;
- }
-
- header = &mapped_rsdt->header;
-
for (i = 0; i < sdt.count; i++)
sdt.entry[i].pa = (unsigned long) mapped_rsdt->entry[i];
}
@@ -471,12 +473,20 @@

for (i = 0; i < sdt.count; i++) {

+ /* map in just the header */
header = (struct acpi_table_header *)
__acpi_map_table(sdt.entry[i].pa,
sizeof(struct acpi_table_header));
if (!header)
continue;

+ /* remap in the entire table before processing */
+ header = (struct acpi_table_header *)
+ __acpi_map_table(sdt.entry[i].pa,
+ header->length);
+ if (!header)
+ continue;
+
acpi_table_print(header, sdt.entry[i].pa);

if (acpi_table_compute_checksum(header, header->length)) {

[unhandled content-type:application/pgp-signature]
\
 
 \ /
  Last update: 2005-03-22 13:33    [W:0.020 / U:5.400 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site