Skip to content

Conversation

@HeatCrab
Copy link
Collaborator

@HeatCrab HeatCrab commented Oct 29, 2025

This PR implements PMP (Physical Memory Protection) support for RISC-V to enable hardware-enforced memory isolation in Linmo, addressing #30.

Currently Phase 1 (infrastructure) is complete. This branch will continue development through the remaining phases. Phase 1 adds the foundational structures and declarations: PMP hardware layer in arch/riscv with CSR definitions and region management structures, architecture-independent memory abstractions (flex pages, address spaces, memory pools), kernel memory pool declarations from linker symbols, and TCB extension for address space linkage.

The actual PMP operations including region configuration, CSR manipulation, and context switching integration are not yet implemented.

TOR mode is used for its flexibility with arbitrary address ranges without alignment constraints, simplifying region management for task stacks of varying sizes. Priority-based eviction allows the system to manage competing demands when the 16 hardware regions are exhausted, ensuring critical kernel and stack regions remain protected while allowing temporary mappings to be reclaimed as needed.


Summary by cubic

Adds RISC-V Physical Memory Protection (PMP) for hardware memory isolation (Phase 1 of #30). Uses TOR mode with hardware init, boot-time kernel protection, trap-time recovery for access faults, and per-task context switching to load/evict flexpages.

  • New Features
    • PMP CSR definitions, permission bits, TOR-mode constants, and numeric CSR accessors.
    • Hardware init and region operations: set, disable, lock, read, and access checks with shadow state.
    • Kernel memory pools from linker symbols: text RX; data/bss/heap/stack RW (no execute).
    • Memory abstractions: flexpages and memory spaces; flexpage load/evict with victim selection; macro helpers.
    • TCB extended with a memory space pointer for per-task isolation.
    • PMP-related error codes for validation and state checks.
    • Trap handler integration to recover load/store faults by dynamically loading/evicting flexpages.
    • Context switch integration to evict old task regions and load new task flexpages.

Written for commit fa5a588. Summary will update automatically on new commits.

Copy link
Contributor

@jserv jserv left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use unified "flexpage" notation.

@HeatCrab HeatCrab force-pushed the pmp/memory-isolation branch from e264a35 to 4a62d5b Compare October 31, 2025 13:25
@HeatCrab
Copy link
Collaborator Author

Use unified "flexpage" notation.

Got it! Thanks for the correction and the L4 X.2 reference.
I've fixed all occurrences to use "flexpage" notation.

@HeatCrab HeatCrab force-pushed the pmp/memory-isolation branch 5 times, most recently from 109259d to f6c3912 Compare November 6, 2025 09:16
@HeatCrab HeatCrab force-pushed the pmp/memory-isolation branch 2 times, most recently from 2644558 to 1bb5fcf Compare November 16, 2025 13:18
jserv

This comment was marked as outdated.

@HeatCrab HeatCrab force-pushed the pmp/memory-isolation branch 6 times, most recently from 904e972 to ed800fc Compare November 21, 2025 12:38
@HeatCrab

This comment was marked as outdated.

Copy link
Contributor

@jserv jserv left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rebase the latest 'main' branch to resolve rtsched issues.

@HeatCrab HeatCrab force-pushed the pmp/memory-isolation branch 6 times, most recently from 0d55f21 to 865a5d6 Compare November 22, 2025 08:36
@HeatCrab
Copy link
Collaborator Author

Rebase the latest 'main' branch to resolve rtsched issues.

Finished. And I removed the M-mode fault-handling commits, as they are not aligned with the upcoming work.
Next, I plan to start U-mode support (#19) on a new branch, and then circle back to complete the PMP development and apply any adjustments that may be needed after the U-mode integration.

@HeatCrab HeatCrab force-pushed the pmp/memory-isolation branch from 865a5d6 to 7e3992e Compare December 11, 2025 08:51
@HeatCrab HeatCrab force-pushed the pmp/memory-isolation branch 5 times, most recently from 6ba8560 to 38e3ca5 Compare December 20, 2025 10:00
Introduces RISC-V Physical Memory Protection (PMP) support for hardware-enforced memory isolation. TOR mode is adopted as the addressing scheme for its flexibility in supporting arbitrary address ranges without alignment requirements, simplifying region management for task stacks of varying sizes. Adds CSR definitions for PMP registers, permission encodings, and hardware constants. Provides structures for region configuration and state tracking, with priority-based management to handle the 16-region hardware limit. Includes error codes and functions for region configuration and access verification.
Introduces three abstractions that build upon the PMP infrastructure for managing memory protection at different granularities. Flexpages represent contiguous physical memory regions with protection attributes, providing arbitrary base addresses and sizes without alignment constraints. Memory spaces implement the address space concept but use distinct terminology to avoid confusion with virtual address spaces, as this structure represents a task's memory protection domain in a physical-address-only system. They organize flexpages into task memory views and support sharing across multiple tasks without requiring an MMU. Memory pools define static regions for boot-time initialization of kernel memory protection. Field naming retains 'as_' prefix (e.g., as_id, as_next) to reflect the underlying address space concept, while documentation uses "memory space" terminology for clarity in physical-memory-only contexts. Structures are used to enable runtime iteration, simplify debugging, and maintain consistency with other subsystems. Macro helpers reduce initialization boilerplate while maintaining type safety.
Defines static memory pools for boot-time PMP initialization using linker symbols to identify kernel memory regions. Linker symbol declarations are updated to include text segment boundaries and match actual linker script definitions for stack regions. Five kernel memory pools protect text as read-execute, data and bss as read-write, heap and stack as read-write without execute to prevent code injection. Macro helpers reduce initialization boilerplate while maintaining debuggability through struct arrays. Priority-based management handles the 16-region hardware constraint.
Extends TCB with a memory space pointer to enable per-task memory isolation. Each task can now reference its own memory protection domain through the flexpage mechanism.
Adds creation and destruction functions for flexpages, which are software abstractions representing contiguous physical memory regions with hardware-enforced protection attributes. These primitives will be used by higher-level memory space management to construct per-task memory views for PMP-based isolation. Function naming follows kernel conventions to reflect that these operations manage abstract memory protection objects rather than just memory allocation.
@HeatCrab HeatCrab force-pushed the pmp/memory-isolation branch 5 times, most recently from 6c2c5cf to 811ac55 Compare December 20, 2025 15:36
Implements the core Physical Memory Protection (PMP) driver to bridge software flexpages with the underlying hardware, enabling dynamic management of limited PMP entries. This driver introduces a centralized global configuration state to track and coordinate PMP register usage across the kernel. To manage the finite hardware slots, it provides operations to dynamically load and evict flexpages at runtime. When hardware regions are exhausted, a priority-based victim selection algorithm identifies candidates for eviction. This policy prioritizes preserving critical system regions (priority 0) while selecting less important pages for replacement, ensuring safeguards against kernel instability during PMP context switches.
Add functions to create and destroy memory spaces, which serve as containers for flexpages. A memory space can be dedicated to a single task or shared across multiple tasks, supporting both isolated and shared memory models.
Provide helper functions for runtime-indexed access to PMP control and status registers alongside existing compile-time CSR macros. RISC-V CSR instructions encode register addresses as immediate values in the instruction itself, making dynamic selection impossible through simple arithmetic. These helpers use switch-case dispatch to map runtime indices to specific CSR instructions while preserving type safety. This enables PMP register management code to iterate over regions without knowing exact register numbers at compile-time, supporting features with multiple registers of the same type. PMP implementation is now included in the build system to make these helpers and future PMP functionality available at link time.
Provides a complete set of functions for managing Physical Memory Protection regions in TOR mode, maintaining shadow configuration state synchronized with hardware CSRs. Hardware initialization clears all PMP regions by zeroing address and configuration registers, then initializes shadow state with default values for each region slot. This establishes clean hardware and software state for subsequent region configuration. Region configuration validates that the address range is valid and the region is not locked, then constructs configuration bytes with TOR addressing mode and permission bits. Both hardware CSRs and shadow state are updated atomically, with optional locking to prevent further modification. A helper function computes configuration register index and bit offset from region index, eliminating code duplication across multiple operations. Region disabling clears the configuration byte to remove protection while preserving other regions in the same configuration register. Region locking sets the lock bit to prevent modification until hardware reset. Region retrieval reads address range, permissions, priority, and lock status from shadow configuration. Access verification checks whether a memory operation falls within configured region boundaries by comparing address and size, then validates that region permissions match the requested operation type. Address register read helpers are marked unused as the shadow state design eliminates the need to read hardware registers during normal operation. They remain available for potential future use cases requiring hardware state verification.
@HeatCrab HeatCrab force-pushed the pmp/memory-isolation branch from 811ac55 to bf5dfa9 Compare December 20, 2025 15:51
When a task accesses memory not currently loaded in a PMP region, the hardware raises an access fault. Rather than panicking, we now attempt recovery by dynamically loading the required region, enabling tasks to access more memory than can fit simultaneously in the 16 hardware regions. The ISR captures and passes the faulting memory address from the mtval CSR to the trap handler. The handler uses this address to locate the corresponding flexpage in the task's memory space. If all regions are in use, we select a victim and evict it to make space. This required exposing internal region management functions so the handler can invoke them, and simplifying documentation at implementation sites since detailed documentation now resides in headers.
Configure memory protection for kernel text, data, BSS, heap, and stack regions during hardware initialization. Halt on setup failure.
Add per-task memory space switching during context transitions. Evicts old task's dynamic regions and loads new task's regions into available hardware slots while preserving locked kernel regions.
Switch memory protection configuration during task context switches for both preemptive and cooperative scheduling. The old task's memory space is captured before the scheduler updates its internal state, allowing both old and new memory spaces to be passed to the PMP switching logic.
Allocate a dedicated memory space for each task and register the task stack as a flexpage. This establishes the memory protection metadata that will be loaded into hardware regions during context switches.
Validate PMP hardware configuration during task context switches by reading CSRs directly. Tests verify that kernel regions remain loaded and PMP state persists correctly across switches. Since linmo runs in M-mode only, PMP cannot enforce access restrictions. The test focuses on infrastructure correctness: CSR configuration, context switching mechanics, and flexpage metadata management. Test results: 30/30 checks pass. PMP CSRs show correct configuration with kernel regions loaded at expected addresses.
@HeatCrab HeatCrab force-pushed the pmp/memory-isolation branch from bf5dfa9 to fa5a588 Compare December 20, 2025 15:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

2 participants