The difference between Call Gate, Interrupt Gate, Trap Gate?

smwikipedia picture smwikipedia · Aug 6, 2010 · Viewed 20.6k times · Source

I am studying Intel Protected Mode. I found that Call Gate, Interrupt Gate, Trap Gate are almost the same. In fact, besides that Call Gate has the fields for parameter counter, and that these 3 gates have different type fields, they are identical in all other fields.

As to their functions, they are all used to transfer code control into some procedure within some code segment.

I am wondering, since these 3 gates all contain the information needed for the call across privilege boundaries. Why do we need 3 kinds of them? Isn't 1 just good enough?

Thanks for your time and response.

Update 1

A related question: When to use Interrupt Gate or Trap Gate?

Update 2

Today I came up with this thought:

Different purpose, different gates, and with different CPU behavior details carried out. Such as IF flag handling.

Answer

Michael Foukarakis picture Michael Foukarakis · Aug 6, 2010

A gate (call, interrupt, task or trap) is used to transfer control of execution across segments. Privilege level checking is done differently depending on the type of destination and instruction used.

A call gate uses the CALL and JMP instructions. Call gates transfer control from lower privilege code to higher privilege code. The gate DPL is used to determine what privilege levels have access to the gate. Call gates are (or have been, probably) gradually abandoned in favour of the SYSENTER/SYSEXIT mechanism, which is faster.

Task gates are used for hardware multitasking support. A hardware task switch can occur voluntarily (CALL/JMP to a task gate descriptor), or through an interrupt or an IRET when the NT flag is set. It works the same way with interrupt or trap gates. Task gates are not used, to the best of my knowledge, as kernels usually want extra work done when task switching.

Interrupt & trap gates, together with task gates, are known as the Interrupt Descriptor Table. They work the same as call gates, except the transfer of parameters, from one privilege stack to another. One difference is that interrupt gates clear the IF bit in EFLAGS, while trap gates do not. This makes them ideal for serving hardware interrupts. Traps are widely used in hardware-assisted virtualization.

For more information, see the Intel Architecture Manuals on the processors that interest you.

Update

To answer the comment:

There are many reasons to distinguish interrupts from traps. One is the difference in scope: interrupt gates point to kernel space (after all, it's the kernel who manages the hardware) while traps are called in userspace. Interrupt handlers are called in response to hardware events, while traps are executed in response to an CPU instruction.

For a simple (but impractical) example to better understand why interrupt and trap gates treat EFLAGS differently, consider what would happen in case we were writing an interrupt handler for hardware events on a uniprocessor system and we couldn't clear the IF bit while we were serving one. It would be possible for a second interrupt to arrive while we were busy serving the first. Then our interrupt handler would be called by the processor at some random point during our IH execution. This could lead to data corruption, deadlocking, or other bad magic. Practically, interrupt disabling is one of the mechanisms to ensure that a series of kernel statements is treated like a critical section.

The above example is assuming maskable interrupts, though. You wouldn't want to ignore NMIs, anyway.

It's largely irrelevant today, too. Today there's practically no distinction between fast and slow interrupt handlers (search for "Fast and Slow Handlers"), interrupt handlers can execute in nested fashion, SMP processors make it mandatory to couple local interrupt disabling with spin locks, and so forth.

Now, trap gates are indeed used to service software interrupts, exceptions, etc. A page fault or division by zero exception in your processor is probably handled through a trap gate. The simplest example of using trap gates to control program execution is the INT 3 instruction, which is used to implement breakpoints in debuggers. When doing virtualization, what happens is that the hypervisor runs in ring 0, and the guest kernel usually in ring 1 - where privileged code would fail with general exception fault. Witchel and Rosenblum developed binary translation, which is basically rewriting instructions to simulate their effects. Critical instructions are discovered and replaced with traps. Then when the trap executes, control is yielded to the VMM/hypervisor, which is responsible for emulating the critical instructions in ring 0.

With hardware-assisted virtualization, the trap-and-emulate technique has been somewhat limited in its use (since it's quite expensive, especially when it's dynamic) but the practice of binary translation is still widely used.

For more information, I'd suggest you check out:

  • Linux Device Drivers, Third Edition (available online)
  • For binary translation, QEMU is an excellent start.
  • Regarding trap-and-emulate, check out a comparison between software/hardware techniques.

Hope this helps!