Generic Traits System
Relevant source files
This document describes the core trait system that enables architecture abstraction in the page_table_multiarch library. The traits define interfaces for architecture-specific metadata, OS-level memory management, and page table entry manipulation, allowing a single PageTable64
implementation to work across multiple processor architectures.
For information about how these traits are implemented for specific architectures, see the Architecture Support section 4. For details about the main page table implementation that uses these traits, see PageTable64 Implementation.
Core Trait Architecture
The generic traits system consists of three primary traits that decouple architecture-specific behavior from the common page table logic:
flowchart TD subgraph subGraph3["Architecture Implementations"] X86_MD["X64PagingMetaData"] ARM_MD["A64PagingMetaData"] RV_MD["Sv39MetaData/Sv48MetaData"] LA_MD["LA64MetaData"] X86_PTE["X64PTE"] ARM_PTE["A64PTE"] RV_PTE["Rv64PTE"] LA_PTE["LA64PTE"] end subgraph subGraph2["Page Table Implementation"] PT64["PageTable64<M,PTE,H>Generic page table"] end subgraph subGraph1["Supporting Types"] MF["MappingFlagsGeneric permission flags"] PS["PageSize4K, 2M, 1G page sizes"] TLB["TlbFlush/TlbFlushAllTLB invalidation"] end subgraph subGraph0["Generic Traits Layer"] PMD["PagingMetaDataArchitecture constants& address validation"] PH["PagingHandlerOS memory management& virtual mapping"] GPTE["GenericPTEPage table entrymanipulation"] end GPTE --> ARM_PTE GPTE --> LA_PTE GPTE --> RV_PTE GPTE --> X86_PTE PMD --> ARM_MD PMD --> LA_MD PMD --> RV_MD PMD --> X86_MD PT64 --> GPTE PT64 --> MF PT64 --> PH PT64 --> PMD PT64 --> PS PT64 --> TLB
Sources: page_table_multiarch/src/lib.rs(L42 - L92) page_table_entry/src/lib.rs(L41 - L68)
PagingMetaData Trait
The PagingMetaData
trait defines architecture-specific constants and validation logic for page table implementations:
Method/Constant | Purpose | Type |
---|---|---|
LEVELS | Number of page table levels | const usize |
PA_MAX_BITS | Maximum physical address bits | const usize |
VA_MAX_BITS | Maximum virtual address bits | const usize |
VirtAddr | Virtual address type for this architecture | Associated type |
paddr_is_valid() | Validates physical addresses | fn(usize) -> bool |
vaddr_is_valid() | Validates virtual addresses | fn(usize) -> bool |
flush_tlb() | Flushes Translation Lookaside Buffer | fn(OptionSelf::VirtAddr) |
Address Validation Logic
The trait provides default implementations for address validation that work for most architectures:
flowchart TD PADDR_CHECK["paddr_is_valid(paddr)"] PADDR_RESULT["paddr <= PA_MAX_ADDR"] VADDR_CHECK["vaddr_is_valid(vaddr)"] VADDR_MASK["top_mask = usize::MAX << (VA_MAX_BITS - 1)"] VADDR_SIGN["(vaddr & top_mask) == 0 ||(vaddr & top_mask) == top_mask"] PADDR_CHECK --> PADDR_RESULT VADDR_CHECK --> VADDR_MASK VADDR_MASK --> VADDR_SIGN
Sources: page_table_multiarch/src/lib.rs(L61 - L72)
PagingHandler Trait
The PagingHandler
trait abstracts OS-level memory management operations required by the page table implementation:
Method | Purpose | Signature |
---|---|---|
alloc_frame() | Allocate a 4K physical frame | fn() -> Option |
dealloc_frame() | Free a physical frame | fn(PhysAddr) |
phys_to_virt() | Get virtual address for physical memory access | fn(PhysAddr) -> VirtAddr |
This trait enables the page table implementation to work with different memory management systems by requiring the OS to provide these three fundamental operations.
Sources: page_table_multiarch/src/lib.rs(L83 - L92)
GenericPTE Trait
The GenericPTE
trait provides a unified interface for manipulating page table entries across different architectures:
flowchart TD subgraph subGraph4["Query Methods"] IS_UNUSED["is_unused() -> bool"] IS_PRESENT["is_present() -> bool"] IS_HUGE["is_huge() -> bool"] end subgraph subGraph3["Modification Methods"] SET_PADDR["set_paddr(paddr)"] SET_FLAGS["set_flags(flags, is_huge)"] CLEAR["clear()"] end subgraph subGraph2["Access Methods"] GET_PADDR["paddr() -> PhysAddr"] GET_FLAGS["flags() -> MappingFlags"] GET_BITS["bits() -> usize"] end subgraph subGraph1["Creation Methods"] NEW_PAGE["new_page(paddr, flags, is_huge)"] NEW_TABLE["new_table(paddr)"] end subgraph subGraph0["GenericPTE Interface"] CREATE["Creation Methods"] ACCESS["Access Methods"] MODIFY["Modification Methods"] QUERY["Query Methods"] end ACCESS --> GET_BITS ACCESS --> GET_FLAGS ACCESS --> GET_PADDR CREATE --> NEW_PAGE CREATE --> NEW_TABLE MODIFY --> CLEAR MODIFY --> SET_FLAGS MODIFY --> SET_PADDR QUERY --> IS_HUGE QUERY --> IS_PRESENT QUERY --> IS_UNUSED
Sources: page_table_entry/src/lib.rs(L41 - L68)
MappingFlags System
The MappingFlags
bitflags provide a generic representation of memory permissions and attributes:
Flag | Value | Purpose |
---|---|---|
READ | 1 << 0 | Memory is readable |
WRITE | 1 << 1 | Memory is writable |
EXECUTE | 1 << 2 | Memory is executable |
USER | 1 << 3 | Memory is user-accessible |
DEVICE | 1 << 4 | Memory is device memory |
UNCACHED | 1 << 5 | Memory is uncached |
Architecture-specific implementations convert between these generic flags and their hardware-specific representations.
Sources: page_table_entry/src/lib.rs(L12 - L30)
Page Size Support
The PageSize
enum defines supported page sizes across architectures:
flowchart TD subgraph subGraph0["Helper Methods"] IS_HUGE["is_huge() -> bool"] IS_ALIGNED["is_aligned(addr) -> bool"] ALIGN_OFFSET["align_offset(addr) -> usize"] end PS["PageSize enum"] SIZE_4K["Size4K = 0x1000(4 KiB)"] SIZE_2M["Size2M = 0x20_0000(2 MiB)"] SIZE_1G["Size1G = 0x4000_0000(1 GiB)"] PS --> SIZE_1G PS --> SIZE_2M PS --> SIZE_4K SIZE_1G --> IS_HUGE SIZE_2M --> IS_HUGE
Sources: page_table_multiarch/src/lib.rs(L95 - L128)
TLB Management Types
The system provides type-safe TLB invalidation through must-use wrapper types:
flowchart TD subgraph Actions["Actions"] FLUSH["flush() - Execute flush"] IGNORE["ignore() - Skip flush"] FLUSH_ALL["flush_all() - Execute full flush"] end subgraph subGraph0["TLB Flush Types"] TLB_FLUSH["TlbFlush<M>Single address flush"] TLB_FLUSH_ALL["TlbFlushAll<M>Complete TLB flush"] end TLB_FLUSH --> FLUSH TLB_FLUSH --> IGNORE TLB_FLUSH_ALL --> FLUSH_ALL TLB_FLUSH_ALL --> IGNORE
These types ensure that TLB flushes are not accidentally forgotten after page table modifications by using the #[must_use]
attribute.
Sources: page_table_multiarch/src/lib.rs(L130 - L172)
Trait Integration Pattern
The three core traits work together to parameterize the PageTable64
implementation:
This design allows compile-time specialization while maintaining a common interface, enabling zero-cost abstractions across different processor architectures.
Sources: page_table_multiarch/src/lib.rs(L42 - L92) page_table_entry/src/lib.rs(L41 - L68)