zephyr/include/arch/riscv/error.h
Mark Holden 7803a4e590 arch: riscv: ARCH_EXCEPT macro
Enable ARCH_EXCEPT macro for non-usermode scenario for RISC-V
Macro will now raise an illegal instruction exception so that mepc will
hold expected value in exception handler, and generated coredump can
reconstruct the failing stack

Coredump tests running on renode (for RISC-V) can now utilize fatal error
path through k_panic

Signed-off-by: Mark Holden <mholden@fb.com>
2022-01-01 07:38:20 -05:00

73 lines
1.9 KiB
C

/*
* Copyright (c) 2020 BayLibre, SAS
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
* @brief RISCV public error handling
*
* RISCV-specific kernel error handling interface. Included by riscv/arch.h.
*/
#ifndef ZEPHYR_INCLUDE_ARCH_RISCV_ERROR_H_
#define ZEPHYR_INCLUDE_ARCH_RISCV_ERROR_H_
#include <arch/riscv/syscall.h>
#include <arch/riscv/exp.h>
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifdef CONFIG_USERSPACE
/*
* Kernel features like canary (software stack guard) are built
* with an argument to bypass the test before syscall (test if CPU
* is running in user or kernel) and directly execute the function.
* Then if this kind of code wishes to trigger a CPU exception,
* the implemented syscall is useless because the function is directly
* called even if the CPU is running in user (which happens during
* sanity check). To fix that, I bypass the generated test code by writing
* the test myself to remove the bypass ability.
*/
#define ARCH_EXCEPT(reason_p) do { \
if (k_is_user_context()) { \
arch_syscall_invoke1(reason_p, \
K_SYSCALL_USER_FAULT); \
} else { \
compiler_barrier(); \
z_impl_user_fault(reason_p); \
} \
CODE_UNREACHABLE; /* LCOV_EXCL_LINE */ \
} while (false)
#else
/*
* Raise an illegal instruction exception so that mepc will hold expected value in
* exception handler, and generated coredump can reconstruct the failing stack.
* Store reason_p in register t6, marker in t5
*/
#define ARCH_EXCEPT_MARKER 0x00DEAD00
#define ARCH_EXCEPT(reason_p) do { \
__asm__ volatile("addi t5, %[marker], 0" \
: : [marker] "r" (ARCH_EXCEPT_MARKER)); \
__asm__ volatile("addi t6, %[reason], 0" \
: : [reason] "r" (reason_p)); \
__asm__ volatile("unimp"); \
} while (false)
#endif
__syscall void user_fault(unsigned int reason);
#include <syscalls/error.h>
#ifdef __cplusplus
}
#endif
#endif /* ZEPHYR_INCLUDE_ARCH_RISCV_ERROR_H_ */