Summary
The Linux/GNU simulation target has no module port. Adding one as a test scaffold only (no memory isolation) would allow the module manager sources to compile and be unit-tested on Linux but would not implement:
- Memory isolation (no
mprotect()/MPU enforcement)
- The privileged dispatcher gate (no
SVC-equivalent)
- Module binary loading from filesystem images
- Bounds checking on module-to-kernel pointer parameters
The goal of this issue is to go further and implement real mprotect()-based isolation in the Linux simulation port, making it useful for module boundary validation, developer tooling, and fuzzing.
Proposed implementation: mprotect()-based isolation
Use mprotect() as a software analog to the ARM MPU:
| Embedded (ARM Cortex-M) |
Linux simulation |
| 8–16 MPU region registers |
Two mprotect() region descriptors |
SVC instruction → SVC handler |
C dispatcher gate with mprotect() permission swap |
| Hardware MPU reload on context switch |
mprotect() syscall (~1 µs per switch) |
| MEMFAULT exception |
SIGSEGV → sigaction() handler |
New directory structure
ports_module/linux/gnu/
├── inc/
│ └── txm_module_port.h # port header
└── module_manager/src/
├── txm_module_manager_mm_setup.c # mmap regions, mprotect enforcement
├── txm_module_manager_user_mode_entry.c # replaces SVC gate
└── txm_module_manager_memory_fault.c # SIGSEGV handler → module fault callback
TXM_MODULE_MANAGER_PORT_EXTENSION would add two mprotect region descriptors to TXM_MODULE_INSTANCE (code region + data region).
Dispatcher gate sketch
ALIGN_TYPE _txm_module_manager_user_mode_entry(ULONG request, ...)
{
ALIGN_TYPE result;
mprotect(module_code, code_size, PROT_NONE);
mprotect(module_data, data_size, PROT_NONE);
result = _txm_module_manager_kernel_dispatch(request, ...);
mprotect(module_code, code_size, PROT_READ | PROT_EXEC);
mprotect(module_data, data_size, PROT_READ | PROT_WRITE);
return result;
}
Fault detection
static void module_fault_handler(int sig, siginfo_t *si, void *ctx)
{
/* Walk module list, find owner of faulting address, invoke module fault callback */
_txm_module_manager_fault_notify(faulting_module);
}
Known limitation: process-wide protection
mprotect() changes affect the entire process. In a multi-threaded scenario, only one module can be active at a time without a global lock. A future upgrade to Intel MPK (pkey_mprotect() + wrpkru) on capable hardware (Linux on Skylake+/Zen 2+) would remove this constraint because the PKRU register is thread-local.
Windows equivalent
A Windows counterpart in ports_module/win32/msvc/ is equally feasible using VirtualProtect() and AddVectoredExceptionHandler():
| Linux |
Windows |
mmap(MAP_ANONYMOUS|MAP_PRIVATE) |
VirtualAlloc(MEM_COMMIT|MEM_RESERVE) |
mprotect(..., PROT_NONE) |
VirtualProtect(..., PAGE_NOACCESS, &old) |
mprotect(..., PROT_READ|PROT_WRITE) |
VirtualProtect(..., PAGE_READWRITE, &old) |
mprotect(..., PROT_READ|PROT_EXEC) |
VirtualProtect(..., PAGE_EXECUTE_READ, &old) |
sigaction(SIGSEGV, ...) |
AddVectoredExceptionHandler(...) |
SIGSEGV |
EXCEPTION_ACCESS_VIOLATION |
Note: Intel MPK is not available on Windows. VirtualProtect() is the ceiling on that platform, which is acceptable for a simulation/test port.
Why this matters
- Module developer tooling: Catch isolation violations (stray pointer into kernel memory) as
SIGSEGV instead of silent corruption on developer workstations, without requiring embedded hardware.
- Fuzzing infrastructure: AFL/libfuzzer can target module inputs with real boundary detection on Linux.
- CI coverage: Isolation-breach scenarios can be validated in automated pipelines without a hardware target.
Scope
This is a new platform feature. The ports_module/linux/gnu/ directory and CMake wiring need to be created from scratch as part of this work.
Estimated effort: ~500–800 lines of new C code plus tests for each platform port.
Summary
The Linux/GNU simulation target has no module port. Adding one as a test scaffold only (no memory isolation) would allow the module manager sources to compile and be unit-tested on Linux but would not implement:
mprotect()/MPU enforcement)SVC-equivalent)The goal of this issue is to go further and implement real
mprotect()-based isolation in the Linux simulation port, making it useful for module boundary validation, developer tooling, and fuzzing.Proposed implementation:
mprotect()-based isolationUse
mprotect()as a software analog to the ARM MPU:mprotect()region descriptorsSVCinstruction → SVC handlermprotect()permission swapmprotect()syscall (~1 µs per switch)SIGSEGV→sigaction()handlerNew directory structure
TXM_MODULE_MANAGER_PORT_EXTENSIONwould add twomprotectregion descriptors toTXM_MODULE_INSTANCE(code region + data region).Dispatcher gate sketch
Fault detection
Known limitation: process-wide protection
mprotect()changes affect the entire process. In a multi-threaded scenario, only one module can be active at a time without a global lock. A future upgrade to Intel MPK (pkey_mprotect()+wrpkru) on capable hardware (Linux on Skylake+/Zen 2+) would remove this constraint because the PKRU register is thread-local.Windows equivalent
A Windows counterpart in
ports_module/win32/msvc/is equally feasible usingVirtualProtect()andAddVectoredExceptionHandler():mmap(MAP_ANONYMOUS|MAP_PRIVATE)VirtualAlloc(MEM_COMMIT|MEM_RESERVE)mprotect(..., PROT_NONE)VirtualProtect(..., PAGE_NOACCESS, &old)mprotect(..., PROT_READ|PROT_WRITE)VirtualProtect(..., PAGE_READWRITE, &old)mprotect(..., PROT_READ|PROT_EXEC)VirtualProtect(..., PAGE_EXECUTE_READ, &old)sigaction(SIGSEGV, ...)AddVectoredExceptionHandler(...)SIGSEGVEXCEPTION_ACCESS_VIOLATIONNote: Intel MPK is not available on Windows.
VirtualProtect()is the ceiling on that platform, which is acceptable for a simulation/test port.Why this matters
SIGSEGVinstead of silent corruption on developer workstations, without requiring embedded hardware.Scope
This is a new platform feature. The
ports_module/linux/gnu/directory and CMake wiring need to be created from scratch as part of this work.Estimated effort: ~500–800 lines of new C code plus tests for each platform port.