summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2024-06-15 18:01:45 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2024-06-15 18:01:45 +0000
commitb9d8abb10feb3cfd2bd273ee3d3b91850e6529cd (patch)
tree4e412ed78d9e5a5ff7ce39f46c81d670527b58dc
parent3e0095641cc79b5fcb73ae14ac7697cd67c27b4f (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.c11
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;