Subject: Re: port-shark/22355 [was: Help needed to fix NetBSD/shark]
To: None <chris@dokein.co.uk>
From: Izumi Tsutsui <tsutsui@ceres.dti.ne.jp>
List: port-arm
Date: 08/05/2007 20:25:26
chris@dokein.co.uk wrote:

> What worries me, and a version with more debugging that jmmv ran showed
> errors that clockintr doesn't reset the the spl level after every call,
> which is why the mask is wrong.
> 
> So these patches are just hiding an underlying bug somewhere else by
> reseting the spl_mask after interrupt routines are called, however the
> mask should have been reset back by an splx call.

The attached one also seems to fix the problem.
(use spl_masks[current_spl_level] rather than spl_mask in irq_setmask())

If clockintr() occurs during interrupt handlers for lower SPLs,
it will be served with wrong spl_mask which is not matched
with current_spl_level.

I haven't tracked how spl_mask could be corrupted in the recursive case,
but this patch doesn't reset spl_mask so I don't think it could hide
other problems.

(BTW, why do we have an independent spl_mask variable?)
---
Izumi Tsutsui


Index: shark/isa/isa_irq.S
===================================================================
RCS file: /cvsroot/src/sys/arch/shark/isa/isa_irq.S,v
retrieving revision 1.7
diff -u -r1.7 isa_irq.S
--- shark/isa/isa_irq.S	9 Mar 2007 19:21:59 -0000	1.7
+++ shark/isa/isa_irq.S	5 Aug 2007 10:56:20 -0000
@@ -297,9 +297,11 @@
 	/* NOT REACHED */
 	b	. - 8
 
+#if 0
 Lspl_mask:
 	.word	_C_LABEL(spl_mask)	/* irq's allowed at current spl level */
 
+#endif
 Lcurrent_mask:
 	.word	_C_LABEL(current_mask)	/* irq's that are usable */
 
@@ -317,9 +319,16 @@
 	/* Calculate interrupt mask */
 	ldr	r1, Lcurrent_mask	/* All the enabled interrupts */
 	ldrh	r1, [r1]		/* get hardware bits of mask */
+#if 0
 /*	.word	0xe0d110b0 */		/* hand-assembled ldrh r1, [r1] */
 	ldr	r2, Lspl_mask		/* Block due to current spl level */
 	ldr	r2, [r2]
+#else
+	ldr	r2, Lcurrent_spl_level
+	ldr	r2, [r2]
+	ldr	r0, Lspl_masks
+	ldr	r2, [r0, r2, lsl #2]
+#endif
 	and	r1, r1, r2
 	ldr	r2, Ldisabled_mask	/* Block due to active interrupts */
 	ldr	r2, [r2]