diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2024-06-15 18:01:45 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2024-06-15 18:01:45 +0000 |
commit | b9d8abb10feb3cfd2bd273ee3d3b91850e6529cd (patch) | |
tree | 4e412ed78d9e5a5ff7ce39f46c81d670527b58dc | |
parent | 3e0095641cc79b5fcb73ae14ac7697cd67c27b4f (diff) |
We should block non-wakeup interrupts until we're in the resume path and
have disabled interrupts at the CPU level again. So instead of
cpu_suspended use a new intr_suspended variable that is set and cleared in
intr_enable_wakeup() and intr_disable_wakeup().
ok mglocker@, mlarkin@
-rw-r--r-- | sys/arch/amd64/amd64/intr.c | 11 |
1 files changed, 8 insertions, 3 deletions
diff --git a/sys/arch/amd64/amd64/intr.c b/sys/arch/amd64/amd64/intr.c index dcef658cc02..88c65f26855 100644 --- a/sys/arch/amd64/amd64/intr.c +++ b/sys/arch/amd64/amd64/intr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: intr.c,v 1.59 2024/06/07 06:26:23 jsg Exp $ */ +/* $OpenBSD: intr.c,v 1.60 2024/06/15 18:01:44 kettenis Exp $ */ /* $NetBSD: intr.c,v 1.3 2003/03/03 22:16:20 fvdl Exp $ */ /* @@ -73,6 +73,8 @@ struct pic softintr_pic = { NULL, }; +int intr_suspended; + /* * Fill in default interrupt table (in case of spurious interrupt * during configuration of kernel), setup interrupt control unit @@ -524,7 +526,6 @@ intr_disestablish(struct intrhand *ih) int intr_handler(struct intrframe *frame, struct intrhand *ih) { - extern int cpu_suspended; struct cpu_info *ci = curcpu(); int floor; int rc; @@ -536,7 +537,7 @@ intr_handler(struct intrframe *frame, struct intrhand *ih) * We may not be able to mask MSIs, so block non-wakeup * interrupts while we're suspended. */ - if (cpu_suspended && (ih->ih_flags & IPL_WAKEUP) == 0) + if (intr_suspended && (ih->ih_flags & IPL_WAKEUP) == 0) return 0; #ifdef MULTIPROCESSOR @@ -723,6 +724,8 @@ intr_enable_wakeup(void) if (pic->pic_hwmask) pic->pic_hwmask(pic, pin); } + + intr_suspended = 1; } void @@ -732,6 +735,8 @@ intr_disable_wakeup(void) struct pic *pic; int irq, pin; + intr_suspended = 0; + for (irq = 0; irq < MAX_INTR_SOURCES; irq++) { if (ci->ci_isources[irq] == NULL) continue; |