arch/risc-v: kill faulting user task instead of panicking kernel#19377
Merged
Conversation
riscv_fillpage() unconditionally panics the kernel on an unmappable or invalid access, even when the fault is caused by a user task. A user-space fault should terminate that task with SIGSEGV instead of taking down the whole system, matching the existing behavior for other exceptions in riscv_exception(). Signed-off-by: liang.huang <liang.huang@houmo.ai>
xiaoxiang781216
approved these changes
Jul 9, 2026
tmedicci
approved these changes
Jul 10, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
riscv_fillpage()is the LOADPF/STOREPF handler used underCONFIG_PAGING. Both ofits fault paths (virtual address not mappable, leaf PTE already mapped with a
permission violation) unconditionally called
PANIC_WITH_REGS(), taking down thewhole kernel even when the fault was caused by an ordinary user-space task
dereferencing a bad pointer.
riscv_exception()already has a pattern for this: if the faulting task is a usertask and not currently inside a syscall, it rewrites the trap frame to return into
_exit(SIGSEGV)on the task's own kernel stack instead of panicking, and only panicswhen there's no safe task to terminate (kernel thread, or a fault while already
running kernel code on behalf of a syscall).
riscv_fillpage()never reused thislogic, so any user-space wild-pointer access that missed the paged-in text/data/heap
regions crashed the entire system instead of just the offending process.
This PR extracts that decision (terminate the task vs. panic) out of
riscv_exception()into a shared static helper,riscv_fault_handler(), and hasboth
riscv_exception()and both fault sites inriscv_fillpage()call it.Impact
CONFIG_PAGINGbuilds (BUILD_KERNEL && ARCH_USE_MMU && !ARCH_ROMPGTABLE && !LEGACY_PAGING) on RISC-V.riscv_fillpage()on an addressoutside the mappable text/data/heap ranges, or on top of an already-mapped leaf PTE
(permission violation), is now terminated with
SIGSEGVinstead of taking down thekernel. Kernel threads and faults occurring in kernel context on behalf of a syscall
still panic, since there's no user task that can be safely unwound in that case.
application (leaf PTE already valid but its permissions don't satisfy the access,
e.g. a write to an already-loaded
.textpage): that case used to unconditionallypanic the kernel, and now terminates the offending task instead, consistent with
every other fault path in this file.
riscv_exception()itself: its own panic/terminate logic is nowin
riscv_fault_handler(), called the same way as before.Testing
Tested on QEMU RISC-V (
rv-virt), bothknsh_paging(32-bit) andknsh64_paging(64-bit) configs. Also verified on Houmo M50 hardware.
Test app, a modified
hellothat dereferences a NULL pointer:Before this fix: the NULL write is treated as "address not mappable", and
riscv_fillpagepanics the whole kernel:The whole system goes down for a single user process's bad pointer.
After this fix: same test app, same NULL write.
riscv_fillpagestill detects thefault the same way, but now routes it through
riscv_fault_handler(), whichrecognizes
helloas a user task not in a syscall and terminates it withSIGSEGVinstead of panicking: