Bug that I just discovered in my OS: typing "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" really quickly in the editor can cause a kernel panic.

(It also works for other keys, as long as you hit them really quickly. A long "a" is just the funniest.)

Current hypothesis: `message:match-receive!' does a lot of recursion, so it might cause a stack overflow.

I might actually just end up replacing the stack model, instantly fixing continuations in the process!

My plan is to allocate stack frames just like all other allocations, so continuations can just store a pointer to the top stack frame rather than a whole copy of the stack. (In other words, I want to switch to saguaro stacks.)

The main issue: the kernel needs a stack but can't always allocate memory, e.g. at startup when memory isn't initialized yet, or when the garbage collector is running. Allocating a traditional stack for the kernel is not an issue on the continuation level. However, the kernel and userspace share a codebase. So I guess I have to dynamically determine how to deal with the stack? Seems awkward...

Alternatively, microkernelize the system further and move all stack-related stuff to a userspace process.


Hmm, what if the rule is "before grabbing the memory lock, you must reserve a bunch of stack frames" and "when creating a stack frame, if the memory lock is held (therefore you are in the kernel), use one of the reserved frames instead"

· · Web · 1 · 0 · 0

Or! I can just set up multiple allocation arenas and ensure the kernel never locks its own arena. But that's hard :(

Looking through kernel code, there isn't actually much, if any, userspace code being called while a memory lock is held (this makes sense: userspace code is allowed to do allocations!). It might just be possible to implement saguaro stacks without too many headaches.

Ok, this might actually work: replace the current userspace function header with `if top_kernelstack < sp < bottom_kernelstack: panic("don't call userspace functions from the kernel!") # this is a cheap check that doesn't read system registers' declare a new function header doing exactly the opposite, then assign each function to the appropriate side of the divide. (Duplicating or adding a kernel->user call gate.)

Once everything works again, replace the usermode stack implementation.

Just figured out another complication: my plan was to allocate a frame for the kernel to use when taking an exception from user mode and put it in the supervisor stack pointer register. This works well! Until there's a kernelmode -> kernelmode exception (e.g. to swap in a page), and you have nowhere to put your registers since the stack pointer is useless.

Sign in to participate in the conversation

Mastodon is a server for a federated social network: everyone can run a server if they want to, including me. So this is a Mastodon server for me (Vierkantor) and my friends.