Subject: port-hpcmips/26158: cpu_intr problems
To: None <gnats-bugs@gnats.netbsd.org>
From: Matthew Orgass <darkstar@city-net.com>
List: netbsd-bugs
Date: 07/03/2004 20:37:33
>Number:         26158
>Category:       port-hpcmips
>Synopsis:       cpu_intr problems
>Confidential:   no
>Severity:       serious
>Priority:       high
>Responsible:    port-hpcmips-maintainer
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sun Jul 04 00:47:00 UTC 2004
>Closed-Date:
>Last-Modified:
>Originator:     darkstar@city-net.com
>Release:        NetBSD 2.0_BETA
>Organization:
>Environment:
>Description:

  The hpcmips cpu_intr routines are incorrect.  The vr code will allow
non-clock hard interrupts to interrupt hardclock and can allow stack
overflow during high interrupt activity.  The TX code will keep hard
interrupts blocked while executing soft ISRs if a hard and soft interrupt
occur at the same time and looks like it could give soft interrupts
priority over hard interrupts.  It can also allow stack overflow.

>How-To-Repeat:
>Fix:

  This is just a fix for vr.c.  Something similar should be done in
tx39icu.c.  This patch lowers the priority in strict order and never
unmasks the lowest pending interrupt.  This will bound stack usage.

Index: vr.c
===================================================================
RCS file: /cvsroot/src/sys/arch/hpcmips/vr/vr.c,v
retrieving revision 1.44
diff -u -r1.44 vr.c
--- vr.c	25 Oct 2003 18:04:34 -0000	1.44
+++ vr.c	3 Jul 2004 07:38:54 -0000
@@ -546,33 +546,27 @@
 {
 	uvmexp.intrs++;

+	/* Deal with unneded compare interrupts occasionally so that we can
+	 * keep spllowersoftclock. */
 	if (ipending & MIPS_INT_MASK_5) {
-		/*
-		 * spl* uses MIPS_INT_MASK not MIPS3_INT_MASK. it causes
-		 * INT5 interrupt.
-		 */
-		mips3_cp0_compare_write(mips3_cp0_count_read());
+		mips3_cp0_compare_write(0);
 	}

-	/* for spllowersoftclock */
-	_splset(((status & ~cause) & MIPS_HARD_INT_MASK) | MIPS_SR_INT_IE);
-
 	if (ipending & MIPS_INT_MASK_1) {
+		_splset(MIPS_SR_INT_IE); /* for spllowersoftclock */
 		(*vr_intr_handler[1])(vr_intr_arg[1], pc, status);
-
-		cause &= ~MIPS_INT_MASK_1;
-		_splset(((status & ~cause) & MIPS_HARD_INT_MASK)
-		    | MIPS_SR_INT_IE);
 	}

 	if (ipending & MIPS_INT_MASK_0) {
+		_splset(MIPS_INT_MASK_1|MIPS_SR_INT_IE);
 		(*vr_intr_handler[0])(vr_intr_arg[0], pc, status);
-
-		cause &= ~MIPS_INT_MASK_0;
 	}
-	_splset(((status & ~cause) & MIPS_HARD_INT_MASK) | MIPS_SR_INT_IE);

-	softintr(ipending);
+	/* XXX sofintr priorities should be separated. */
+	if (ipending & (MIPS_SOFT_INT_MASK_1|MIPS_SOFT_INT_MASK_0)) {
+		_splset(MIPS_INT_MASK_1|MIPS_INT_MASK_0|MIPS_SR_INT_IE);
+		softintr(ipending);
+	}
 }

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