Two problems in the same path make a contained user fault look like a kernel failure. arm64_el1_undef() dumps the words around ELR. For an exception taken from EL0, ELR is a user address, and the words around it can be in a page that is not mapped. Then the memcpy faults inside the fatal handler. That nested exception trips the DEBUGASSERT in arm64_fatal_handler(), and the fault that the user took is not reported. The ESR that tells what happened is lost. Skip the dump when the exception came from EL0. At EL1 the address is kernel code that was just fetched, so keep the dump there. arm64_fatal_handler() then reports the fault that it recovers from as "PANIC: Unhandled user exception", followed by a full register dump. But there is no panic: it sets TCB_FLAG_FORCED_CANCEL, changes ELR to _exit(SIGSEGV), and the system continues without the offending task. Print "Segmentation fault in <process> (PID n: <thread>)" instead, the same message as risc-v, and keep the register dump for the PANIC_WITH_REGS() path, which is fatal. Tested on QEMU qemu-armv8a:knsh with examples/sandbox and ostest. A user read or write of kernel memory (0x40000000) now prints: arm64_exception_handler: ESR_ELn: 0x9200000e arm64_fatal_handler: Segmentation fault in sandbox (PID 10: sandbox) arm64_fatal_handler: Reason: DABT (lower EL) - Data Abort from a ... sandbox: the offender exited with status 2816 Before this change it printed "PANIC: Unhandled user exception" and a register dump for the same recovered fault. An undefined instruction at EL0 now prints "Undefined instruction at <ELR>" without the dump, then the same segmentation fault message. The shell survives in all cases, and ostest exits with status 0 before and after this change. Assisted-by: Claude Code:claude-opus-5-5 Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com> |
||
|---|---|---|
| .github | ||
| arch | ||
| audio | ||
| binfmt | ||
| boards | ||
| cmake | ||
| crypto | ||
| Documentation | ||
| drivers | ||
| dummy | ||
| fs | ||
| graphics | ||
| include | ||
| libs | ||
| mm | ||
| net | ||
| openamp | ||
| pass1 | ||
| sched | ||
| syscall | ||
| tools | ||
| video | ||
| wireless | ||
| .asf.yaml | ||
| .codespell-ignore-lines | ||
| .codespellrc | ||
| .editorconfig | ||
| .gitignore | ||
| .gitmessage | ||
| .mcp.json | ||
| .pre-commit-config.yaml | ||
| .yamllint | ||
| AUTHORS | ||
| CMakeLists.txt | ||
| CONTRIBUTING.md | ||
| INVIOLABLES.md | ||
| Kconfig | ||
| LICENSE | ||
| Makefile | ||
| NOTICE | ||
| README.md | ||
| ReleaseNotes | ||
Apache NuttX is a real-time operating system (RTOS) with an emphasis on standards compliance and small footprint. Scalable from 8-bit to 64-bit microcontroller environments, the primary governing standards in NuttX are POSIX and ANSI standards. Additional standard APIs from Unix and other common RTOSs (such as VxWorks) are adopted for functionality not available under these standards, or for functionality that is not appropriate for deeply-embedded environments (such as fork()).
For brevity, many parts of the documentation will refer to Apache NuttX as simply NuttX.
Getting Started
First time on NuttX? Read the Getting Started guide! If you don't have a board available, NuttX has its own simulator that you can run on terminal.
Documentation
You can find the current NuttX documentation on the Documentation Page.
Alternatively, you can build the documentation yourself by following the Documentation Build Instructions.
The old NuttX documentation is still available in the Apache wiki.
Supported Boards
NuttX supports a wide variety of platforms. See the full list on the Supported Platforms page.
Contributing
If you wish to contribute to the NuttX project, read the Contributing guidelines for information on Git usage, coding standard, workflow and the NuttX principles.
License
The code in this repository is under either the Apache 2 license, or a license compatible with the Apache 2 license. See the License Page for more information.