x86_64 Context Management
Relevant source files
This document covers the x86_64 CPU context management implementation in axcpu, focusing on the core data structures and mechanisms used for task context switching, exception handling, and state preservation. The implementation provides both kernel-level task switching and user space context management capabilities.
For x86_64 trap and exception handling mechanisms, see x86_64 Trap and Exception Handling. For system call implementation details, see x86_64 System Calls.
Core Context Data Structures
The x86_64 context management system uses several key data structures to manage CPU state across different scenarios:
flowchart TD subgraph subGraph2["Hardware Integration"] CPU["x86_64 CPU"] Stack["Kernel Stack"] Registers["CPU Registers"] end subgraph subGraph0["Core Context Types"] TaskContext["TaskContextMain task switching context"] TrapFrame["TrapFrameException/interrupt context"] ContextSwitchFrame["ContextSwitchFrameInternal context switch frame"] ExtendedState["ExtendedStateFP/SIMD state container"] FxsaveArea["FxsaveArea512-byte FXSAVE region"] end ContextSwitchFrame --> Registers ExtendedState --> CPU ExtendedState --> FxsaveArea TaskContext --> ContextSwitchFrame TaskContext --> ExtendedState TaskContext --> Stack TrapFrame --> Registers
Sources: src/x86_64/context.rs(L1 - L291)
TaskContext Structure
The TaskContext
struct represents the complete saved hardware state of a task, containing all necessary information for context switching:
Field | Type | Purpose | Feature Gate |
---|---|---|---|
kstack_top | VirtAddr | Top of kernel stack | Always |
rsp | u64 | Stack pointer after register saves | Always |
fs_base | usize | Thread Local Storage base | Always |
gs_base | usize | User space GS base register | uspace |
ext_state | ExtendedState | FP/SIMD state | fp-simd |
cr3 | PhysAddr | Page table root | uspace |
Sources: src/x86_64/context.rs(L166 - L183)
TrapFrame Structure
The TrapFrame
captures the complete CPU register state when a trap (interrupt or exception) occurs, containing all general-purpose registers plus trap-specific information:
flowchart TD subgraph subGraph1["Syscall Interface"] ARG0["arg0() -> rdi"] ARG1["arg1() -> rsi"] ARG2["arg2() -> rdx"] ARG3["arg3() -> r10"] ARG4["arg4() -> r8"] ARG5["arg5() -> r9"] USER_CHECK["is_user() -> cs & 3 == 3"] end subgraph subGraph0["TrapFrame Layout"] GPR["General Purpose Registersrax, rbx, rcx, rdx, rbp, rsi, rdir8, r9, r10, r11, r12, r13, r14, r15"] TRAP_INFO["Trap Informationvector, error_code"] CPU_PUSHED["CPU-Pushed Fieldsrip, cs, rflags, rsp, ss"] end CPU_PUSHED --> USER_CHECK GPR --> ARG0 GPR --> ARG1 GPR --> ARG2 GPR --> ARG3 GPR --> ARG4 GPR --> ARG5
Sources: src/x86_64/context.rs(L4 - L72)
Context Switching Mechanism
The context switching process involves saving the current task's state and restoring the next task's state through a coordinated sequence of operations:
flowchart TD subgraph subGraph1["Feature Gates"] FP_GATE["fp-simd feature"] TLS_GATE["tls feature"] USPACE_GATE["uspace feature"] end subgraph subGraph0["Context Switch Flow"] START["switch_to() called"] SAVE_FP["Save FP/SIMD stateext_state.save()"] RESTORE_FP["Restore FP/SIMD statenext_ctx.ext_state.restore()"] SAVE_TLS["Save current TLSread_thread_pointer()"] RESTORE_TLS["Restore next TLSwrite_thread_pointer()"] SAVE_GS["Save GS baserdmsr(IA32_KERNEL_GSBASE)"] RESTORE_GS["Restore GS basewrmsr(IA32_KERNEL_GSBASE)"] UPDATE_TSS["Update TSS RSP0write_tss_rsp0()"] SWITCH_PT["Switch page tablewrite_user_page_table()"] ASM_SWITCH["Assembly context switchcontext_switch()"] END["Context switch complete"] end ASM_SWITCH --> END RESTORE_FP --> FP_GATE RESTORE_FP --> SAVE_TLS RESTORE_GS --> UPDATE_TSS RESTORE_GS --> USPACE_GATE RESTORE_TLS --> SAVE_GS RESTORE_TLS --> TLS_GATE SAVE_FP --> FP_GATE SAVE_FP --> RESTORE_FP SAVE_GS --> RESTORE_GS SAVE_GS --> USPACE_GATE SAVE_TLS --> RESTORE_TLS SAVE_TLS --> TLS_GATE START --> SAVE_FP SWITCH_PT --> ASM_SWITCH SWITCH_PT --> USPACE_GATE UPDATE_TSS --> SWITCH_PT UPDATE_TSS --> USPACE_GATE
Sources: src/x86_64/context.rs(L242 - L265)
Assembly Context Switch Implementation
The low-level context switching is implemented in assembly using a naked function that saves and restores callee-saved registers:
flowchart TD subgraph subGraph0["context_switch Assembly"] PUSH["Push callee-saved registersrbp, rbx, r12-r15"] SAVE_RSP["Save current RSPmov [rdi], rsp"] LOAD_RSP["Load next RSPmov rsp, [rsi]"] POP["Pop callee-saved registersr15-r12, rbx, rbp"] RET["Return to new taskret"] end LOAD_RSP --> POP POP --> RET PUSH --> SAVE_RSP SAVE_RSP --> LOAD_RSP
Sources: src/x86_64/context.rs(L268 - L290)
Extended State Management
The x86_64 architecture provides extensive floating-point and SIMD capabilities that require specialized state management:
FxsaveArea Structure
The FxsaveArea
represents the 512-byte memory region used by the FXSAVE/FXRSTOR instructions:
Field | Type | Purpose |
---|---|---|
fcw | u16 | FPU Control Word |
fsw | u16 | FPU Status Word |
ftw | u16 | FPU Tag Word |
fop | u16 | FPU Opcode |
fip | u64 | FPU Instruction Pointer |
fdp | u64 | FPU Data Pointer |
mxcsr | u32 | MXCSR Register |
mxcsr_mask | u32 | MXCSR Mask |
st | [u64; 16] | ST0-ST7 FPU registers |
xmm | [u64; 32] | XMM0-XMM15 registers |
Sources: src/x86_64/context.rs(L86 - L107)
ExtendedState Operations
The ExtendedState
provides methods for saving and restoring FP/SIMD state:
flowchart TD subgraph subGraph2["Hardware Interface"] CPU_FPU["CPU FPU/SIMD Units"] FXSAVE_AREA["512-byte aligned memory"] end subgraph subGraph1["Default Values"] FCW["fcw = 0x37fStandard FPU control"] FTW["ftw = 0xffffAll tags empty"] MXCSR["mxcsr = 0x1f80Standard SIMD control"] end subgraph subGraph0["ExtendedState Operations"] SAVE["save()_fxsave64()"] RESTORE["restore()_fxrstor64()"] DEFAULT["default()Initialize with standard values"] end DEFAULT --> FCW DEFAULT --> FTW DEFAULT --> MXCSR RESTORE --> CPU_FPU RESTORE --> FXSAVE_AREA SAVE --> CPU_FPU SAVE --> FXSAVE_AREA
Sources: src/x86_64/context.rs(L115 - L137)
Task Context Initialization
The task context initialization process sets up a new task for execution:
flowchart TD subgraph subGraph2["Stack Layout"] STACK_TOP["Stack top (16-byte aligned)"] PADDING["8-byte padding"] SWITCH_FRAME["ContextSwitchFramerip = entry point"] end subgraph subGraph1["Default Values"] KSTACK["kstack_top = 0"] RSP["rsp = 0"] FS_BASE["fs_base = 0"] CR3["cr3 = kernel page table"] EXT_STATE["ext_state = default"] GS_BASE["gs_base = 0"] end subgraph subGraph0["Task Initialization"] NEW["new()Create empty context"] INIT["init()Setup for execution"] SETUP_STACK["Setup kernel stack16-byte alignment"] CREATE_FRAME["Create ContextSwitchFrameSet entry point"] SET_TLS["Set TLS basefs_base = tls_area"] end CREATE_FRAME --> SET_TLS INIT --> SETUP_STACK NEW --> CR3 NEW --> EXT_STATE NEW --> FS_BASE NEW --> GS_BASE NEW --> KSTACK NEW --> RSP PADDING --> SWITCH_FRAME SETUP_STACK --> CREATE_FRAME SETUP_STACK --> STACK_TOP STACK_TOP --> PADDING
Sources: src/x86_64/context.rs(L185 - L227)
User Space Context Management
When the uspace
feature is enabled, the context management system provides additional support for user space processes:
User Space Fields
Field | Purpose | Usage |
---|---|---|
gs_base | User space GS base register | Saved/restored via MSR operations |
cr3 | Page table root | Updated during context switch |
Page Table Management
The context switching process includes page table switching when transitioning between user space tasks:
flowchart TD subgraph subGraph1["TSS Update"] UPDATE_TSS["write_tss_rsp0(next_ctx.kstack_top)"] KERNEL_STACK["Update kernel stack for syscalls"] end subgraph subGraph0["Page Table Switch Logic"] CHECK["Compare next_ctx.cr3 with current cr3"] SWITCH["write_user_page_table(next_ctx.cr3)"] FLUSH["TLB automatically flushed"] SKIP["Skip page table switch"] end CHECK --> SKIP CHECK --> SWITCH SWITCH --> FLUSH SWITCH --> UPDATE_TSS UPDATE_TSS --> KERNEL_STACK
Sources: src/x86_64/context.rs(L253 - L263)
System Call Argument Extraction
The TrapFrame
provides convenient methods for extracting system call arguments following the x86_64 calling convention:
Method | Register | Purpose |
---|---|---|
arg0() | rdi | First argument |
arg1() | rsi | Second argument |
arg2() | rdx | Third argument |
arg3() | r10 | Fourth argument (note: r10, not rcx) |
arg4() | r8 | Fifth argument |
arg5() | r9 | Sixth argument |
is_user() | cs & 3 | Check if trap originated from user space |
Sources: src/x86_64/context.rs(L37 - L71)