panic: vm_fault: fault on nofualt entry, addr: 81423000
John Baldwin
jhb at freebsd.org
Fri Jan 18 07:11:32 PST 2008
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
More information about the freebsd-stable
mailing list