Ring 0 multithreading

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
protegee6155
Posts: 24
Joined: Tue Dec 16, 2025 4:17 am

Re: Ring 0 multithreading

Post by protegee6155 »

Well, never mind — I think I should research this topic a bit more so I don’t end up asking overly general questions for nothing. After learning more, I’ll probably create a new post with a more meaningful and focused question.

In any case, thank you all for the help!!! 😄
User avatar
bellezzasolo
Member
Member
Posts: 163
Joined: Sun Feb 20, 2011 2:01 pm

Re: Ring 0 multithreading

Post by bellezzasolo »

protegee6155 wrote: Tue Jan 13, 2026 1:09 pm Hmm, okay, that somewhat makes sense.
So in that case, should my interrupt-handling code—the part that executes iret at the end—also serve as my context-switch function?
It's an interesting one to tackle design-wise. You almost certainly want the ability to context-switch in a device interrupt - for the purpose of timer preemption. And context-switching in a syscall is key to blocking.

Thing is, you also want to send the EOI in the device interrupt case. So you need to make sure the EOI is sent before doing the context switch.

Since you also want to restore flags, at the point of switching, IRET isn't actually a bad way of doing it. With a bit of pseudo-assembly:

Code: Select all

context_switch(current_context, next_context):
pop rax ;return address
;Build iret frame
pushfq
push cs
push rax
mov [current_context.stack_ptr], rsp

mov rsp, [next_context.stack_ptr]
iretq

Whoever said you can't do OS development on Windows?
https://github.com/ChaiSoft/ChaiOS
Octocontrabass
Member
Member
Posts: 6245
Joined: Mon Mar 25, 2013 7:01 pm

Re: Ring 0 multithreading

Post by Octocontrabass »

protegee6155 wrote: Tue Jan 13, 2026 1:09 pmSo in that case, should my interrupt-handling code—the part that executes iret at the end—also serve as my context-switch function?
No. That makes context switching more complicated for no reason, and that extra complexity will come back and bite you later. Stick to something like the switch_to_task example.
bellezzasolo wrote: Wed Jan 14, 2026 6:27 amSince you also want to restore flags,
Do you? Tasks that will return to ring 3 will restore their flags when they return to ring 3. What other flags would you want to restore?
User avatar
bellezzasolo
Member
Member
Posts: 163
Joined: Sun Feb 20, 2011 2:01 pm

Re: Ring 0 multithreading

Post by bellezzasolo »

Octocontrabass wrote: Wed Jan 14, 2026 8:56 pm
protegee6155 wrote: Tue Jan 13, 2026 1:09 pmSo in that case, should my interrupt-handling code—the part that executes iret at the end—also serve as my context-switch function?
No. That makes context switching more complicated for no reason, and that extra complexity will come back and bite you later. Stick to something like the switch_to_task example.
bellezzasolo wrote: Wed Jan 14, 2026 6:27 amSince you also want to restore flags,
Do you? Tasks that will return to ring 3 will restore their flags when they return to ring 3. What other flags would you want to restore?
The interrupt flag. While you might get away with mov rsp, [x] being atomic, you're still in a context switch procedure, quite possibly triggered from a hardware interrupt. To avoid stack overflow, you've probably done something like:

Code: Select all

cli
EOI()
next_context = schedule()
if(next_context) context_switch(next_context)
iret
As if you have interrupts enabled, it's theoretically possible to get into an overloaded state where another int keeps firing before you iret.

And just generally being interrupted during a context switch seems messy to reason about as you now hav reentrancy into the scheduler.

But, if you go into it with IF off, you now resume on a syscall / sysret, which doesn't necessariy touch flags (and you may well want the kernel to be preemptible while servicing a system call).

Neater I think to just save/restore flags as part of the context switch.
Whoever said you can't do OS development on Windows?
https://github.com/ChaiSoft/ChaiOS
nullplan
Member
Member
Posts: 2034
Joined: Wed Aug 30, 2017 8:24 am

Re: Ring 0 multithreading

Post by nullplan »

bellezzasolo wrote: Thu Jan 15, 2026 2:40 am And just generally being interrupted during a context switch seems messy to reason about as you now hav reentrancy into the scheduler.
So long as stack overflow is avoided (and if you are implementing a pre-emptible kernel, you typically still don't re-enable the interrupt flag if only a small amount of stack remains), it is not harder to reason about an interrupt in the scheduler than an interrupt in any other place. All shared state must be spinlock-protected anyway (unless you have the kind of space brain necessary to implement lockless algorithms) and spinlocks shared with interrupt handlers must disable the interrupt flag when taken.
bellezzasolo wrote: Thu Jan 15, 2026 2:40 am Neater I think to just save/restore flags as part of the context switch.
Yes, if the interrupt flag can be different between contexts, then it should also be preserved by the task switcher. That is one more pushfd before and one more popfd after the stack switch.

Indeed I left a lot out of there. For example, switching CR3, possibly handling the debug registers, the FPU/SSE and other state. But all of this can be added later, once the principle is out of the way.
Carpe diem!
Post Reply