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