aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/riscv64/kernel/entry.S2
-rw-r--r--arch/riscv64/kernel/proc.c2
-rw-r--r--include/arch/lock.h2
-rw-r--r--include/kmi/bkl.h18
-rw-r--r--include/kmi/lock.h2
-rw-r--r--src/bkl.c3
-rw-r--r--src/dispatch.c3
-rw-r--r--src/ipi.c8
-rw-r--r--src/main.c5
-rw-r--r--src/timer.c7
-rw-r--r--src/uapi/ipc.c4
11 files changed, 50 insertions, 6 deletions
diff --git a/arch/riscv64/kernel/entry.S b/arch/riscv64/kernel/entry.S
index 815694b..1680a35 100644
--- a/arch/riscv64/kernel/entry.S
+++ b/arch/riscv64/kernel/entry.S
@@ -90,7 +90,7 @@ continue_trap:
save_regs
save_args
- mv t5, a0
+ mv a0, t5
call riscv_handle_interrupt
j _load_context
diff --git a/arch/riscv64/kernel/proc.c b/arch/riscv64/kernel/proc.c
index 55ccbb8..0c43b3d 100644
--- a/arch/riscv64/kernel/proc.c
+++ b/arch/riscv64/kernel/proc.c
@@ -8,6 +8,7 @@
#include <kmi/tcb.h>
#include <kmi/elf.h>
+#include <kmi/bkl.h>
#include <kmi/string.h>
#include <arch/proc.h>
@@ -27,6 +28,7 @@ void run_init(struct tcb *t, vm_t fdt, vm_t initrd)
* Could be fixed with a separate pure asm run_init, but I guess this
* works for now.
*/
+ bkl_unlock();
__asm__ volatile ("mv sp, %0\n"
"mv a0, %1\n"
"mv a1, %2\n"
diff --git a/include/arch/lock.h b/include/arch/lock.h
index 2a94fbf..ea19585 100644
--- a/include/arch/lock.h
+++ b/include/arch/lock.h
@@ -11,7 +11,7 @@
#if defined(riscv64)
#include "../../arch/riscv64/include/lock.h"
-#if defined(riscv32)
+#elif defined(riscv32)
#include "../../arch/riscv32/include/lock.h"
#endif
diff --git a/include/kmi/bkl.h b/include/kmi/bkl.h
new file mode 100644
index 0000000..26dfaa8
--- /dev/null
+++ b/include/kmi/bkl.h
@@ -0,0 +1,18 @@
+#ifndef KMI_BKL_H
+#define KMI_BKL_H
+
+#include <kmi/lock.h>
+
+extern spinlock_t bkl;
+
+static inline void bkl_lock()
+{
+ spin_lock(&bkl);
+}
+
+static inline void bkl_unlock()
+{
+ spin_unlock(&bkl);
+}
+
+#endif /* KMI_BKL_H */
diff --git a/include/kmi/lock.h b/include/kmi/lock.h
index 31cf1aa..f24413c 100644
--- a/include/kmi/lock.h
+++ b/include/kmi/lock.h
@@ -33,7 +33,6 @@ typedef atomic_int spinlock_t;
*/
static inline void spin_lock(spinlock_t *lck)
{
- disable_irq();
do {
while (atomic_load_explicit(lck, memory_order_acquire))
optional_pause();
@@ -49,7 +48,6 @@ static inline void spin_lock(spinlock_t *lck)
static inline void spin_unlock(spinlock_t *lck)
{
atomic_store_explicit(lck, 0, memory_order_release);
- enable_irq();
}
#endif /* KMI_LOCK_H */
diff --git a/src/bkl.c b/src/bkl.c
new file mode 100644
index 0000000..6dc120f
--- /dev/null
+++ b/src/bkl.c
@@ -0,0 +1,3 @@
+#include <kmi/lock.h>
+
+spinlock_t bkl = 0;
diff --git a/src/dispatch.c b/src/dispatch.c
index 2786678..222611b 100644
--- a/src/dispatch.c
+++ b/src/dispatch.c
@@ -2,6 +2,7 @@
/* Copyright 2023 Kim Kuparinen < kimi.h.kuparinen@gmail.com > */
#include <kmi/uapi.h>
+#include <kmi/bkl.h>
#include <kmi/ipi.h>
/**
@@ -31,5 +32,7 @@
void dispatch(sys_arg_t a, sys_arg_t b, sys_arg_t c,
sys_arg_t d, sys_arg_t e, sys_arg_t f)
{
+ bkl_lock();
handle_syscall(a, b, c, d, e, f, cur_tcb());
+ bkl_unlock();
}
diff --git a/src/ipi.c b/src/ipi.c
index d00ba1c..eed3895 100644
--- a/src/ipi.c
+++ b/src/ipi.c
@@ -3,6 +3,7 @@
#include <kmi/notify.h>
#include <kmi/queue.h>
+#include <kmi/bkl.h>
#include <kmi/ipi.h>
#include <arch/proc.h>
@@ -33,14 +34,19 @@ void unqueue_ipi(struct tcb *t)
void handle_ipi()
{
+ bkl_lock();
+
struct tcb *t = cur_tcb();
adjust_ipi(t);
struct queue_head *q = queue_pop(&fifo);
- if (!q)
+ if (!q) {
+ bkl_unlock();
return;
+ }
struct tcb *r = container_of(q, struct tcb, ipi_queue);
notify(r, 0);
/* notify didn't take for whatever reason so return whence we came from */
+ bkl_unlock();
}
diff --git a/src/main.c b/src/main.c
index 506d7fe..33d9596 100644
--- a/src/main.c
+++ b/src/main.c
@@ -14,6 +14,7 @@
#include <kmi/debug.h>
#include <kmi/vmem.h>
#include <kmi/irq.h>
+#include <kmi/bkl.h>
#include <arch/arch.h>
#include <arch/proc.h>
#include <arch/smp.h>
@@ -60,6 +61,8 @@ __noreturn void kernel(void *fdt, uintptr_t load_addr, struct vmem *d)
/* we should be in kernelspace, so use the virtual address of our FDT. */
fdt = __va(fdt);
+ bkl_lock();
+
/* dbg uses direct mapping at this point */
init_dbg(fdt);
/* start up debugging in kernel IO */
@@ -101,6 +104,8 @@ __noreturn void main(unsigned long hart, void *fdt, uintptr_t load_addr)
* have to get the function signature right */
(void)hart;
+ /** @todo some kind of lottery? */
+
pm_t ram_base = __fdt_ram_base(fdt);
pm_t ram_size = __fdt_ram_size(fdt);
set_ram_base(ram_base);
diff --git a/src/timer.c b/src/timer.c
index 2607584..2d4ff01 100644
--- a/src/timer.c
+++ b/src/timer.c
@@ -21,6 +21,7 @@
#include <kmi/notify.h>
#include <kmi/nodes.h>
#include <kmi/utils.h>
+#include <kmi/bkl.h>
#include <kmi/timer.h>
#include <kmi/debug.h>
#include <arch/cpu.h>
@@ -197,12 +198,16 @@ ticks_t nsecs_to_ticks(tunit_t nsecs)
/* call to this function from exception handlers */
void handle_timer()
{
+ bkl_lock();
struct timer *t = newest_timer();
remove_timer(t);
struct tcb *r = get_tcb(t->tid);
- if (!r)
+ if (!r) {
+ bkl_unlock();
return;
+ }
notify(r, NOTIFY_TIMER);
+ bkl_unlock();
}
diff --git a/src/uapi/ipc.c b/src/uapi/ipc.c
index 3c24f1c..613d4a9 100644
--- a/src/uapi/ipc.c
+++ b/src/uapi/ipc.c
@@ -9,6 +9,7 @@
#include <kmi/orphanage.h>
#include <kmi/debug.h>
#include <kmi/uapi.h>
+#include <kmi/bkl.h>
#include <kmi/tcb.h>
#include <kmi/ipi.h>
#include <kmi/irq.h>
@@ -171,6 +172,8 @@ static __noreturn void __run_notify(struct tcb *t, struct tcb *r)
finalize_rpc(t, r, s);
clear_bits(t->notify_flags, flags);
+
+ bkl_unlock();
ret_userspace_fast();
unreachable();
}
@@ -335,6 +338,7 @@ static void do_ipc(struct tcb *t,
/* I tested out passing the return values as arguments to
* ret_userspace_fast, but apparently that causes enough stack shuffling
* to be slower overall. */
+ bkl_unlock();
ret_userspace_fast();
}
/**