page_table_multiarch Crate
Relevant source files
The page_table_multiarch crate provides high-level, architecture-independent page table management abstractions for 64-bit platforms. This crate implements the generic PageTable64 structure and supporting traits that enable unified page table operations across multiple hardware architectures including x86_64, AArch64, RISC-V, and LoongArch64.
For low-level page table entry definitions and architecture-specific implementations, see page_table_entry Crate. For detailed architecture-specific support information, see Architecture Support.
Core Components
The crate centers around three main abstractions that work together to provide architecture-independent page table management:
Architecture Abstraction Through Generic Types
Sources: page_table_multiarch/src/bits64.rs(L28 - L31) page_table_multiarch/src/lib.rs(L40 - L92)
PageTable64 Implementation
The PageTable64 struct is the central component providing a unified interface for page table operations across all supported architectures:
| Component | Type Parameter | Purpose |
|---|---|---|
| M | PagingMetaData | Architecture-specific constants and validation |
| PTE | GenericPTE | Page table entry manipulation |
| H | PagingHandler | OS-dependent memory management |
flowchart TD
subgraph subGraph2["Bulk Operations"]
MAP_REGION["map_region()"]
UNMAP_REGION["unmap_region()"]
PROTECT_REGION["protect_region()"]
end
subgraph subGraph1["Core Operations"]
MAP["map()"]
UNMAP["unmap()"]
QUERY["query()"]
PROTECT["protect()"]
REMAP["remap()"]
end
subgraph subGraph0["PageTable64 Structure"]
ROOT["root_paddr: PhysAddr"]
PHANTOM["_phantom: PhantomData"]
end
subgraph subGraph3["Utility Operations"]
WALK["walk()"]
COPY["copy_from()"]
TRY_NEW["try_new()"]
end
MAP --> MAP_REGION
PROTECT --> PROTECT_REGION
ROOT --> MAP
ROOT --> QUERY
ROOT --> UNMAP
UNMAP --> UNMAP_REGION
Page Table Management Methods
Single Page Operations
The PageTable64 provides methods for managing individual page mappings:
map()- Maps a virtual page to a physical frame with specified size and flags page_table_multiarch/src/bits64.rs(L59 - L72)unmap()- Removes a mapping and returns the physical address page_table_multiarch/src/bits64.rs(L116 - L125)query()- Retrieves mapping information for a virtual address page_table_multiarch/src/bits64.rs(L134 - L141)protect()- Updates mapping flags without changing the physical address page_table_multiarch/src/bits64.rs(L99 - L110)remap()- Updates both physical address and flags page_table_multiarch/src/bits64.rs(L81 - L91)
Bulk Region Operations
For efficient handling of large memory regions, bulk operations automatically detect and use huge pages when possible:
map_region()- Maps contiguous virtual regions with automatic huge page detection page_table_multiarch/src/bits64.rs(L157 - L217)unmap_region()- Unmaps contiguous regions page_table_multiarch/src/bits64.rs(L226 - L257)protect_region()- Updates flags for entire regions page_table_multiarch/src/bits64.rs(L266 - L299)
Sources: page_table_multiarch/src/bits64.rs(L33 - L347)
Architecture Abstraction System
The crate achieves architecture independence through a trait-based abstraction system:
flowchart TD
subgraph subGraph3["Entry Operations"]
NEW_PAGE["new_page()"]
NEW_TABLE["new_table()"]
IS_PRESENT["is_present()"]
IS_HUGE["is_huge()"]
PADDR["paddr()"]
FLAGS["flags()"]
end
subgraph subGraph2["OS Integration"]
ALLOC["alloc_frame()"]
DEALLOC["dealloc_frame()"]
PHYS_TO_VIRT["phys_to_virt()"]
end
subgraph subGraph1["Architecture Constants"]
LEVELS["LEVELS: usize"]
PA_BITS["PA_MAX_BITS: usize"]
VA_BITS["VA_MAX_BITS: usize"]
VADDR_TYPE["VirtAddr: MemoryAddr"]
end
subgraph subGraph0["Trait System"]
PMD_TRAIT["PagingMetaData trait"]
PH_TRAIT["PagingHandler trait"]
GPTE_TRAIT["GenericPTE trait"]
end
GPTE_TRAIT --> FLAGS
GPTE_TRAIT --> IS_HUGE
GPTE_TRAIT --> IS_PRESENT
GPTE_TRAIT --> NEW_PAGE
GPTE_TRAIT --> NEW_TABLE
GPTE_TRAIT --> PADDR
PH_TRAIT --> ALLOC
PH_TRAIT --> DEALLOC
PH_TRAIT --> PHYS_TO_VIRT
PMD_TRAIT --> LEVELS
PMD_TRAIT --> PA_BITS
PMD_TRAIT --> VADDR_TYPE
PMD_TRAIT --> VA_BITS
Trait Responsibilities
PagingMetaData Trait
Defines architecture-specific constants and validation logic:
LEVELS- Number of page table levels (3 or 4)PA_MAX_BITS/VA_MAX_BITS- Maximum address widthsVirtAddr- Associated type for virtual addressesflush_tlb()- Architecture-specific TLB flushing
PagingHandler Trait
Provides OS-dependent memory management operations:
alloc_frame()- Allocates 4K physical framesdealloc_frame()- Deallocates physical framesphys_to_virt()- Converts physical to virtual addresses for direct access
Sources: page_table_multiarch/src/lib.rs(L40 - L92)
Page Table Navigation
The PageTable64 implements multi-level page table navigation supporting both 3-level and 4-level configurations:
flowchart TD
subgraph subGraph3["Page Sizes"]
SIZE_1G["1GB Pages (P3 level)"]
SIZE_2M["2MB Pages (P2 level)"]
SIZE_4K["4KB Pages (P1 level)"]
end
subgraph subGraph2["Index Functions"]
P4_IDX["p4_index(vaddr)"]
P3_IDX["p3_index(vaddr)"]
P2_IDX["p2_index(vaddr)"]
P1_IDX["p1_index(vaddr)"]
end
subgraph subGraph1["3-Level Page Table (RISC-V Sv39)"]
P3_3["P3 Table (Level 0)"]
P2_3["P2 Table (Level 1)"]
P1_3["P1 Table (Level 2)"]
end
subgraph subGraph0["4-Level Page Table (x86_64, AArch64)"]
P4["P4 Table (Level 0)"]
P3_4["P3 Table (Level 1)"]
P2_4["P2 Table (Level 2)"]
P1_4["P1 Table (Level 3)"]
end
P1_IDX --> P1_3
P1_IDX --> P1_4
P2_IDX --> P2_3
P2_IDX --> P2_4
P3_IDX --> P3_3
P3_IDX --> P3_4
P4 --> P3_4
P4_IDX --> P4
Virtual Address Translation
The implementation uses bit manipulation to extract table indices from virtual addresses:
- P4 Index: Bits 39-47 (4-level only) page_table_multiarch/src/bits64.rs(L8 - L10)
- P3 Index: Bits 30-38 page_table_multiarch/src/bits64.rs(L12 - L14)
- P2 Index: Bits 21-29 page_table_multiarch/src/bits64.rs(L16 - L18)
- P1 Index: Bits 12-20 page_table_multiarch/src/bits64.rs(L20 - L22)
Sources: page_table_multiarch/src/bits64.rs(L8 - L22) page_table_multiarch/src/bits64.rs(L401 - L484)
Error Handling and TLB Management
The crate provides comprehensive error handling and TLB management:
| Error Type | Description | Usage |
|---|---|---|
| NoMemory | Frame allocation failure | Memory exhaustion scenarios |
| NotAligned | Address alignment violation | Invalid page boundaries |
| NotMapped | Missing page table entry | Query/unmap operations |
| AlreadyMapped | Existing mapping conflict | Duplicate map operations |
| MappedToHugePage | Huge page access conflict | Table navigation errors |
flowchart TD
subgraph subGraph2["Operation Results"]
SINGLE["Single page operations"]
BULK["Bulk region operations"]
end
subgraph subGraph1["TLB Management"]
TF["TlbFlush<M>"]
TFA["TlbFlushAll<M>"]
subgraph Operations["Operations"]
FLUSH["flush()"]
IGNORE["ignore()"]
FLUSH_ALL["flush_all()"]
end
end
BULK --> TFA
SINGLE --> TF
TF --> FLUSH
TF --> IGNORE
TFA --> FLUSH_ALL
TLB Flush Types
TlbFlush<M>- Manages single page TLB invalidation page_table_multiarch/src/lib.rs(L135 - L151)TlbFlushAll<M>- Manages complete TLB invalidation page_table_multiarch/src/lib.rs(L157 - L172)
Sources: page_table_multiarch/src/lib.rs(L21 - L38) page_table_multiarch/src/lib.rs(L130 - L172)
Dependencies and Integration
The crate integrates with the workspace through carefully managed dependencies:
Conditional Compilation
The build system includes architecture-specific dependencies only when targeting supported platforms or building documentation:
- x86 dependency: Included for
x86_64targets and documentation builds page_table_multiarch/Cargo.toml(L20 - L21) - riscv dependency: Included for
riscv32/riscv64targets and documentation builds page_table_multiarch/Cargo.toml(L23 - L24)
Sources: page_table_multiarch/Cargo.toml(L15 - L28) page_table_multiarch/src/lib.rs(L15 - L19)