mirror of
https://github.com/apache/nuttx.git
synced 2026-08-10 15:05:07 +00:00
arch/risc-v: kill faulting user task instead of panicking kernel
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>
This commit is contained in:
parent
6bfb85c96f
commit
41837f0699
1 changed files with 42 additions and 24 deletions
|
|
@ -83,26 +83,27 @@ static const char *g_reasons_str[RISCV_MAX_EXCEPTION + 1] =
|
|||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: riscv_exception
|
||||
* Name: riscv_fault_handler
|
||||
*
|
||||
* Description:
|
||||
* This is the exception handler.
|
||||
* Handle a fault caused by the running task. If the task is a user task
|
||||
* not currently in a syscall, kill it with SIGSEGV instead of
|
||||
* taking down the whole system. Otherwise (kernel thread, or a fault
|
||||
* while already in kernel context on behalf of a syscall) there is no
|
||||
* safe task to kill, so panic.
|
||||
*
|
||||
* Input Parameters:
|
||||
* cause - The (masked) machine cause of the exception, used for the
|
||||
* panic message only.
|
||||
* regs - A pointer to the register state at the time of the exception.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int riscv_exception(int mcause, void *regs, void *args)
|
||||
static void riscv_fault_handler(uintreg_t cause, void *regs)
|
||||
{
|
||||
#ifdef CONFIG_ARCH_KERNEL_STACK
|
||||
struct tcb_s *tcb = this_task();
|
||||
#endif
|
||||
uintreg_t cause = mcause & RISCV_IRQ_MASK;
|
||||
|
||||
_alert("EXCEPTION: %s. MCAUSE: %" PRIxREG ", EPC: %" PRIxREG
|
||||
", MTVAL: %" PRIxREG "\n",
|
||||
mcause > RISCV_MAX_EXCEPTION ? "Unknown" : g_reasons_str[cause],
|
||||
cause, READ_CSR(CSR_EPC), READ_CSR(CSR_TVAL));
|
||||
|
||||
#ifdef CONFIG_ARCH_KERNEL_STACK
|
||||
if (((tcb->flags & TCB_FLAG_TTYPE_MASK) != TCB_FLAG_TTYPE_KERNEL) &&
|
||||
((tcb->flags & TCB_FLAG_SYSCALL) == false))
|
||||
{
|
||||
|
|
@ -124,15 +125,34 @@ int riscv_exception(int mcause, void *regs, void *args)
|
|||
*/
|
||||
|
||||
running_regs()[REG_SP] = tcb->xcp.ktopstk;
|
||||
return;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
_alert("PANIC!!! Exception = %" PRIxREG "\n", cause);
|
||||
up_irq_save();
|
||||
up_set_interrupt_context(true);
|
||||
PANIC_WITH_REGS("panic", regs);
|
||||
}
|
||||
|
||||
_alert("PANIC!!! Exception = %" PRIxREG "\n", cause);
|
||||
up_irq_save();
|
||||
up_set_interrupt_context(true);
|
||||
PANIC_WITH_REGS("panic", regs);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: riscv_exception
|
||||
*
|
||||
* Description:
|
||||
* This is the exception handler.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int riscv_exception(int mcause, void *regs, void *args)
|
||||
{
|
||||
uintreg_t cause = mcause & RISCV_IRQ_MASK;
|
||||
|
||||
_alert("EXCEPTION: %s. MCAUSE: %" PRIxREG ", EPC: %" PRIxREG
|
||||
", MTVAL: %" PRIxREG "\n",
|
||||
mcause > RISCV_MAX_EXCEPTION ? "Unknown" : g_reasons_str[cause],
|
||||
cause, READ_CSR(CSR_EPC), READ_CSR(CSR_TVAL));
|
||||
|
||||
riscv_fault_handler(cause, regs);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -200,7 +220,7 @@ int riscv_fillpage(int mcause, void *regs, void *args)
|
|||
}
|
||||
else
|
||||
{
|
||||
_alert("PANIC!!! virtual address not mappable: %" PRIxPTR "\n", vaddr);
|
||||
_alert("Virtual address not mappable: %" PRIxPTR "\n", vaddr);
|
||||
goto access_fault;
|
||||
}
|
||||
|
||||
|
|
@ -242,7 +262,7 @@ int riscv_fillpage(int mcause, void *regs, void *args)
|
|||
|
||||
if (mmu_ln_getentry(ARCH_PGT_MAX_LEVELS, ptlast, vaddr) & PTE_VALID)
|
||||
{
|
||||
_alert("PANIC!!! page already mapped, permission violation: %"
|
||||
_alert("Page already mapped, permission violation: %"
|
||||
PRIxPTR "\n", vaddr);
|
||||
goto access_fault;
|
||||
}
|
||||
|
|
@ -264,10 +284,8 @@ int riscv_fillpage(int mcause, void *regs, void *args)
|
|||
return 0;
|
||||
|
||||
access_fault:
|
||||
up_irq_save();
|
||||
up_set_interrupt_context(true);
|
||||
PANIC_WITH_REGS("panic", regs);
|
||||
return -EINVAL;
|
||||
riscv_fault_handler(cause, regs);
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_PAGING */
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue