From e105fa42d5ddb6ff7bfbbb964c4b93415b22b05a Mon Sep 17 00:00:00 2001 From: Ian Moffett Date: Fri, 21 Nov 2025 14:20:15 -0500 Subject: kern: Improve IRQ mask modification on spinlocks Signed-off-by: Ian Moffett --- sys/arch/amd64/cpu/cpu.c | 10 ++++++++++ sys/arch/amd64/cpu/spinlock.c | 16 ++++++++++------ 2 files changed, 20 insertions(+), 6 deletions(-) (limited to 'sys/arch/amd64') diff --git a/sys/arch/amd64/cpu/cpu.c b/sys/arch/amd64/cpu/cpu.c index 4edc850..d9093fd 100644 --- a/sys/arch/amd64/cpu/cpu.c +++ b/sys/arch/amd64/cpu/cpu.c @@ -29,11 +29,21 @@ #include #include +#include #include #include #include #include +bool +mu_irq_state(void) +{ + uint64_t rflags; + + __asmv("pushfq; pop %0" : "=r" (rflags) :: "memory"); + return ISSET(rflags, BIT(9)) != 0; +} + struct cpu_info * cpu_self(void) { diff --git a/sys/arch/amd64/cpu/spinlock.c b/sys/arch/amd64/cpu/spinlock.c index 1cfa088..6857aa6 100644 --- a/sys/arch/amd64/cpu/spinlock.c +++ b/sys/arch/amd64/cpu/spinlock.c @@ -29,12 +29,15 @@ #include #include +#include void mu_spinlock_acq(volatile size_t *lock, int flags) { - if (ISSET(flags, SPINLOCK_INTTOG)) { - asm volatile("cli"); + bool irq_en = mu_irq_state(); + + if (ISSET(flags, SPINLOCK_INTTOG) && irq_en) { + __asmv("cli"); } __asmv( @@ -48,6 +51,11 @@ mu_spinlock_acq(volatile size_t *lock, int flags) : "r" (lock) : "memory", "rax" ); + + if (ISSET(flags, SPINLOCK_INTTOG)) { + if (irq_en && !mu_irq_state()) + __asmv("sti"); + } } void @@ -60,8 +68,4 @@ mu_spinlock_rel(volatile size_t *lock, int flags) : : "memory", "rax" ); - - if (ISSET(flags, SPINLOCK_INTTOG)) { - asm volatile("sti"); - } } -- cgit v1.2.3