x86_64 Trap and Exception Handling

Relevant source files

This document covers the x86_64-specific trap and exception handling implementation in the axcpu library. It focuses on how hardware exceptions, interrupts, and system calls are processed and dispatched to appropriate handlers on the x86_64 architecture.

For broader context management including TrapFrame structure details, see x86_64 Context Management. For system call implementation specifics, see x86_64 System Calls. For cross-architecture trap handling abstractions, see Core Trap Handling Framework.

Exception Dispatch Architecture

The x86_64 trap handling system centers around the x86_trap_handler function, which serves as the main dispatcher for all hardware exceptions and interrupts. This handler examines the trap vector number to determine the appropriate response.

flowchart TD
subgraph subGraph2["Exception Handlers"]
    PAGE_FAULT["handle_page_fault()"]
    BREAKPOINT["Breakpoint Debug"]
    GPF["General Protection Fault Panic"]
    SYSCALL["x86_syscall_handler()"]
    IRQ["IRQ Handler via handle_trap!"]
    UNKNOWN["Unhandled Exception Panic"]
end
subgraph subGraph1["Main Dispatch Logic"]
    TRAP_HANDLER["x86_trap_handler()"]
    VECTOR_MATCH["Match tf.vector"]
end
subgraph subGraph0["Hardware Exception Entry"]
    HW_TRAP["Hardware Exception/Interrupt"]
    ASM_ENTRY["trap.S Assembly Entry Point"]
    SAVE_CONTEXT["Save CPU State to TrapFrame"]
end

ASM_ENTRY --> SAVE_CONTEXT
HW_TRAP --> ASM_ENTRY
SAVE_CONTEXT --> TRAP_HANDLER
TRAP_HANDLER --> VECTOR_MATCH
VECTOR_MATCH --> BREAKPOINT
VECTOR_MATCH --> GPF
VECTOR_MATCH --> IRQ
VECTOR_MATCH --> PAGE_FAULT
VECTOR_MATCH --> SYSCALL
VECTOR_MATCH --> UNKNOWN

The dispatch mechanism uses a simple match statement on the trap vector stored in the TrapFrame. Each vector corresponds to a specific x86_64 exception or interrupt type defined by the hardware architecture.

Sources: src/x86_64/trap.rs(L33 - L59) 

Vector Classification and Constants

The trap handler categorizes exceptions and interrupts using predefined vector constants that correspond to x86_64 architectural definitions:

Vector TypeRange/ValuePurpose
PAGE_FAULT_VECTOR14Memory access violations
BREAKPOINT_VECTOR3Debug breakpoints
GENERAL_PROTECTION_FAULT_VECTOR13Protection violations
LEGACY_SYSCALL_VECTOR0x80System calls (int 0x80)
IRQ_VECTOR_STARTtoIRQ_VECTOR_END0x20-0xFFHardware interrupts

Sources: src/x86_64/trap.rs(L10 - L13)  src/x86_64/trap.rs(L34 - L47) 

Page Fault Handling

Page fault processing involves extracting the fault address from the CR2 control register and converting the hardware error code into portable flags for the broader trap handling framework.

flowchart TD
subgraph subGraph3["Dispatch Decision"]
    HANDLE_TRAP["handle_trap!(PAGE_FAULT, ...)"]
    SUCCESS["Handler processes fault"]
    PANIC["Unhandled page fault panic"]
end
subgraph subGraph2["Flag Mapping"]
    WRITE_FLAG["PageFaultFlags::WRITE"]
    READ_FLAG["PageFaultFlags::READ"]
    USER_FLAG["PageFaultFlags::USER"]
    EXEC_FLAG["PageFaultFlags::EXECUTE"]
end
subgraph subGraph1["Error Code Analysis"]
    WRITE_BIT["CAUSED_BY_WRITE bit"]
    USER_BIT["USER_MODE bit"]
    EXEC_BIT["INSTRUCTION_FETCH bit"]
    RESERVED_CHECK["Check reserved bits"]
end
subgraph subGraph0["Page Fault Processing"]
    PF_ENTRY["handle_page_fault(tf)"]
    ERR_CONVERT["err_code_to_flags(tf.error_code)"]
    CR2_READ["Read fault address from CR2"]
    FLAG_CHECK["Convert to PageFaultFlags"]
end
read_FLAG["read_FLAG"]

CR2_READ --> HANDLE_TRAP
ERR_CONVERT --> FLAG_CHECK
EXEC_BIT --> EXEC_FLAG
EXEC_FLAG --> HANDLE_TRAP
FLAG_CHECK --> EXEC_BIT
FLAG_CHECK --> RESERVED_CHECK
FLAG_CHECK --> USER_BIT
FLAG_CHECK --> WRITE_BIT
HANDLE_TRAP --> PANIC
HANDLE_TRAP --> SUCCESS
PF_ENTRY --> CR2_READ
PF_ENTRY --> ERR_CONVERT
USER_BIT --> USER_FLAG
USER_FLAG --> HANDLE_TRAP
WRITE_BIT --> READ_FLAG
WRITE_BIT --> WRITE_FLAG
WRITE_FLAG --> HANDLE_TRAP
read_FLAG --> HANDLE_TRAP

The err_code_to_flags function translates x86_64 page fault error codes into architecture-neutral PageFaultFlags. This abstraction allows the same page fault logic to work across different architectures.

Sources: src/x86_64/trap.rs(L15 - L30)  src/x86_64/trap.rs(L69 - L92) 

Interrupt Request (IRQ) Handling

Hardware interrupts occupy vector numbers 0x20 through 0xFF and are handled through the unified trap framework. The handler identifies IRQ vectors and delegates processing to registered handlers.

flowchart TD
subgraph subGraph1["IRQ Vector Space"]
    VEC_20["0x20: Timer"]
    VEC_21["0x21: Keyboard"]
    VEC_22["0x22: Cascade"]
    VEC_DOTS["..."]
    VEC_FF["0xFF: Spurious"]
end
subgraph subGraph0["IRQ Processing Flow"]
    IRQ_DETECT["Vector in IRQ_VECTOR_START..=IRQ_VECTOR_END"]
    IRQ_EXTRACT["Extract IRQ number from tf.vector"]
    HANDLE_TRAP_IRQ["handle_trap!(IRQ, tf.vector as _)"]
end

IRQ_DETECT --> IRQ_EXTRACT
IRQ_EXTRACT --> HANDLE_TRAP_IRQ
VEC_DOTS --> IRQ_DETECT
VEC_FF --> IRQ_DETECT

The IRQ handling delegates to the cross-architecture trap framework using the handle_trap! macro, which allows different system components to register interrupt handlers.

Sources: src/x86_64/trap.rs(L45 - L47) 

Assembly Integration

The trap handling system integrates with assembly code through the trap.S file, which contains the low-level exception entry points and state saving routines.


The assembly code is included at compile time and provides the hardware-level interface between x86_64 exception mechanisms and the Rust handler functions.

Sources: src/x86_64/trap.rs(L7) 

System Call Integration

When the uspace feature is enabled, the trap handler supports legacy system calls via the int 0x80 instruction. This provides compatibility with traditional Unix system call interfaces.


System call handling is feature-gated and delegates to the dedicated system call module for processing.

Sources: src/x86_64/trap.rs(L9 - L10)  src/x86_64/trap.rs(L44) 

Error Handling and Diagnostics

The trap handler implements comprehensive error reporting for unhandled exceptions and invalid page faults. Critical errors result in detailed panic messages that include register state and fault information.

Unhandled Exception Reporting

For unknown or unsupported exception vectors, the handler provides detailed diagnostic information including vector number, mnemonic name, error code, and complete register state dump.

Page Fault Error Reporting

Page fault panics include comprehensive fault analysis showing whether the fault occurred in user or kernel mode, the faulting instruction address, the virtual address that caused the fault, and the decoded access flags.

Sources: src/x86_64/trap.rs(L20 - L29)  src/x86_64/trap.rs(L48 - L57)  src/x86_64/trap.rs(L61 - L67) 

Integration with Cross-Architecture Framework

The x86_64 trap handler integrates with the broader axcpu trap handling framework through the handle_trap! macro and standardized flag types like PageFaultFlags. This design allows architecture-specific trap handling while maintaining consistent interfaces for higher-level system components.

Sources: src/x86_64/trap.rs(L5)  src/x86_64/trap.rs(L19)  src/x86_64/trap.rs(L46)