1 /*
2  * Copyright (c) 2020 BayLibre, SAS
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 /**
8  * @file
9  * @brief RISCV public error handling
10  *
11  * RISCV-specific kernel error handling interface. Included by riscv/arch.h.
12  */
13 
14 #ifndef ZEPHYR_INCLUDE_ARCH_RISCV_ERROR_H_
15 #define ZEPHYR_INCLUDE_ARCH_RISCV_ERROR_H_
16 
17 #include <arch/riscv/syscall.h>
18 #include <arch/riscv/exp.h>
19 #include <stdbool.h>
20 
21 #ifdef __cplusplus
22 extern "C" {
23 #endif
24 
25 #ifdef CONFIG_USERSPACE
26 
27 /*
28  * Kernel features like canary (software stack guard) are built
29  * with an argument to bypass the test before syscall (test if CPU
30  * is running in user or kernel) and directly execute the function.
31  * Then if this kind of code wishes to trigger a CPU exception,
32  * the implemented syscall is useless because  the function is directly
33  * called even if the CPU is running in user (which happens during
34  * sanity check). To fix that, I bypass the generated test code by writing
35  * the test myself to remove the bypass ability.
36  */
37 
38 #define ARCH_EXCEPT(reason_p)	do {			\
39 		if (k_is_user_context()) {		\
40 			arch_syscall_invoke1(reason_p,	\
41 				K_SYSCALL_USER_FAULT);	\
42 		} else {				\
43 			compiler_barrier();		\
44 			z_impl_user_fault(reason_p);	\
45 		}					\
46 		CODE_UNREACHABLE; /* LCOV_EXCL_LINE */	\
47 	} while (false)
48 #else
49 #define ARCH_EXCEPT(reason_p)	do {			\
50 		z_impl_user_fault(reason_p);		\
51 	} while (false)
52 #endif
53 
54 __syscall void user_fault(unsigned int reason);
55 
56 #include <syscalls/error.h>
57 
58 #ifdef __cplusplus
59 }
60 #endif
61 
62 #endif /* ZEPHYR_INCLUDE_ARCH_RISCV_ERROR_H_ */
63