0
\$\begingroup\$

The INTEL manuals tell us that when a HW-task has been switched to using a 'CALL' instruction the destination task is considered a nested task:

The processor

  • copies the segment selector for the current TSS ( task A ) to the previous task link field of the TSS for the destination task ( task B's TSS )

  • sets the EFLAGS.NT = 1

                      task A  task B
    
                        v      .
                        .    / v 
                        v   /  .
                        .  /   v  
                        v /    .
                        ./     v
                   CALL        .
                        .\     v 
                        v \    . 
                        .  \   v 
                        v   \  .
                        .     IRET         
                        v 
    

The 'nested task' should eventually return to the calling task ( task A ) by means of an IRET instruction. When software in task B uses an IRET instruction return, the processor checks for EFLAGS.NT = 1, it then uses the value in the previous task link field to return to the previous task ( task A ) if the flag is set.

However nothing is to stop an interrupt occuring while execution is in progress in task B.

Now when the handler tries to return to the interrupted thread in task B, it would do this with an IRET. Since the handler is executing within task B, it would seem that the processor checks the EFLAGS.NT and since it will still be set ( i.e. 1 ) returns to task A, rather than returning to the next instruction of the interrupted thread within task B.

                      WHAT HAPPENS WHEN:


                      task A  task B

                        v      .
                        .    / v 
                        v   /  .   /.
                        .  /   v  / v
                        v /    . /  .
                        ./     v/ interrupt handler  
               CALL            .    v
                        .           .
                        v           v
                        .          IRET
                        v          EFLAGS.NT = 1  
                        .              Get the previous task link in B's TSS?      
                        v          OR    
                                       Go to the return address on the stack?

I would expect the following behaviour

                      task A  task B

                        v      .
                        .    / v 
                        v   /  .   /.
                        .  /   v  / v
                        v /    . /  .
                        ./     v/ interrupt handler  
               CALL            .    v
                        .\     v \  .
                        v \    .  \ v
                        .  \   v   IRET
                        v   \  .
                        .     IRET         
                        v 

In other words first a return is made from the interrupt which occured during task B ( consumes 1st IRET ) then a return is made to the 'calling' task ( task A ) which uses a 2nd IRET.

Would this be reasonable?

If so how does the processor 'know' that eventhough EFLAGS.NT=1, it must return to the interrupted thread in task B itself; or in other words it is dealing with a simple interrupt return in within task B and that it should not return to task A ?

What am I missing here?

\$\endgroup\$

2 Answers 2

1
\$\begingroup\$

Have a look at the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 3:

6.12.1.2 Flag Usage By Exception- or Interrupt-Handler Procedure

When accessing an exception or interrupt handler through either an interrupt gate or a trap gate, the processor clears the TF flag in the EFLAGS register after it saves the contents of the EFLAGS register on the stack. (On calls to exception and interrupt handlers, the processor also clears the VM, RF, and NT flags in the EFLAGS register, after they are saved on the stack.) Clearing the TF flag prevents instruction tracing from affecting interrupt response. A subsequent IRET instruction restores the TF (and VM, RF, and NT) flags to the values in the saved contents of the EFLAGS register on the stack.

An exception entry will save an exception stack frame (including current EFLAGS), and then tweak the (new) EFLAGS to ensure correct and safe execution of the exception handler.

\$\endgroup\$
1
  • \$\begingroup\$ Your feedback is greatly appreciated! I was suspecting that something had to be done to the NT flag while preparing to service an interrupt. Clearing the NT flag prior to entering the handler is what forces IRET to o a 'normal' return. When the IRET restores the EFLAGS to its previous state ( NT=1 ) the CPU will find its way back to the parent task on encountering a subsequent IRET outside an interrupt. \$\endgroup\$
    – darbehdar
    Jun 9, 2015 at 11:22
0
\$\begingroup\$

For the benefit of others:

As pointed out by the answer above, the CPU does return to task B as expected, since the NT flag is cleared prior to entering the handler.

This is what forces an IRET to a 'normal' return ( i.e. back to task B ). When the IRET restores the EFLAGS to its previous state ( which would have been NT=1 ) it is assured that the CPU will find its way back to the parent task on encountering the subsequent IRET ( this time outside an interrupt ).

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.