From fe107fbad3c4977a58b20b7ac65a90bec0188950 Mon Sep 17 00:00:00 2001 From: Max Wash Date: Mon, 23 Feb 2026 18:24:49 +0000 Subject: [PATCH] kernel: locks: add spin lock/unlock function that don't change interrupt state --- arch/user/hwlock.c | 2 +- arch/x86_64/hwlock.S | 45 +++++++++++++++++++-- arch/x86_64/include/kernel/machine/hwlock.h | 3 ++ include/kernel/locks.h | 12 ++++-- 4 files changed, 53 insertions(+), 9 deletions(-) diff --git a/arch/user/hwlock.c b/arch/user/hwlock.c index 0074865..6c635ff 100644 --- a/arch/user/hwlock.c +++ b/arch/user/hwlock.c @@ -1,5 +1,5 @@ -#include #include +#include void ml_hwlock_lock(ml_hwlock_t *lck) { diff --git a/arch/x86_64/hwlock.S b/arch/x86_64/hwlock.S index b659333..9ee5f86 100644 --- a/arch/x86_64/hwlock.S +++ b/arch/x86_64/hwlock.S @@ -11,6 +11,41 @@ ml_hwlock_lock: mov $1, %ecx + mfence + +1: mov $0, %eax + lock cmpxchg %ecx, (%rdi) + jne 1b + + pop %rbp + ret + + + .global ml_hwlock_unlock + .type ml_hwlock_unlock, @function + + /* %rdi = pointer to ml_hwlock_t (int) */ +ml_hwlock_unlock: + push %rbp + mov %rsp, %rbp + + movl $0, (%rdi) + mfence + + pop %rbp + ret + + + .global ml_hwlock_lock_irq + .type ml_hwlock_lock_irq, @function + + /* %rdi = pointer to ml_hwlock_t (int) */ +ml_hwlock_lock_irq: + push %rbp + mov %rsp, %rbp + + mov $1, %ecx + cli mfence @@ -21,11 +56,12 @@ ml_hwlock_lock: pop %rbp ret - .global ml_hwlock_unlock - .type ml_hwlock_unlock, @function + + .global ml_hwlock_unlock_irq + .type ml_hwlock_unlock_irq, @function /* %rdi = pointer to ml_hwlock_t (int) */ -ml_hwlock_unlock: +ml_hwlock_unlock_irq: push %rbp mov %rsp, %rbp @@ -42,7 +78,7 @@ ml_hwlock_unlock: /* %rdi = pointer to ml_hwlock_t (int) %rsi = pointer to quadword to store rflags in */ -ml_hwlock_lock_irqsave: +ml_hwlock_lock_irqsave: push %rbp mov %rsp, %rbp @@ -62,6 +98,7 @@ ml_hwlock_lock_irqsave: pop %rbp ret + .global ml_hwlock_unlock_irqrestore .type ml_hwlock_unlock_irqrestore, @function diff --git a/arch/x86_64/include/kernel/machine/hwlock.h b/arch/x86_64/include/kernel/machine/hwlock.h index 355e82c..4d83654 100644 --- a/arch/x86_64/include/kernel/machine/hwlock.h +++ b/arch/x86_64/include/kernel/machine/hwlock.h @@ -12,6 +12,9 @@ typedef int ml_hwlock_t; extern void ml_hwlock_lock(ml_hwlock_t *lck); extern void ml_hwlock_unlock(ml_hwlock_t *lck); +extern void ml_hwlock_lock_irq(ml_hwlock_t *lck); +extern void ml_hwlock_unlock_irq(ml_hwlock_t *lck); + extern void ml_hwlock_lock_irqsave(ml_hwlock_t *lck, unsigned long *flags); extern void ml_hwlock_unlock_irqrestore(ml_hwlock_t *lck, unsigned long flags); diff --git a/include/kernel/locks.h b/include/kernel/locks.h index 8ff7098..83feacb 100644 --- a/include/kernel/locks.h +++ b/include/kernel/locks.h @@ -10,13 +10,17 @@ extern "C" { typedef __aligned(8) ml_hwlock_t spin_lock_t; -#define SPIN_LOCK_INIT ML_HWLOCK_INIT +#define SPIN_LOCK_INIT ML_HWLOCK_INIT -#define spin_lock(lck) ml_hwlock_lock(lck); -#define spin_unlock(lck) ml_hwlock_unlock(lck); +#define spin_lock(lck) ml_hwlock_lock(lck); +#define spin_unlock(lck) ml_hwlock_unlock(lck); + +#define spin_lock_irq(lck) ml_hwlock_lock_irq(lck); +#define spin_unlock_irq(lck) ml_hwlock_unlock_irq(lck); #define spin_lock_irqsave(lck, flags) ml_hwlock_lock_irqsave(lck, flags); -#define spin_unlock_irqrestore(lck, flags) ml_hwlock_unlock_irqrestore(lck, flags); +#define spin_unlock_irqrestore(lck, flags) \ + ml_hwlock_unlock_irqrestore(lck, flags); #ifdef __cplusplus }