bewing wrote:
A ring0 app will store EFLAGS/CS/EIP on its own stack. This is very nice.
If I only have one ring0 stack, then an interrupted ring3 app will store SS/ESP/EFLAGS/CS/EIP on the ring0 system stack! Isn't that correct? This is totally unacceptable -- I may not be returning to ring 3. I need that "state" info stored somewhere with the task -- preferably in the task's own memory space. So I have to remove it from the ring0 system stack, right? So I'm back with trying to determine whether I interrupted from CPL0 or 3.
*If* you only have one ring0 stack, of course, that changes the design completely. You should of course differentiate whether a ring0 or a ring3 task was interrupted, but that shouldn't be the problem as the interrupted task's CS-value is pushed onto the stack during an interrupt.
bewing wrote:
Quote:
use a seperate stack in kernel space for each userspace thread
OK, now I'm seeing what you meant by this -- so every single userspace thread that gets spawned allocates both a new stack in userspace AND a new stack in physical kernelspace? Gawd, that's horrifying. I don't want to waste that quantity of memory in kernelspace just to handle interrupts from every possible running thread in userspace.
You got it right, yes. But as I said, that's the way most multitasking systems do it. You need some place in kernel space to store a ring3 task's saved state, just for security reasons (otherwise ring3 code could for example change it's own privilege level...) Typically the ring0 stack is kept small to not exhaust kernel address space, Linux for example uses 4K per kernel stack. If you design a microkernel system (and you don't have much systemcall-code to execute in a thread's context) you could make the kernel stack even smaller, of course.
cheers
Joe