Expand description
N3 MMU Thread Migration : PCID-preserving (N3b) and Full Isolation (N3c).
Implements the transport layer for IPC level N3
§Architecture
sender ──send()──▶ MigrationFrame ──CR3 switch──▶ receiver handler
▲ │
└────────────── reschedule IPI ◀─────────────────────┘The sender saves its context, copies the message, then calls the ASM primitive which switches CR3 and restores the receiver’s context. The receiver handler reads the message from the frame and returns. The sender is resumed via a reschedule IPI.
§Frame pointer requirement
The send() method captures sender_rip from [rbp + 8], which requires
frame pointers to be enabled at compile time. The kernel must be built with
-C force-frame-pointers=yes (see workspace/kernel/.cargo/config.toml).
§Shared mapping note
The MigrationFrame is mapped in both address spaces at the same virtual
address (N3_SHARED_FRAME_VA), but without USER_ACCESSIBLE. The frame
lives in kernel space and is accessible only from Ring 0. Both sender and
receiver access it via their kernel page tables : the shared VA means the
same PTE (same physical page) is reachable from both page table hierarchies.
This is NOT a user-mappable region; it is kernel-only shared memory.
§PCID contract
A PCID value of 0 means “no PCID” : either PCID is unsupported by the CPU
or exhausted. All code paths check pcid > 0 before using PCID-specific
features (INVPCID, CR3 PCID bits). The tier selection function
(select_n3_tier()) distinguishes theoretical CPU support from actual
operational capability.
Structs§
- Frame
Allocator 🔒 - Bitmap-based O(1) frame allocator.
- Frame
Pool 🔒 - Static pool of MigrationFrame slots.
- Migration
Flags - Flags for a migration operation.
- Migration
Frame - Shared migration frame : one per N3 transport endpoint pair.
- MsgBuffer 🔒
- Wrapper for a raw pointer to the shared message buffer.
- N3Minimal
Context - Minimal CPU context saved/restored during N3 migration.
- N3Transport
- N3 MMU transport : thread migration between distinct address spaces.
- Watchdog
Entry 🔒 - Watchdog state per frame.
Enums§
- Migration
State - Migration state machine.
- N3Tier
- N3 tier selection
Constants§
- MAX_
PCIDS 🔒 - Maximum number of PCIDs before panic (x86-64 supports 4096).
- N3_
FRAME_ 🔒POOL_ SIZE - Number of pre-allocated migration frames.
- N3_
HANDLER_ 🔒STACK_ SIZE - Size of the per-N3Transport handler stack (1 page).
After CR3 switch, the ASM primitive loads RSP from
dst_ctx.rspwhich points to this stack with the handler address as the return address. - N3_
MSG_ BUF_ SIZE - Maximum message size for N3 transport (separate buffer, not in frame).
- N3_
SHARED_ FRAME_ VA - Virtual address where the MigrationFrame is mapped in both address spaces. Located in canonical upper-half, just below the HHDM boundary.
- N3_
SHARED_ MSG_ BUF_ VA - Virtual address where the shared message buffer is mapped. Must be distinct from N3_SHARED_FRAME_VA to avoid page table conflicts.
- N3_
WATCHDOG_ 🔒TIMEOUT - Default watchdog timeout in TSC cycles (~10ms at 3GHz).
Statics§
- N3_
FRAME_ 🔒ALLOC - N3_
FRAME_ 🔒POOL - N3_
PENDING_ 🔒MIGRATION - Per-CPU pending migration frame pointer. Set by the sender before sending the IPI, consumed by the IPI handler.
- N3_
WATCHDOG_ 🔒TABLE - Global watchdog table.
- PCID_
COUNTER 🔒 - Global PCID counter : monotonic allocation, panics at 4096 (prototype).
Functions§
- alloc_
frame_ 🔒slot - Allocate a MigrationFrame from the static pool.
- allocate_
pcid - Allocate a stable PCID for an address space.
- frame_
pool_ 🔒phys_ addr - Get the physical address of a frame in the static pool.
- free_
frame_ 🔒slot - Free a MigrationFrame back to the pool.
- free_
pcid - Free a PCID back to the pool (called when an address space is destroyed).
- map_
frame_ 🔒in_ both_ spaces - Map a MigrationFrame’s physical page into both sender and receiver
address spaces at
N3_SHARED_FRAME_VA. - map_
msg_ 🔒buf_ in_ both_ spaces - Map a message buffer’s physical page into both address spaces
at
N3_SHARED_MSG_BUF_VA. - map_
page_ 🔒in_ space - Map a physical page into an address space at the specified virtual address.
- n3_
frame_ generation - Get the current generation counter of a frame.
- n3_
frame_ is_ ready - Check if a frame is in the Ready state.
- n3_
frame_ state - Get the current migration state of a frame.
- n3_
migrate_ ⚠ipi_ entry - Naked IPI handler for N3 migration synchronization.
- n3_
migrate_ ipi_ handler - Fallback handler for N3 migration IPI (non-naked path).
- n3_
prepare_ 🔒migration - Prepare a MigrationFrame for a send operation.
- n3_
watchdog_ tick - Called from the timer ISR to check for stalled migrations.
- n3b_
migrate_ ⚠asm - ASM migration primitive.
- pcid_
available - Check if PCID feature is available on this CPU.
- safe_
kernel_ 🔒rflags - Return safe kernel-mode rflags for N3 context switching.
- select_
n3_ tier - Select the N3 tier based on actual PCID capability.
- send_
n3_ 🔒sync_ ipi - Send a migration-sync IPI to the target CPU.
- shared_
msg_ 🔒read - Read the message payload from a shared message buffer.
- shared_
msg_ 🔒write - Write a message payload into a shared message buffer.
- unmap_
from_ 🔒both_ spaces - Unmap the MigrationFrame and message buffer from both address spaces.
- unmap_
page_ 🔒in_ space - Unmap a single page from an address space and shoot down TLB on all CPUs.
- validate_
rip 🔒 - Validate that
rippoints to an authorized executable page. - walk_
page_ 🔒 ⚠tables_ executable - Walk x86-64 4-level page tables to check if
vaddris present, executable, and supervisor-only (U/S=0). - watchdog_
recover 🔒 - Recover a stalled frame : reset to Ready via atomic CAS transitions.
- watchdog_
register 🔒 - Register a frame with the watchdog.
- watchdog_
unregister 🔒 - Unregister a frame from the watchdog.