Page 1 of 2
TSS and SS0, ESP0....
Posted: Tue May 24, 2011 3:59 am
by iocoder
Hi guys...
One advantage of TSS is that it has entries for SS0 [SS for PL0] and ESP0 [ESP for PL0]. this helps me a lot when a ring3 program has a ring 3 to 0 switch. for example, when the ring 3 program do "int $0x80" [syscall], the CPU will change the value in SS to SS0 and ESP to ESP0 automatically, and pushes old SS and old ESP on the new kernel-mode stack....
Quafios [my OS] has been using soft-ware switch for a while and it works well, but i would like to make use of the feature SS0 and ESP0 without moving to hard-ware switch... is there a good idea to do it???? it is necessary because the stack of a ring 3 process is dynamically growing on. when the program needs more, a page fault happens and the CPU pushes values onto the stack that -in fact- needs to grow, then another page fault happens and so on......
If TSS was enabled, and a page fault happened, the CPU would automatically change SS and ESP and push what he wants to push onto the new stack... how flexible!!! any ideas??????
Thanks and Regards,
Re: TSS and SS0, ESP0....
Posted: Tue May 24, 2011 4:45 am
by bluemoon
On IA32 / IA64 manual, section 5.8.5:
IA manual wrote:5.8.5 Stack Switching
Whenever a call gate is used to transfer program control to a more privileged nonconforming code segment (that is, when the DPL of the nonconforming destination code segment is less than the CPL), the processor automatically switches to the stack for the destination code segment’s privilege level. This stack switching is carried out to prevent more privileged procedures from crashing due to insufficient stack space. It also prevents less privileged procedures from interfering (by accident or intent) with more privileged procedures through a shared stack.
Each task must define up to 4 stacks....<snip>...The operating system is responsible for creating stacks and stack-segment descriptors for all the privilege levels to be used and for loading initial pointers for these stacks into the TSS
This is why you need at least one TSS if you ever want to get from ring3 to ring0.
it is necessary because the stack of a ring 3 process is dynamically growing on. when the program needs more, a page fault happens and the CPU pushes values onto the stack that -in fact- needs to grow, then another page fault happens and so on......
This is not going to happen since you have (and require) an TSS for stack switch from 3 to 0.
Re: TSS and SS0, ESP0....
Posted: Tue May 24, 2011 4:48 am
by iocoder
thanks a lot, but by loading TR, hardware context switching is enabled, isn't it???
Re: TSS and SS0, ESP0....
Posted: Tue May 24, 2011 4:53 am
by bluemoon
By loading TR (ie. LTR instruction) itself does not trigger any context switch.
But context switch (going thru' about 12 bullet points of checking and loading) is unavoidable when requesting more more privilege, it is slow but it's a protection measure.
If you don't need such protection you may just run all stuff with same privilege.
ps. The so called "hardware context switch" is always enabled. If you try to get from rin3 to ring0 without a task (previously LTR'ed) you get an CPU exception.
Re: TSS and SS0, ESP0....
Posted: Tue May 24, 2011 5:08 am
by egos
Hi, mostafazizo.
For handling critical errors such as kernel stack page fault you should use additional TSS(s) in IA-32.
Re: TSS and SS0, ESP0....
Posted: Tue May 24, 2011 5:13 am
by iocoder
By loading TR (ie. LTR instruction) itself does not trigger any context switch.
But context switch (going thru' about 12 bullet points of checking and loading) is unavoidable when requesting more more privilege, it is slow but it's a protection measure.
If you don't need such protection you may just run all stuff with same privilege.
ps. The so called "hardware context switch" is always enabled. If you try to get from rin3 to ring0 without a task (previously LTR'ed) you get an CPU exception.
Hi, mostafazizo.
For critical errors such as kernel stack page fault you should use additional TSS(s) in IA-32.
thanks guys...
now i believe i have to use at least one TSS... using TSS and loading it to TR will not activate hardware context switching, will it??? to say we are using hardware context switching, we have to do a far jump to TSS selector for each task-switch.. and this is the slow part that modern operating systems don't use... is that right??
Re: TSS and SS0, ESP0....
Posted: Tue May 24, 2011 5:23 am
by bluemoon
mostafazizo wrote:and this is the slow part that modern operating systems don't use... is that right??
The whole point is avoid context switch if it is not necessary. for example, scheduling between process group which involve no privilege change. However, to get higher privilege it by definition involve a context switch, even for modern OS.
Re: TSS and SS0, ESP0....
Posted: Tue May 24, 2011 9:14 am
by xenos
bluemoon wrote:However, to get higher privilege it by definition involve a context switch, even for modern OS.
No, that's wrong.
Going from ring 3 to ring 0 (through an interrupt or call gate) triggers a
stack switch: The new values of SS and ESP are loaded from the SS0 and ESP0 fields of the current TSS. However, this is not a hardware
context switch, which would be saving all registers into the current TSS, switching to a new TSS and loading all registers from the new TSS, as caused by a jmp / call to a new TSS.
If you want to have ring 3 code (which you certainly want, since any code running in ring 0 can do anything it wants with the system), you need at least one TSS (one TSS per CPU in multiprocessor systems), which will hold the SS0 / ESP0 for the current task. But you don't need to use hardware task switching. For example, you could do the following to implement a simple software task switching (assuming you do a task switch when the timer IRQ fires):
- The timer IRQ fires and its IDT entry points to a ring 0 interrupt handler.
- SS and ESP are loaded from the SS0 and ESP0 fields of the current TSS; the old values are pushed on the ring 0 stack (stack switch).
- Push all registers on the ring 0 stack. Save a copy of CR3 (if you use paging).
- Call the scheduler, put the current task in the task queue and get a new task to execute.
- Change the values of SS and ESP to point to the new task's ring 0 stack.
- Load all register values (including CR3) from the ring 0 stack of the new task.
- Do an IRET. This will save SS and ESP in the current (new) task's TSS and get you back to ring 3 - of the new task.
Re: TSS and SS0, ESP0....
Posted: Tue May 24, 2011 9:32 am
by bluemoon
Oh I mixed up the terms on context switch and stack switch, thanks for clarification. Hope I'm not confusing the OP.
By the way I guess you mean CR3(pointer to page directory).
Re: TSS and SS0, ESP0....
Posted: Tue May 24, 2011 9:53 am
by xenos
bluemoon wrote:By the way I guess you mean CR3(pointer to page directory).
Of course, you're right... Thanks for the hint.
Re: TSS and SS0, ESP0....
Posted: Tue May 24, 2011 1:04 pm
by rdos
I find it awkward to save task state on the stack. Mostly because different processor-modes have different stack-layouts. For instance, a V86 task would save segment registers on the top of the stack. An protected mode application would save SS:ESP on top of the stack. For a kernel-debugger, it is also pretty handy if tasks blocked on exceptions have an memory area with registers that is easy to get to, which a stack frame is not, especially not with different processor-modes being involved. I therefore find it more convinient to actually store task state in the thread-control-block instead of on the stack. And exception-handlers would pop-of the exception handler frames from the stack, and reload the state so the thread points to the faulting instruction, and not code in an exception handler.
Re: TSS and SS0, ESP0....
Posted: Tue May 24, 2011 1:14 pm
by rdos
mostafazizo wrote:now i believe i have to use at least one TSS... using TSS and loading it to TR will not activate hardware context switching, will it??? to say we are using hardware context switching, we have to do a far jump to TSS selector for each task-switch.. and this is the slow part that modern operating systems don't use... is that right??
Pretty much, yes. Loading TR is similar to loading a segment register. It does do a few validations, and it sets the TSS to busy, but it doesn't save/load register-state in the TSS.
The reason I use one TSS per thread has to do with IO-permission bitmap. I have tasks that should have no IO-port restrictions, even if they run at ring 3 (the V86 video-mode switcher), and tasks that should be restricted. It is non-trivial to solve this issue with only one TSS per processor. The other issues (setting the correct SS0:ESP0 and possibly CR3) with every task-switch is not a problem really.
Re: TSS and SS0, ESP0....
Posted: Tue May 24, 2011 4:31 pm
by iocoder
thank u guys u r so helpful
Re: TSS and SS0, ESP0....
Posted: Tue May 24, 2011 4:45 pm
by Combuster
rdos wrote:It is non-trivial to solve this issue with only one TSS per processor.
Paging works pretty good - you can even have TSSes share bitmaps for free that way. Plus that true threads have the same privileges so in your case you'd have N identical copies of the same bitmap, no?
Re: TSS and SS0, ESP0....
Posted: Wed May 25, 2011 7:14 am
by xenos
rdos wrote:I find it awkward to save task state on the stack. Mostly because different processor-modes have different stack-layouts.
Of course, one can also save the register information in a thread control block. As I said, saving them on the stack is only a simple example.
Combuster wrote:rdos wrote:It is non-trivial to solve this issue with only one TSS per processor.
Paging works pretty good - you can even have TSSes share bitmaps for free that way. Plus that true threads have the same privileges so in your case you'd have N identical copies of the same bitmap, no?
That's indeed very simple, and it's the way I handler IO bitmaps in my kernel. I have one TSS per CPU and one page directory per process (which may contain several threads). IO permissions are granted per process. Thus, every process has its own IO bitmap, which is mapped (via the process' page directory) at the end of the TSS area.