Page 1 of 1

Hardware task switching questions

Posted: Mon Jan 01, 2007 2:38 pm
by ManOfSteel
Hello,

When using hardware task switching, is it absolutely necessary to use one TSS for every process?

What are SS0:ESP0, SS1:ESP1 and SS2:ESP2 exactly? Are they related to different segment protection privilege levels (AKA rings)? In that case, why is there three of them for four privilege levels?

Should the AVL bit be set in TSS descriptors?

Should the busy bit be messed with? When?

I read in the Intel manual:
Interrupts and exceptions can be handled with a task switch to a handler task.
Normally, an interrupt is done by calling the interrupt gate with "int" + "interrupt_gate_descriptor_number". So how would an interrupt be handled with a task switch? Would it be done by calling (with call or jmp) the TSS gate that points to the actual interrupt handler or with "int + TSS gate number"?
Also, how should it be done when called from user mode ring 3 (CPL/DPL/RPL)?
When the G flag is 0 in a TSS descriptor for a 32-bit TSS, the limit field must have a value equal to or greater than 67H, one byte less than the minimum size of a TSS. Attempting to switch to a task whose TSS descriptor has a limit less than 67H generates an invalid-TSS exception (#TS). A larger limit is required if an I/O permission bit map is included in the TSS. An even larger limit would be required if the operating system stores additional data in the TSS.
What kind of additional data are they talking about? Are they talking about things like process name, priority, niceness, etc. Does the CPU actually take care of saving and restoring all this additional data on every task switch?

Thank you in advance.

Re: Hardware task switching questions

Posted: Mon Jan 01, 2007 3:11 pm
by Brendan
Hi,
ManOfSteel wrote:When using hardware task switching, is it absolutely necessary to use one TSS for every process?
No.

IIRC you can use one TSS for the destination of a task switch (where the CPU loads new CPU state from) while the CPU *should* save the previous task's state to where the CPU's hidden parts of TR point.

For reliability I'd use at least 2 TSS's though, as I'm not sure if all CPUs cache the current TSS's details (base and limit) in hidden parts of TR (or if some early CPUs reload the data from the GDT).
ManOfSteel wrote:What are SS0:ESP0, SS1:ESP1 and SS2:ESP2 exactly? Are they related to different segment protection privilege levels (AKA rings)? In that case, why is there three of them for four privilege levels?
They are used for switching stacks when the CPU changes from a lower privilege level (e.g. CPL=3) to a higher privilege level (e.g. CPL=0). There's only 3 of them because there are no privilege levels lower than CPL=3, so "SS3:ESP3" is never needed.
ManOfSteel wrote:Should the AVL bit be set in TSS descriptors?
The AVL bit is "available for use by system software". The CPU ignores it, and you can use it for anything you like.
ManOfSteel wrote:Should the busy bit be messed with? When?
IMHO the busy bit shouldn't need to be messed with, and if you think you need to mess with it you're probably using a "call far" where you should be using a "jmp far" (or a task gate where you should be using an interrupt or trap gate).
ManOfSteel wrote:I read in the Intel manual:
Interrupts and exceptions can be handled with a task switch to a handler task.
Normally, an interrupt is done by calling the interrupt gate with "int" + "interrupt_gate_descriptor_number". So how would an interrupt be handled with a task switch? Would it be done by calling (with call or jmp) the TSS gate that points to the actual interrupt handler or with "int + TSS gate number"?
Also, how should it be done when called from user mode ring 3 (CPL/DPL/RPL)?
If you're using tasks as interrupt handlers then the task gate will do a task switch similar to using "call far". In general using tasks for interrupt handlers is a bad idea - it's slow, they aren't re-entrant and it's normally not necessary. I'd only consider using tasks for the NMI, double fault and machine check exceptions (where it may be beneficial, especially if you're worried about trashing the kernel's stack).
ManOfSteel wrote:
When the G flag is 0 in a TSS descriptor for a 32-bit TSS, the limit field must have a value equal to or greater than 67H, one byte less than the minimum size of a TSS. Attempting to switch to a task whose TSS descriptor has a limit less than 67H generates an invalid-TSS exception (#TS). A larger limit is required if an I/O permission bit map is included in the TSS. An even larger limit would be required if the operating system stores additional data in the TSS.
What kind of additional data are they talking about? Are they talking about things like process name, priority, niceness, etc. Does the CPU actually take care of saving and restoring all this additional data on every task switch?
I'm not sure exactly what the manual is talking about, although I remember something about an extension to virtual8086 that uses an array of bits for interrupt redirection in the TSS. AFAIK the CPU will never write to anything above the first 104 bytes of the TSS as part of a task switch.


Cheers,

Brendan

Posted: Mon Jan 01, 2007 3:11 pm
by Ready4Dis
Don't have all your answers, but read this, might clarify a bit for you.

http://www.acm.uiuc.edu/sigops/roll_your_own/5.a.html

Also read this, good reasons not to use hardware task switching

http://neworder.box.sk/newsread.php?newsid=10562


May I ask when you are going with hardware instead of software (unless you are changing privelege levels)

Posted: Tue Jan 02, 2007 6:28 am
by ManOfSteel
Hello,

@Brendan
Thank you very much for all these answers.

@Ready4Dis
The first link seems interesting. I already know the second one. Anyway, thank you.
May I ask when you are going with hardware instead of software (unless you are changing privelege levels)
I don't really understand your question. If you're actually asking why I'm using HTS instead of STS, then I can tell you I may try both and I don't exclude the possibility of using STS some day.

Posted: Tue Jan 02, 2007 6:46 am
by Ready4Dis
Yes, that is what I was asking. Just from everything i've read, software task switching is faster and more easily extendable. The only reason most OS's even use hardware is to switch privelege levels because it's the only way. For hts you will need an entry for each task, and there is a limit on the number of tasks you can have (unless you dynamically update your GDT and move information around while running, which will hurt performance even more!).

Posted: Wed Jan 03, 2007 12:35 am
by Brendan
Hi,
Ready4Dis wrote:The only reason most OS's even use hardware is to switch privelege levels because it's the only way.
Just a minor clarification on terminology... ;)

Using hardware task switching to change privilege levels isn't the same as using the SS0:ESP0 fields (and/or the SS1:ESP1 and SS2:ESP2 fields) in a single TSS to change privilege levels. For software task switching you'd use the latter (including in long mode, where hardware task switching isn't even supported).


Cheers,

Brendan