xref: /optee_os/core/arch/riscv/kernel/arch_scall.c (revision 12fc37711783247b0d05fdc271ef007f4930767b)
1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright 2022-2023 NXP
4  * Copyright (c) 2014-2022, Linaro Limited
5  * Copyright (c) 2020, Arm Limited
6  */
7 
8 #include <kernel/abort.h>
9 #include <kernel/scall.h>
10 #include <kernel/thread.h>
11 #include <kernel/trace_ta.h>
12 #include <kernel/user_ta.h>
13 #include <mm/vm.h>
14 #include <riscv.h>
15 #include <types_ext.h>
16 
17 #define TA_CONTEXT_MAX_SIZE	(RISCV_XLEN_BYTES * 32)
18 
19 #ifdef CFG_UNWIND
20 
21 static void save_panic_regs_rv_ta(struct thread_specific_data *tsd,
22 				  unsigned long *pushed)
23 {
24 	tsd->abort_regs = (struct thread_abort_regs){
25 		.ra = pushed[0],
26 		.sp = (unsigned long)pushed,
27 		.gp = pushed[1],
28 		.tp = pushed[2],
29 		.t0 = pushed[3],
30 		.t1 = pushed[4],
31 		.t2 = pushed[5],
32 		.s0 = pushed[6],
33 		.s1 = pushed[7],
34 		.a0 = pushed[8],
35 		.a1 = pushed[9],
36 		.a2 = pushed[10],
37 		.a3 = pushed[11],
38 		.a4 = pushed[12],
39 		.a5 = pushed[13],
40 		.a6 = pushed[14],
41 		.a7 = pushed[15],
42 		.s2 = pushed[16],
43 		.s3 = pushed[17],
44 		.s4 = pushed[18],
45 		.s5 = pushed[19],
46 		.s6 = pushed[20],
47 		.s7 = pushed[21],
48 		.s8 = pushed[22],
49 		.s9 = pushed[23],
50 		.s10 = pushed[24],
51 		.s11 = pushed[25],
52 		.t3 = pushed[26],
53 		.t4 = pushed[27],
54 		.t5 = pushed[28],
55 		.t6 = pushed[29],
56 		.status = read_csr(CSR_XSTATUS),
57 	};
58 }
59 
60 void scall_save_panic_stack(struct thread_scall_regs *regs)
61 {
62 	struct thread_specific_data *tsd = thread_get_tsd();
63 	struct ts_session *s = ts_get_current_session();
64 	struct user_ta_ctx *utc = to_user_ta_ctx(s->ctx);
65 
66 	if (vm_check_access_rights(&utc->uctx,
67 				   TEE_MEMORY_ACCESS_READ |
68 				   TEE_MEMORY_ACCESS_WRITE,
69 				   (uaddr_t)regs->a1,
70 				   TA_CONTEXT_MAX_SIZE)) {
71 		TAMSG_RAW("");
72 		TAMSG_RAW("Can't unwind invalid user stack 0x%"PRIxUA,
73 			  (uaddr_t)regs->a1);
74 		return;
75 	}
76 
77 	tsd->abort_type = ABORT_TYPE_USER_MODE_PANIC;
78 	tsd->abort_descr = 0;
79 	tsd->abort_va = 0;
80 
81 	save_panic_regs_rv_ta(tsd, (unsigned long *)regs->a1);
82 }
83 
84 #else /* CFG_UNWIND */
85 void scall_save_panic_stack(struct thread_scall_regs *regs __unused)
86 {
87 	struct thread_specific_data *tsd = thread_get_tsd();
88 
89 	tsd->abort_type = ABORT_TYPE_USER_MODE_PANIC;
90 }
91 #endif /* CFG_UNWIND */
92