Page 1 of 1

About Task Switch and TSS

Posted: Wed Jan 08, 2014 9:40 pm
by watermirror
Hi,
Could any one told me what's the difference between the Source of task switch initiation:

CALL instruction
IRET instruction
JMP instruction
Task gate in IDT

I am very confused about these.

Re: About Task Switch and TSS

Posted: Wed Jan 08, 2014 11:41 pm
by Brendan
Hi,
watermirror wrote:Could any one told me what's the difference between the Source of task switch initiation:
CALL instruction: Leaves previous task's "busy bit" set, and also sets destination task's "busy bit". I think it also sets the destination task's "back link" field (as a way of remembering which task to "RETF" to) but can't quite remember.

IRET instruction: Expects current task's "busy bit" to be set and clears it (similar to RETF). Sets destination task's "busy bit".

JMP instruction: Clear's previous task's "busy bit" and sets destination task's busy bit.

Task gate in IDT: Says which "TSS descriptor" (in the GDT) to use for the task switch
watermirror wrote:I am very confused about these.
The difference between different types of task switching is mostly how it effects the "busy bit" for both tasks. In general, for hardware task switching between processes/threads you should never need to use anything except "JMP". For using hardware task switching to ensure that exception handlers are started with a secure state (e.g. possibly for double fault and NMI, even if the OS uses software task switching) there's no choice - you have to have a TSS somewhere, a "TSS descriptor" in the GDT that says where the TSS is, plus a "task gate" in the IDT so the CPU knows its not a normal interrupt/trap gate.

Of course I don't actually use any of this. It's better/faster/easier to use software task switching for switching between processes/threads; and (at least for micro-kernels) easier to make sure exception handlers don't crash (and avoid the need to bother with double fault exception handlers completely). ;)

Also note that because tasks are not re-entrant (any attempt to switch to a task that has its "busy bit" set results in a general protection fault); it's extremely difficult to use hardware task switching in a multi-CPU scenario. For a simple example, if you have a task gate for the double fault exception handler, then you'll need a different TSS (and different "TSS descriptor") for each CPU, just in case 2 or more CPUs happens to trigger a double fault at the same time (otherwise, the first CPU to use that task sets the task's "busy bit" and the second CPU gets a general protection fault while attempting to start the double fault handler, which results in a triple fault/reset).


Cheers,

Brendan

Re: About Task Switch and TSS

Posted: Thu Jan 09, 2014 2:49 pm
by devsau
Figured I would just ask this here since we are on the topic.

If I were to use a task gate for something that always needs to have a known good stack (like IST mechanism in long mode) like NMI, the old cs/eip/ss/esp is not pushed onto the stack obtained from the new TSS if it's using the task gate mechanism correct?

If I wanted that, I would need to use the back-link selector (assuming int got us here) and read it out manually correct?

Re: About Task Switch and TSS

Posted: Thu Jan 09, 2014 7:02 pm
by Brendan
Hi,
devsau wrote:If I were to use a task gate for something that always needs to have a known good stack (like IST mechanism in long mode) like NMI, the old cs/eip/ss/esp is not pushed onto the stack obtained from the new TSS if it's using the task gate mechanism correct?
Correct. The only thing the CPU pushes on the stack is the exception's error code (but only if the exception has one - NMI doesn't).
devsau wrote:If I wanted that, I would need to use the back-link selector (assuming int got us here) and read it out manually correct?
Yes - use your NMI handler task's backlink to find the previous task's TSS descriptor in the GDT, then use that to find the previous task's TSS.

Of course (due to interactions between NMI and SMI/SMM) there's no way to prevent a second NMI from interrupting while you're handling a previous NMI, and hardware tasks aren't re-entrant, so it's extremely difficult to use a task gate for NMI 100% safely (even for single-CPU).


Cheers,

Brendan

Re: About Task Switch and TSS

Posted: Fri Jan 10, 2014 3:10 pm
by devsau
Brendan wrote:Hi,
devsau wrote:If I were to use a task gate for something that always needs to have a known good stack (like IST mechanism in long mode) like NMI, the old cs/eip/ss/esp is not pushed onto the stack obtained from the new TSS if it's using the task gate mechanism correct?
Correct. The only thing the CPU pushes on the stack is the exception's error code (but only if the exception has one - NMI doesn't).
devsau wrote:If I wanted that, I would need to use the back-link selector (assuming int got us here) and read it out manually correct?
Yes - use your NMI handler task's backlink to find the previous task's TSS descriptor in the GDT, then use that to find the previous task's TSS.

Of course (due to interactions between NMI and SMI/SMM) there's no way to prevent a second NMI from interrupting while you're handling a previous NMI, and hardware tasks aren't re-entrant, so it's extremely difficult to use a task gate for NMI 100% safely (even for single-CPU).


Cheers,

Brendan

thank you again.