Subject: port-sparc64/15633: datafault at tlp_start causes panic
To: None <gnats-bugs@gnats.netbsd.org>
From: None <t-nkyma@tcp-ip.or.jp>
List: netbsd-bugs
Date: 02/16/2002 22:33:31
>Number:         15633
>Category:       port-sparc64
>Synopsis:       datafault at tlp_start causes panic
>Confidential:   no
>Severity:       critical
>Priority:       high
>Responsible:    port-sparc64-maintainer
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sat Feb 16 05:34:00 PST 2002
>Closed-Date:
>Last-Modified:
>Originator:     Takeshi Nakayama
>Release:        NetBSD 1.5ZA (2002-02-14)
>Organization:
	none
>Environment:
System: NetBSD nyx 1.5ZA NetBSD 1.5ZA (NYX) #49: Sat Feb 16 20:36:05 JST 2002 takeshi@nyx:/usr/src/sys/arch/sparc64/compile/NYX sparc64
Architecture: sparc64
Machine: sparc64
>Description:
	It occurs kernel panic while using NIC (tlp) on Netra X1
	after change of iommu.c 1.44 to 1.47.

panic: lockmgr: no context
kdb breakpoint at 11e5c80
Stopped at      cpu_Debugger+0x4:       nop
db> t
lockmgr(1826ee8, 1, 0, 1826ee0, 2000, 0) at lockmgr+0xb0
uvm_fault(1826ee0, e13844000, 0, 1, 180c400, 1264958) at uvm_fault+0x14c
data_access_fault(e00174d0, 30, 1016b6c, e13844000, e13845a04, 800809) at data_access_fault+0xd4
Ldatafault_internal(40, ff00, 136ce004, e00177a00, 1288, 11b47a0) at Ldatafault_internal+0xd8
tlp_start(2165500, 10166e0, 0, 21d44d8, e00177a0, 300) at tlp_start+0x470
ether_output(0, b, 321, 2201900, 2275420, 10aa640) at ether_output+0x71c
ip_output(2275420, 1326e810, 22e00d8, 0, 22e00e0, 21d4060) at ip_output+0x790
tcp_output(0, c, 34, 2, 22cfc40, 1860400) at tcp_output+0x1378
tcp_input(2274920, 2274984, 22d0cd0, 0, 1867000, 34) at tcp_input+0x30d4
ip_input(14, 1867608, 2274920, 1, 400, 11b47a0) at ip_input+0x99c
ipintr(1000000, 1, f, 21d44d8, 1a3ef, 3) at ipintr+0x60
softnet(4, 0, e0017ed0, 1237c00, 11d8500, 0) at softnet+0x60
sparc_intr_retry(0, 0, 122b258, 0, ffffffffffffffff, ffffffffffffd1f8) at sparc_intr_retry+0x48
vn_read(141db980, 10e4, 0, 1871500, 3c6e4279, fffffffffffa09db) at vn_read+0xd8
mi_switch(141db980, 94, 1425c428, 3, 1, 14216fe8) at mi_switch+0x16c
ltsleep(0, 119, 12359f0, 0, 0, 6) at ltsleep+0x268
ttysleep(136cc380, 1, 119, 12359f0, 0, 0) at ttysleep+0x18
ttread(136cc380, 136cc390, 0, 141db980, 0, 1425fba0) at ttread+0x33c
ptsread(136cc380, 1425fba0, 0, 640, 106ad80, 180e520) at ptsread+0x21c
spec_read(1425fa90, 58, 1090d80, 1237c00, 2167200, 0) at spec_read+0xf4
ufsspec_read(1425fa90, 58, 118b000, 2166c00, ffffffffffffd200, ffffffffffffd1f8) at ufsspec_read+0x50
vn_read(0, 14216fe8, 1425fba0, 2258400, 1, 1086960) at vn_read+0xd8
dofileread(141db980, a, 14216fb0, 1, 1, 14216fe8) at dofileread+0x88
sys_read(141db980, 1425fdd0, 1425fdc0, 105f100, ffffffffffffcf4f, 447a) at sys_read+0x74
syscall(1425fed0, 3, 0, 407a6258, 400, 8) at syscall+0x36c
syscall_setup(a, ffffffffffffcf4f, 1, 0, 0, 0) at syscall_setup+0x12c
db> 

>How-To-Repeat:
	Use network on Netra X1.

>Fix:
	Applying the following patch stops krenel panic,
	but I don't know this is the right solution.
	(patch contains also fix to build 32bit kernels.)

Index: iommu.c
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/sparc64/dev/iommu.c,v
retrieving revision 1.47
diff -u -r1.47 iommu.c
--- iommu.c	2002/02/08 20:03:45	1.47
+++ iommu.c	2002/02/16 13:06:45
@@ -667,7 +667,7 @@
 		if (map->dm_segs[seg].ds_addr < is->is_dvmabase ||
 			map->dm_segs[seg].ds_addr > is->is_dvmaend) {
 			printf("seg %d dvmaddr %lx out of range %x - %x\n",
-				seg, map->dm_segs[seg].ds_addr, 
+				seg, (u_long)map->dm_segs[seg].ds_addr, 
 				is->is_dvmabase, is->is_dvmaend);
 			Debugger();
 		}
@@ -842,7 +842,7 @@
 			sgend = sgstart + left - 1;
 
 			/* Are the segments virtually adjacent? */
-			if ((end == offset) && 
+			if ((j > 0) && (end == offset) && 
 				((offset == 0) || (pa == prev_pa))) {
 				/* Just append to the previous segment. */
 #ifdef DEBUG
@@ -923,7 +923,7 @@
 		if (map->dm_segs[seg].ds_addr < is->is_dvmabase ||
 			map->dm_segs[seg].ds_addr > is->is_dvmaend) {
 			printf("seg %d dvmaddr %lx out of range %x - %x\n",
-				seg, map->dm_segs[seg].ds_addr, 
+				seg, (u_long)map->dm_segs[seg].ds_addr, 
 				is->is_dvmabase, is->is_dvmaend);
 			Debugger();
 		}
@@ -988,7 +988,7 @@
 		if (map->dm_segs[seg].ds_addr < is->is_dvmabase ||
 			map->dm_segs[seg].ds_addr > is->is_dvmaend) {
 			printf("seg %d dvmaddr %lx out of range %x - %x\n",
-				seg, map->dm_segs[seg].ds_addr, 
+				seg, (u_long)map->dm_segs[seg].ds_addr, 
 				is->is_dvmabase, is->is_dvmaend);
 			Debugger();
 		}

>Release-Note:
>Audit-Trail:
>Unformatted: