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