Date: Fri, 18 Jan 2008 10:03:23 -0500 From: John Baldwin <jhb@freebsd.org> To: Pete French <petefrench@ticketswitch.com> Cc: freebsd-stable@freebsd.org Subject: Re: panic: vm_fault: fault on nofualt entry, addr: 81423000 Message-ID: <200801181003.24092.jhb@freebsd.org> In-Reply-To: <E1JFsG0-0000YG-U6@dilbert.ticketswitch.com> References: <E1JFsG0-0000YG-U6@dilbert.ticketswitch.com>
next in thread | previous in thread | raw e-mail | index | archive | help
On Friday 18 January 2008 09:31:44 am Pete French wrote: > > Just the stack trace offsets. > > is all the info you need here? > > http://toybox.twisted.org.uk/~pete/acpi_panic.jpg Yep. So it appears to be dying here: (gdb) l *madt_probe+0x119 0xc06e7c69 is in madt_probe (/usr/src/sys/i386/acpica/madt.c:241). 236 if (xsdt == NULL) { 237 if (bootverbose) 238 printf("MADT: Failed to map XSDT\n"); 239 return (ENXIO); 240 } 241 count = (xsdt->Length - sizeof(ACPI_TABLE_HEADER)) / 242 sizeof(UINT64); 243 for (i = 0; i < count; i++) 244 if (madt_probe_table(xsdt->TableOffsetEntry[i])) 245 break; where it reads 'xsdt->Length'. xsdt was just mapped into a temporary part of KVA (used for kernel dumps) a few lines earlier: 218 /* 219 * For ACPI >= 2.0, use the XSDT if it is available. 220 * Otherwise, use the RSDT. We map the XSDT or RSDT at page 1 221 * in the crashdump area. Page 0 is used to map in the 222 * headers of candidate ACPI tables. 223 */ 224 if (rsdp->Revision >= 2 && rsdp->XsdtPhysicalAddress != 0) { 225 /* 226 * AcpiOsGetRootPointer only verifies the checksum for 227 * the version 1.0 portion of the RSDP. Version 2.0 has 228 * an additional checksum that we verify first. 229 */ 230 if (AcpiTbChecksum(rsdp, ACPI_RSDP_XCHECKSUM_LENGTH) != 0) { 231 if (bootverbose) 232 printf("MADT: RSDP failed extended checksum\n"); 233 return (ENXIO); 234 } 235 xsdt = madt_map_table(rsdp->XsdtPhysicalAddress, 1, XSDT_SIG); You can try adding some printfs to see what the values of 'rsdp->XsdtPhysicalAddress' and 'xsdt' after the call to madt_map_table() are. Actually, try this perhaps: Index: madt.c =================================================================== RCS file: /host/cvs/usr/cvs/src/sys/i386/acpica/madt.c,v retrieving revision 1.19.2.4 diff -u -r1.19.2.4 madt.c --- madt.c 5 Oct 2007 15:22:36 -0000 1.19.2.4 +++ madt.c 18 Jan 2008 15:01:40 -0000 @@ -164,7 +164,20 @@ } length = header->Length; madt_unmap(header, sizeof(ACPI_TABLE_HEADER)); + if (length > (MAXDUMPPGS - offset) * PAGE_SIZE) { + printf("MADT: %s is too long, truncating\n", sig); + length = (MAXDUMPPGS - offset) * PAGE_SIZE; + } table = madt_map(pa, offset, length); + header = table; + if (header->Length != length) { + /* + * If we truncated the table, fixup the length to + * perpetuate the lie and skip the checksum. + */ + header->Length = length; + return (table); + } if (ACPI_FAILURE(AcpiTbVerifyTableChecksum(table))) { if (bootverbose) printf("MADT: Failed checksum for table %s\n", sig); @@ -267,6 +280,10 @@ if (bootverbose) printf("MADT: Found table at 0x%jx\n", (uintmax_t)madt_physaddr); + if (madt_length > MAXDUMPPGS * PAGE_SIZE) { + printf("MADT: Table is too large, ignoring\n"); + return (ENXIO); + } /* * Verify that we can map the full table and that its checksum is -- John Baldwin
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200801181003.24092.jhb>