I can't quite understand how a preemptible kernel is supposed to work, meaning that one task can be interrupted while doing a syscall. My kernel supports user and kernel privilege threads. Each user level thread has a kernel stack and a userspace stack. Each kernel level thread only has one stack where the registers are just pushed on-top when an interrupt occurs. This means a system call from userspace currently looks like this:
Code: Select all
Userspace task running
-> System call is fired
-> CPU pushes SS, ESP, EFLAGS, CS, EIP (to kernel stack of user task)
-> Enters interrupt handler
--> CLI so we don't get interrupted
--> Push general registers (to kernel stack of user task)
--> Store register state in task structure
---> System call is processed
--> Restore register state from task structure
--> Interrupt handler pops general registers (off the kernel stack of user task)
-> IRET pops EIP, CS, EFLAGS, ESP SS
-> Returns into the userspace task
Code: Select all
Userspace task running
-> System call is fired
-> CPU pushes SS, ESP, EFLAGS, CS, EIP (to kernel stack of user task)
-> Enters interrupt handler
--> CLI so we don't get interrupted
--> Push general registers (to kernel stack of user task)
--> Store register state in task structure
--> Now STI again?
---> System call is processed
---> We now get interrupted by timer interrupt
---> ???
Best greets