diff options
| -rw-r--r-- | arch/riscv64/kernel/entry.S | 2 | ||||
| -rw-r--r-- | arch/riscv64/kernel/proc.c | 2 | ||||
| -rw-r--r-- | include/arch/lock.h | 2 | ||||
| -rw-r--r-- | include/kmi/bkl.h | 18 | ||||
| -rw-r--r-- | include/kmi/lock.h | 2 | ||||
| -rw-r--r-- | src/bkl.c | 3 | ||||
| -rw-r--r-- | src/dispatch.c | 3 | ||||
| -rw-r--r-- | src/ipi.c | 8 | ||||
| -rw-r--r-- | src/main.c | 5 | ||||
| -rw-r--r-- | src/timer.c | 7 | ||||
| -rw-r--r-- | src/uapi/ipc.c | 4 |
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(); } @@ -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(); } @@ -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(); } /** |
