diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2009-07-30 14:50:21 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2009-07-30 14:50:21 +0000 |
commit | 0a15cc620829179e98a3f8bfab7652d2ba2a708f (patch) | |
tree | 8466a9430176a2e79ddc96f7630ef566fb84358b /sys/arch/hppa | |
parent | ace0f2fb19ea2ef51691f1edcc534bf85f27a736 (diff) |
Disable interrupts when we enter cpu_intr() and enable them again when leaving
that function. It seems this function was intended to be called with
interrupts disabled but that is not (no longer?) the case. As a result
there were some races accessing the list of interrupt handlers and we would
leave the function with interrupts disabled if there were any interrupts
pending. This could make us end up in the idle loop with interrupts disabled,
which would "hang" the machine.
Found with help from deraadt@
Diffstat (limited to 'sys/arch/hppa')
-rw-r--r-- | sys/arch/hppa/hppa/intr.c | 9 |
1 files changed, 7 insertions, 2 deletions
diff --git a/sys/arch/hppa/hppa/intr.c b/sys/arch/hppa/hppa/intr.c index 83af9991634..7f4ba5f7a9e 100644 --- a/sys/arch/hppa/hppa/intr.c +++ b/sys/arch/hppa/hppa/intr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: intr.c,v 1.25 2008/05/19 18:42:12 miod Exp $ */ +/* $OpenBSD: intr.c,v 1.26 2009/07/30 14:50:20 kettenis Exp $ */ /* * Copyright (c) 2002-2004 Michael Shalayeff @@ -284,8 +284,11 @@ cpu_intr(void *v) { struct trapframe *frame = v; u_long mask; - int s = cpl; + int s; + mtctl(0, CR_EIEM); + + s = cpl; if (cpu_inintr++) frame->tf_flags |= TFF_INTR; @@ -321,6 +324,8 @@ cpu_intr(void *v) } cpu_inintr--; cpl = s; + + mtctl(frame->tf_eiem, CR_EIEM); } |