Wednesday, December 7, 2016

Every Thread Starts with an IRET

I noticed I haven't written much for quite a long time. So, let's see. While working out the beginnings of my own operating system I came across the realization that every user mode thread pretty much needs to start with an IRET.

What's an IRET? It's an Interrupt RETurn instruction. It tells the CPU that it should be returning from an interrupt and as such, needs to pop some additional state off the stack. The funny thing is part of this state is which ring protection level to resume. You can transition to higher (and thus lower privilege) RPLs using IRET. It's also apparently the only way to perform this transition.

So... something even cooler (at least to me). Every single time a thread is reactivated from a context switch it is actually resuming via an IRET instruction. The symmetry of this made me happy. If a user mode thread issues a system call (Sleep, WaitForSingleObject, ReadFile, WriteFile, etc.) that's an interrupt! If a thread runs out of quantum, it will get kicked out by a timer interrupt.

The tricky part is getting the stack set up in such a way that the IRET pops off all the register context just how you need it to. Luckily, this is actually pretty easy (the instruction which triggered the interrupt did that for us). It's quite a bit harder to actually start a thread, because all those values need to be properly initialized by the kernel code.

Because I know everyone is curious, here's some additional resources: