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]