NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
port-atari/56859: "iteconfig -h 480" triggers vm_fault panic on ATARITT kernel
>Number: 56859
>Category: port-atari
>Synopsis: "iteconfig -h 480" triggers vm_fault panic on ATARITT kerne
>Confidential: no
>Severity: critical
>Priority: medium
>Responsible: port-atari-maintainer
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Sun May 29 12:15:01 +0000 2022
>Originator: Izumi Tsutsui
>Release: NetBSD 9.2
>Organization:
>Environment:
System: NetBSD ataritt 9.2 NetBSD 9.2 (ATARITT) #0: Wed May 12 13:15:55 UTC 2021 mkrepro%mkrepro.NetBSD.org@localhost:/usr/src/sys/arch/atari/compile/ATARITT atari
Architecture: m68k
Machine: atari
>Description:
"iteconfig -h 480" command immediately triggers vm_fault kernel panic
on TT030 and NetBSD/atari 9.2 ATARITT kernel.
The backtrace on crash shows:
---
[ 30443.6719614] vm_fault(0x26d840, 0, 1) -> e
[ 30443.6719614] type 8, code [mmu,,ssw]: 4020755
[ 30443.6719614] trap type 8, code = 4020755, v = 14
[ 30443.6719614] kernel program counter = 0x19f76
[ 30443.6719614] kernel: MMU fault trap
[ 30443.6719614] pid = 4009, lid = 1, pc = 00019F76, ps = 2700, sfc = 1, dfc = 1
[ 30443.6719614] Registers:
[ 30443.6719614] 0 1 2 3 4 5 6 7
[ 30443.6719614] dreg: 003E2000 00000001 00000000 0025D0AC 00000001 00000014 00000014 FFEFF8D4
[ 30443.6719614] areg: 003E5FD0 00000000 003DBF70 0025DB68 003E5FB8 005A1220 05FBBC54 FFEFF854
[ 30443.6719614] Kernel stack (05FBBAA8):
[ 30443.6719614] FBBAA8: 0001967C 05FBBBA4 00000080 00000008 00000000 00147AB8 005A1220 05FBBB8C
[ 30443.6719614] FBBAC8: 00019C56 00000008 04020755 00000014 05FBBBA4 00000000 0025D0AC 00000001
[ 30443.6719614] FBBAE8: 00000014 00000014 FFEFF8D4 003DBF70 0025DB68 003E5FB8 005A1220 005AB538
[ 30443.6719614] FBBB08: 00000001 05FBBE58 00000001 00000000 00000000 00000000 00000000 00000001
[ 30443.6719614] FBBB28: 00000000 00000000 00000000 00000008 00000000 00000000 00000000 00000000
[ 30443.6719614] FBBB48: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[ 30443.6719614] FBBB68: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[ 30443.6719614] FBBB88: 05FBBBE4 05FBBC54 00002042 05FBBBA4 00000008 04020755 00000014 003E2000
[ 30443.6719614] FBBBA8: 00000001 00000000 0025D0AC 00000001 00000014 00000014 FFEFF8D4 003E5FD0
[ 30443.6719614] FBBBC8: 00000000 003DBF70 0025DB68 003E5FB8 005A1220 05FBBC54 FFEFF854 00000000
[ 30443.6719614] FBBBE8: 27000001 9F76B008 1EEE0755 667C2169 00000014 00000014 00002000 4A290014
[ 30443.6719614] FBBC08: 00019F7E 00019F7C 00019F7A 003DBF00 0014FF0C 000FF6EC 270049E8 0024BB1C
[ 30443.6719614] FBBC28: 00002700 00002700 80200000 00000014 00000000 003BA000 00019F64 0025D0AC
[ 30443.6719614] FBBC48: 0025DB68 0025DB68 005A1220 05FBBC64 0000D2A6 003E5FD0 0025DB7C 05FBBC98
[ 30443.6719614] FBBC68: 00010A42 0025D0AC 80145A73 00000C00 05FBBDA0 0025D170 004EE7C0 00000000
[ 30443.6719614] FBBC88: 005A1220 000F9002 00000280 000001E0 05FBBCE8 0000C802 00000000 00000000
[ 30443.6719614] panic: MMU fault
[ 30443.6719614] cpu0: Begin traceback...
[ 30443.6719614] ?(?)
[ 30443.6719614] db_panic(8,2710,5fb8000,5fbbba4,5fbbaa8) at 0
[ 30443.6719614] vpanic(1e16c6,5fbbab4,5fbbac4,1969a,1e16c6) + 162
[ 30443.6719614] panic(1e16c6,8,0,147ab8,5a1220) + c
[ 30443.6719614] panictrap(?)
[ 30443.6719614] mmc_gettrackinfo(8,4020755,14,5fbbba4,0) + b8
[ 30443.6719614] trap(5fbbba4,8,4020755,14) + 51e
[ 30443.6719614] free_stmem(3e5fd0) + 2a
[ 30443.6719614] tt_free_view(?)
[ 30443.6719614] grf_free_view(25d0ac) + 3e
[ 30443.6719614] viewioctl(0,0,80145602,5fbbcd4,0) + 18a
[ 30443.6719614] ite_newsize(?)
[ 30443.6719614] _ufetch_8(4ee7c0,5fbbe80) + 52
[ 30443.6719614] itecc_ioctl(?)
[ 30443.6719614] cdev_ioctl(4ee7c0,80145a73,5fbbe80,5,62c340,62c340) + 48
[ 30443.6719614] spec_ioctl(5fbbd50,202fac,832d14,80145a73,5fbbe80) + a0
[ 30443.6719614] VOP_IOCTL(832d14,80145a73,5fbbe80,5,4f6c4c) + 38
[ 30443.6719614] vn_ioctl(5d85e0,80145a73,5fbbe80) + 158
[ 30443.6719614] sys_ioctl(62c340,5fbbf38,5fbbf30,d,0) + 240
[ 30443.6719614] syscall_plain(36,62c340,5fbbfb4,ffeff948,5) + d2
[ 30443.6719614] syscall(36) + 70
[ 30443.6719614] trap0() + e
[ 30443.6719614] cpu0: End traceback...
[ 30443.6719614] dumping to dev 4,1 offset 1957882
[ 30443.6719614] Do you want to dump memory? [y]
---
>> [ 30443.6719614] trap type 8, code = 4020755, v = 14
"v = 14" implies NULL pointer dereference, and
>> [ 30443.6719614] pid = 4009, lid = 1, pc = 00019F76, ps = 2700, sfc = 1, dfc = 1
"pc = 00019F76" is the following instruction in free_stmem():
---
00019f4c <free_stmem>:
19f4c: 4e56 0000 linkw %fp,#0
19f50: 48e7 003c moveml %a2-%a5,%sp@-
19f54: 206e 0008 moveal %fp@(8),%a0
19f58: 4a88 tstl %a0
19f5a: 6700 0210 beqw 1a16c <free_stmem+0x220>
19f5e: 40c0 movew %sr,%d0
19f60: 46fc 2700 movew #9984,%sr
19f64: 49e8 ffe8 lea %a0@(-24),%a4
19f68: 2268 ffe8 moveal %a0@(-24),%a1
19f6c: 2468 ffec moveal %a0@(-20),%a2
19f70: 246a 0004 moveal %a2@(4),%a2
19f74: 2452 moveal %a2@,%a2
19f76: 4a29 0014 tstb %a1@(20)
^^^^^^^^^^^^^ *this one*
19f7a: 667c bnes 19ff8 <free_stmem+0xac>
---
This means the following "next" in free_stmem() is NULL:
(note %a0 points *mem here)
https://nxr.netbsd.org/xref/src/sys/arch/atari/atari/stalloc.c?r=1.16#166
---
void
free_stmem(void *mem)
{
struct mem_node *mn, *next, *prev;
int s;
if (mem == NULL)
return;
s = splhigh();
mn = (struct mem_node *)mem - 1;
next = TAILQ_NEXT(mn, link);
prev = TAILQ_PREV(mn, stlist, link);
/*
* check ahead of us.
*/
if (next->type == MNODE_FREE) {
^^^^ *this one*
---
>How-To-Repeat:
See above.
>Fix:
stalloc.c rev 1.16 removed "next != NULL" (and "prev != NULL") checks,
but they should still be checked before dereference?
https://nxr.netbsd.org/diff/src/sys/arch/atari/atari/stalloc.c?r2=%2Fsrc%2Fsys%2Farch%2Fatari%2Fatari%2Fstalloc.c%401.16&r1=%2Fsrc%2Fsys%2Farch%2Fatari%2Fatari%2Fstalloc.c%401.15
--- stalloc.c 27 Nov 2013 17:24:43 -0000 1.15
+++ stalloc.c 3 Jan 2014 07:14:20 -0000 1.16
@@ -117,7 +117,7 @@ alloc_stmem(u_long size, void **phys_add
* for a new node in between.
*/
TAILQ_REMOVE(&free_list, mn, free_link);
- TAILQ_NEXT(mn, free_link) = NULL;
+ mn->type = MNODE_USED;
size = mn->size; /* increase size. (or same) */
stmem_total -= mn->size;
splx(s);
@@ -138,7 +138,7 @@ alloc_stmem(u_long size, void **phys_add
* and mark as not on free list
*/
TAILQ_INSERT_AFTER(&st_list, new, mn, link);
- TAILQ_NEXT(mn, free_link) = NULL;
+ mn->type = MNODE_USED;
stmem_total -= size + sizeof(struct mem_node);
splx(s);
@@ -150,7 +150,7 @@ void
free_stmem(void *mem)
{
struct mem_node *mn, *next, *prev;
- int s;
+ int s;
if (mem == NULL)
return;
@@ -163,48 +163,52 @@ free_stmem(void *mem)
/*
* check ahead of us.
*/
- if (next != NULL && TAILQ_NEXT(next, free_link) != NULL) {
+ if (next->type == MNODE_FREE) {
/*
* if next is: a valid node and a free node. ==> merge
*/
TAILQ_INSERT_BEFORE(next, mn, free_link);
+ mn->type = MNODE_FREE;
TAILQ_REMOVE(&st_list, next, link);
- TAILQ_REMOVE(&st_list, next, free_link);
+ TAILQ_REMOVE(&free_list, next, free_link);
stmem_total += mn->size + sizeof(struct mem_node);
mn->size += next->size + sizeof(struct mem_node);
}
- if (prev != NULL && TAILQ_PREV(prev, freelist, free_link) != NULL) {
+ if (prev->type == MNODE_FREE) {
/*
* if prev is: a valid node and a free node. ==> merge
*/
- if (TAILQ_NEXT(mn, free_link) == NULL)
+ if (mn->type != MNODE_FREE)
stmem_total += mn->size + sizeof(struct mem_node);
else {
/* already on free list */
TAILQ_REMOVE(&free_list, mn, free_link);
+ mn->type = MNODE_USED;
stmem_total += sizeof(struct mem_node);
}
TAILQ_REMOVE(&st_list, mn, link);
prev->size += mn->size + sizeof(struct mem_node);
- } else if (TAILQ_NEXT(mn, free_link) == NULL) {
+ } else if (mn->type != MNODE_FREE) {
/*
* we still are not on free list and we need to be.
* <-- | -->
*/
while (next != NULL && prev != NULL) {
- if (TAILQ_NEXT(next, free_link) != NULL) {
+ if (next->type == MNODE_FREE) {
TAILQ_INSERT_BEFORE(next, mn, free_link);
+ mn->type = MNODE_FREE;
break;
}
- if (TAILQ_NEXT(prev, free_link) != NULL) {
+ if (prev->type == MNODE_FREE) {
TAILQ_INSERT_AFTER(&free_list, prev, mn,
free_link);
+ mn->type = MNODE_FREE;
break;
}
prev = TAILQ_PREV(prev, stlist, link);
next = TAILQ_NEXT(next, link);
}
- if (TAILQ_NEXT(mn, free_link) == NULL) {
+ if (mn->type != MNODE_FREE) {
if (next == NULL) {
/*
* we are not on list so we can add
@@ -214,6 +218,7 @@ free_stmem(void *mem)
} else {
TAILQ_INSERT_HEAD(&free_list,mn,free_link);
}
+ mn->type = MNODE_FREE;
}
stmem_total += mn->size;/* add our helpings to the pool. */
}
---
Izumi Tsutsui
Home |
Main Index |
Thread Index |
Old Index