Why Linux Kernel Use Trap Gate to Handle Divide_Error Exception

Why it throws Floating Point Exception if I divide a floating number by zero?

Dividing by 0 does not necessarily result in infinity. There's a good numberphile video that goes into this.

More importantly here, the IEEE 754 floating point standard (which is what most languages/cpus use) dictates that dividing by 0 should result in NaN, and many programming languages just turn this into an error.

This is not linux specific. I don't even think Linux itself can raise something called an exception, so this must be a higher-level language thing.

When to use Interrupt Gate or Trap Gate?

You have to program the CPU as to what is an interrupt gate and what is a trap gate for a given ISR.

This is set by bit 40-43 in an IDT entry. Info here: http://wiki.osdev.org/Interrupt_Descriptor_Table

task gate, interrupt gate, call gate

Everything you might want to know about interrupts and gates is in the Intel developer manual, volume 3. In short:

  • Task gates were originally designed as a CPU-mediated method of performing task switching; the CPU can automatically record the state of the process during the task switching operation. These are not typically used in modern operating systems; the OS usually does the state-saving operations on its own.
  • At least in Linux, all interrupt handlers are in kernel space and execute at ring 0. If you want to handle a divide-by-zero exception, you register a userspace signal handler for SIGFPE; the kernel-space interrupt handler raises the SIGFPE signal, indirectly triggering the userspace handler code (the userspace code is executed after returning from the interrupt handler).

How does the user to kernel mode switch occur before the Interrupt Gate descriptor is accessed?

When an hardware interrupt happens, the privilege level of the currently executing code can be ignored; the CPU can simply switch to the interrupt's privilege level without checking it.

The Intel 64 and IA-32 Architectures Software Developer’s Manual Volume 3A: System Programming Guide, Part 1 says in section 6.12.1.1:

Protection of Exception- and Interrupt-Handler Procedures

The privilege-level protection for exception- and interrupt-handler procedures is similar to that used for ordinary
procedure calls when called through a call gate (see Section 5.8.4, “Accessing a Code Segment Through a Call
Gate”). The processor does not permit transfer of execution to an exception- or interrupt-handler procedure in a
less privileged code segment (numerically greater privilege level) than the CPL.

An attempt to violate this rule results in a general-protection exception (#GP). The protection mechanism for
exception- and interrupt-handler procedures is different in the following ways:

  • Because interrupt and exception vectors have no RPL, the RPL is not checked on implicit calls to exception and
    interrupt handlers.
  • The processor checks the DPL of the interrupt or trap gate only if an exception or interrupt is generated with an
    INT n, INT 3, or INTO instruction. Here, the CPL must be less than or equal to the DPL of the gate. This
    restriction prevents application programs or procedures running at privilege level 3 from using a software
    interrupt to access critical exception handlers, such as the page-fault handler, providing that those handlers are
    placed in more privileged code segments (numerically lower privilege level). For hardware-generated
    interrupts and processor-detected exceptions, the processor ignores the DPL of interrupt and trap gates.

Because exceptions and interrupts generally do not occur at predictable times, these privilege rules effectively
impose restrictions on the privilege levels at which exception and interrupt- handling procedures can run. Either of
the following techniques can be used to avoid privilege-level violations.

  • The exception or interrupt handler can be placed in a conforming code segment. This technique can be used for
    handlers that only need to access data available on the stack (for example, divide error exceptions). If the
    handler needs data from a data segment, the data segment needs to be accessible from privilege level 3, which
    would make it unprotected.
  • The handler can be placed in a nonconforming code segment with privilege level 0. This handler would always
    run, regardless of the CPL that the interrupted program or task is running at.


Related Topics



Leave a reply



Submit