Skip to content

arch/risc-v: kill faulting user task instead of panicking kernel#19377

Merged
xiaoxiang781216 merged 1 commit into
apache:masterfrom
hitHuang:fix/riscv_fillpage
Jul 10, 2026
Merged

arch/risc-v: kill faulting user task instead of panicking kernel#19377
xiaoxiang781216 merged 1 commit into
apache:masterfrom
hitHuang:fix/riscv_fillpage

Conversation

@hitHuang

@hitHuang hitHuang commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Summary

riscv_fillpage() is the LOADPF/STOREPF handler used under CONFIG_PAGING. Both of
its fault paths (virtual address not mappable, leaf PTE already mapped with a
permission violation) unconditionally called PANIC_WITH_REGS(), taking down the
whole 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 user
task 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 panics
when 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 this
logic, 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 has
both riscv_exception() and both fault sites in riscv_fillpage() call it.

Impact

  • Only affects CONFIG_PAGING builds (BUILD_KERNEL && ARCH_USE_MMU && !ARCH_ROMPGTABLE && !LEGACY_PAGING) on RISC-V.
  • Behavior change: a user-space task that faults in riscv_fillpage() on an address
    outside the mappable text/data/heap ranges, or on top of an already-mapped leaf PTE
    (permission violation), is now terminated with SIGSEGV instead of taking down the
    kernel. 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.
  • This also applies to permission-mismatch faults triggered by a user-space
    application (leaf PTE already valid but its permissions don't satisfy the access,
    e.g. a write to an already-loaded .text page): that case used to unconditionally
    panic the kernel, and now terminates the offending task instead, consistent with
    every other fault path in this file.
  • No Kconfig, API, or build system changes.
  • Pure refactor for riscv_exception() itself: its own panic/terminate logic is now
    in riscv_fault_handler(), called the same way as before.

Testing

Tested on QEMU RISC-V (rv-virt), both knsh_paging (32-bit) and knsh64_paging
(64-bit) configs. Also verified on Houmo M50 hardware.

Test app, a modified hello that dereferences a NULL pointer:

int main(int argc, FAR char *argv[])
{
  *(int *)0 = 0x5a5a5a5a;

  printf("Hello, World!!\n");
  return 0;
}

Before this fix: the NULL write is treated as "address not mappable", and
riscv_fillpage panics the whole kernel:

NuttShell (NSH) NuttX-13.0.0-RC2
nsh> hello
[    2.307000] riscv_fillpage: EXCEPTION: Store/AMO page fault. MCAUSE: 0000000f, EPC: 8020edc0, MTVAL: c0001000
[    2.318000] riscv_fillpage: EXCEPTION: Store/AMO page fault. MCAUSE: 0000000f, EPC: 8020fa1c, MTVAL: c1000ffc
[    2.320000] riscv_fillpage: EXCEPTION: Store/AMO page fault. MCAUSE: 0000000f, EPC: 8021011c, MTVAL: c080638c
[    2.322000] riscv_fillpage: EXCEPTION: Store/AMO page fault. MCAUSE: 0000000f, EPC: 80211108, MTVAL: c0804004
[    2.324000] riscv_fillpage: EXCEPTION: Store/AMO page fault. MCAUSE: 0000000f, EPC: c00003bc, MTVAL: c0803ffc
[    2.328000] riscv_fillpage: EXCEPTION: Store/AMO page fault. MCAUSE: 0000000f, EPC: c00003ee, MTVAL: 00000000
[    2.328000] riscv_fillpage: PANIC!!! virtual address not mappable: 0
[    2.328000] dump_assert_info: Current Version: NuttX  13.0.0-RC2 194d38ea4f Jul  8 2026 11:32:56 risc-v
[    2.328000] dump_assert_info: Assertion failed panic: at file: :0 task: hello process: hello 0xc00003ba
[    2.328000] up_dump_register: EPC: c00003ee
[    2.328000] up_dump_register: A0: 00000001 A1: c0802020 A2: 00000000 A3: 00000020
[    2.328000] up_dump_register: A4: 00000000 A5: 5a5a5a5a A6: 00000000 A7: 00000000
[    2.328000] up_dump_register: T0: 0000001c T1: 80608720 T2: 80609320 T3: 00042022
[    2.328000] up_dump_register: T4: 00000001 T5: 80607a70 T6: 00000000
[    2.328000] up_dump_register: S0: 00000668 S1: 80609988 S2: 8020f40a S3: 00000000
[    2.328000] up_dump_register: S4: 00000000 S5: 00000000 S6: 0000001c S7: 00000000
[    2.328000] up_dump_register: S8: 00000000 S9: 00000000 S10: 00042022 S11: 80609308
[    2.328000] up_dump_register: SP: c0803fb0 FP: 00000668 TP: 00000000 RA: c00003d6
[    2.328000] dump_stackinfo: User Stack:
[    2.328000] dump_stackinfo:   base: 0xc0802030
[    2.328000] dump_stackinfo:   size: 00008144
[    2.328000] dump_stackinfo:     sp: 0xc0803fb0
[    2.328000] stack_dump: 0xc0803f90: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[    2.328000] stack_dump: 0xc0803fb0: 00000000 00000000 c0802020 00000001 00000000 00000000 00000000 c00003d6
[    2.328000] stack_dump: 0xc0803fd0: 00000000 00000000 c0802020 00000001 00000000 00000000 00000000 00000000
[    2.328000] stack_dump: 0xc0803ff0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[    2.328000] dump_tasks:    PID GROUP PRI POLICY   TYPE    NPX STATE   EVENT      SIGMASK          STACKBASE  STACKSIZE   COMMAND
[    2.328000] dump_tasks:   ----   --- --- -------- ------- --- ------- ---------- ---------------- 0x80606000      2048   irq
[    2.328000] dump_task:       0     0   0 FIFO     Kthread -   Ready              0000000000000000 0x80607b40      3040   Idle_Task
[    2.328000] dump_task:       1     0 100 RR       Kthread -   Waiting Semaphore  0000000000000000 0x8060a050      1968   lpwork 0x80600010 0x80600060
[    2.328000] dump_task:       3     3 100 RR       Task    -   Waiting Signal     0000000000000000 0xc0802040      3008   /system/bin/init
[    2.328000] dump_task:       4     4 100 RR       Task    -   Running            0000000000000000 0xc0802030      8144   hello

The whole system goes down for a single user process's bad pointer.

After this fix: same test app, same NULL write. riscv_fillpage still detects the
fault the same way, but now routes it through riscv_fault_handler(), which
recognizes hello as a user task not in a syscall and terminates it with SIGSEGV
instead of panicking:

NuttShell (NSH) NuttX-13.0.0-RC2
nsh> hello
[    1.724000] riscv_fillpage: EXCEPTION: Store/AMO page fault. MCAUSE: 000000000000000f, EPC: 000000008020f2d8, MTVAL: 00000000c0001000
[    1.734000] riscv_fillpage: EXCEPTION: Store/AMO page fault. MCAUSE: 000000000000000f, EPC: 000000008020ff78, MTVAL: 00000000c1000ff8
[    1.737000] riscv_fillpage: EXCEPTION: Store/AMO page fault. MCAUSE: 000000000000000f, EPC: 00000000802106aa, MTVAL: 00000000c08065d0
[    1.740000] riscv_fillpage: EXCEPTION: Store/AMO page fault. MCAUSE: 000000000000000f, EPC: 00000000c0000060, MTVAL: 0000000000000000
[    1.740000] riscv_fillpage: Virtual address not mappable: 0
[    1.740000] riscv_fault_handler: Segmentation fault in hello (PID 4: hello)
nsh> ps
  TID   PID  PPID PRI POLICY   TYPE    NPX STATE    EVENT     SIGMASK            STACK COMMAND
    0     0     0   0 FIFO     Kthread   - Ready              0000000000000000 0003024 Idle_Task
    1     0     0 100 RR       Kthread   - Waiting  Semaphore 0000000000000000 0001936 lpwork 0x80600100 0x80600180
    3     3     0 100 RR       Task      - Running            0000000000000000 0002976 /system/bin/init

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>
@hitHuang hitHuang requested review from tmedicci and yf13 as code owners July 9, 2026 03:41
@github-actions github-actions Bot added Arch: risc-v Issues related to the RISC-V (32-bit or 64-bit) architecture Size: S The size of the change in this PR is small labels Jul 9, 2026
@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown

MemBrowse Memory Report

No memory changes detected for:

@xiaoxiang781216 xiaoxiang781216 merged commit e0b4eb7 into apache:master Jul 10, 2026
30 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Arch: risc-v Issues related to the RISC-V (32-bit or 64-bit) architecture Size: S The size of the change in this PR is small

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants