Subject: port-m68k/26958: kernel crashdump doesn't work on m68k ports
To: None <gnats-bugs@gnats.NetBSD.org>
From: None <tsutsui@ceres.dti.ne.jp>
List: netbsd-bugs
Date: 09/15/2004 23:59:53
>Number:         26958
>Category:       port-m68k
>Synopsis:       kernel crashdump doesn't work on m68k ports
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    port-m68k-maintainer
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Wed Sep 15 15:00:00 UTC 2004
>Closed-Date:
>Last-Modified:
>Originator:     Izumi Tsutsui
>Release:        NetBSD 2.0G, but maybe 2-0-release also affected
>Organization:
>Environment:
NetBSD 2.0G
Architecture: m68k
Machine: news68k, hp300 and maybe other m68k ports
>Description:
Kernel crash dump has a problem on most m68k ports.
hp300 gets trap right after dump is started, and news68k
just hangs before dump.

>How-To-Repeat:
"reboot -d" on m68k ports, and crashdump doesn't proceed.
On hp300:
---
# reboot -d
Sep 15 23:55:24 delica reboot: rebooted by tsutsui
Sep 15 23:55:24 delica syslogd: Exiting on signal 15
syncing disks... 2 1 done

dumping to dev 4,1 offset 181269
dump trap: bad kernel read access at 0x0
trap type 8, code = 0x5e6, v = 0x0
kernel program counter = 0x0
kernel: MMU fault trap
pid = 466, lid = 1, pc = 00000000, ps = 2700, sfc = 1, dfc = 1
Registers:
             0        1        2        3        4        5        6        7
dreg: 00657BBC 00000000 FE802000 00000000 00000000 0000000C 00000000 00000000
areg: 00000000 00657BBC 00657BB4 00657DF0 FFEFECF8 0055E980 00657DB4 FFEFECF4

Kernel stack (00657A7C):
657A7C: 0012FFF4 00657B00 00000080 FE802000 00000000 00000000 0000000C 00000000
657A9C: 00000000 00657BB4 00657DF0 FFEFECF8 0055E980 0055C690 00000000 00000000
657ABC: 00000001 00000000 00000000 00000000 00000000 00000000 00000000 00000008
657ADC: 00000000 00000000 00000000 0003DC58 00657DB4 000018EE 00000008 000005E6
657AFC: 00000000 00657BBC 00000000 FE802000 00000000 00000000 0000000C 00000000
657B1C: 00000000 00000000 00657BBC 00657BB4 00657DF0 FFEFECF8 0055E980 00657DB4
657B3C: FFEFECF4 00000000 27000000 00007008 00657BB0 05E60005 00000005 00000000
657B5C: 00000000 0012DCAE 01C58F00 01C2D000 00657AD0 00657B18 00000000 00657B88
657B7C: 000C3744 0012E7A6 00000401 00000000 0002C415 00657BB4 00000200 00657BBC
657B9C: 001A3920 00000228 FE802000 00000000 000C51F4 0012934A 04878FCA 000001F8
657BBC: 68703330 30000000 00000000 00000000 00001000 00000000 FFFFFFFE 00000002
657BDC: FFFFF000 00000016 003FF000 00000019 01FC0000 00000012 0003F000 0000000C
657BFC: FFFFFE00 FFFFFF00 00000001 FFFFF000 FEA0C000 FE802000 001B1310 00000000
657C1C: 00000000 FE802000 00000000 017FD000 00000000 00000000 00000000 00000000
657C3C: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
657C5C: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
panic: MMU fault
Stopped in pid 466.1 (reboot) at        netbsd:cpu_Debugger+0x6:        unlk    a6
db> 
---

>Fix:
The problem is that most these ports assume the machine dependent
dump header fits in 1 disk block (512bytes), but current
sizeof(struct cpu_kcore_hdr) is 552bytes after sun2 import, so
overrun happens on temporary buffer (mostly 512bytes on stack).

The attached patch fixes the problem but I'm not sure if
it's a propre fix...

--- hp300/machdep.c	2004-09-15 23:48:26.000000000 +0900
+++ hp300/machdep.c.new	2004-09-15 23:52:02.000000000 +0900
@@ -781,13 +781,13 @@
  * Compute the size of the machine-dependent crash dump header.
  * Returns size in disk blocks.
  */
+#define CHDRSIZE (ALIGN(sizeof(kcore_seg_t)) + ALIGN(sizeof(cpu_kcore_hdr_t)))
+#define MDHDRSIZE roundup(CHDRSIZE, dbtob(1))
 static int
 cpu_dumpsize(void)
 {
-	int size;
 
-	size = ALIGN(sizeof(kcore_seg_t)) + ALIGN(sizeof(cpu_kcore_hdr_t));
-	return (btodb(roundup(size, dbtob(1))));
+	return (btodb(MDHDRSIZE));
 }
 
 /*
@@ -796,7 +796,7 @@
 static int
 cpu_dump(int (*dump)(dev_t, daddr_t, caddr_t, size_t), daddr_t *blknop)
 {
-	int buf[dbtob(1) / sizeof(int)];
+	int buf[MDHDRSIZE / sizeof(int)];
 	cpu_kcore_hdr_t *chdr;
 	kcore_seg_t *kseg;
 	int error;
@@ -807,7 +807,7 @@
 
 	/* Create the segment header. */
 	CORE_SETMAGIC(*kseg, KCORE_MAGIC, MID_MACHINE, CORE_CPU);
-	kseg->c_size = dbtob(1) - ALIGN(sizeof(kcore_seg_t));
+	kseg->c_size = MDHDRSIZE - ALIGN(sizeof(kcore_seg_t));
 
 	memcpy(chdr, &cpu_kcore_hdr, sizeof(cpu_kcore_hdr_t));
 	error = (*dump)(dumpdev, *blknop, (caddr_t)buf, sizeof(buf));
>Release-Note:
>Audit-Trail:
>Unformatted: