xref: /optee_os/core/arch/riscv/kernel/arch_scall.c (revision e2ec831cb07ed0099535c7c140cb6338aa62816a)
1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright (c) 2023 Andes Technology Corporation
4  * Copyright 2022-2023 NXP
5  * Copyright (c) 2014-2022, Linaro Limited
6  * Copyright (c) 2020, Arm Limited
7  */
8 
9 #include <kernel/abort.h>
10 #include <kernel/scall.h>
11 #include <kernel/thread.h>
12 #include <kernel/trace_ta.h>
13 #include <kernel/user_ta.h>
14 #include <mm/vm.h>
15 #include <riscv.h>
16 #include <types_ext.h>
17 
18 #define TA_CONTEXT_MAX_SIZE	(RISCV_XLEN_BYTES * 32)
19 
20 #ifdef CFG_UNWIND
21 
22 /* Get register values pushed onto the stack by _utee_panic() */
23 static void save_panic_regs_rv_ta(struct thread_specific_data *tsd,
24 				  unsigned long *pushed)
25 {
26 	tsd->abort_regs = (struct thread_abort_regs){
27 		.sp = (unsigned long)pushed,
28 #if defined(RV32)
29 		.s0 = pushed[2],
30 		.epc = pushed[3],
31 #elif defined(RV64)
32 		.s0 = pushed[0],
33 		.epc = pushed[1],
34 #endif
35 	};
36 }
37 
38 void scall_save_panic_stack(struct thread_scall_regs *regs)
39 {
40 	struct thread_specific_data *tsd = thread_get_tsd();
41 	struct ts_session *s = ts_get_current_session();
42 	struct user_ta_ctx *utc = to_user_ta_ctx(s->ctx);
43 
44 	if (vm_check_access_rights(&utc->uctx,
45 				   TEE_MEMORY_ACCESS_READ |
46 				   TEE_MEMORY_ACCESS_WRITE,
47 				   (uaddr_t)regs->a1,
48 				   TA_CONTEXT_MAX_SIZE)) {
49 		TAMSG_RAW("");
50 		TAMSG_RAW("Can't unwind invalid user stack 0x%"PRIxUA,
51 			  (uaddr_t)regs->a1);
52 		return;
53 	}
54 
55 	tsd->abort_type = ABORT_TYPE_USER_MODE_PANIC;
56 	tsd->abort_descr = 0;
57 	tsd->abort_va = 0;
58 
59 	save_panic_regs_rv_ta(tsd, (unsigned long *)regs->a1);
60 }
61 
62 #else /* CFG_UNWIND */
63 void scall_save_panic_stack(struct thread_scall_regs *regs __unused)
64 {
65 	struct thread_specific_data *tsd = thread_get_tsd();
66 
67 	tsd->abort_type = ABORT_TYPE_USER_MODE_PANIC;
68 }
69 #endif /* CFG_UNWIND */
70