1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Copyright (c) 2014-2022, Linaro Limited 4 * Copyright (c) 2020, Arm Limited 5 */ 6 7 #include <kernel/abort.h> 8 #include <kernel/scall.h> 9 #include <kernel/thread.h> 10 #include <kernel/trace_ta.h> 11 #include <kernel/user_access.h> 12 #include <kernel/user_ta.h> 13 #include <mm/vm.h> 14 #include <types_ext.h> 15 16 #define TA32_CONTEXT_MAX_SIZE (14 * sizeof(uint32_t)) 17 #define TA64_CONTEXT_MAX_SIZE (2 * sizeof(uint64_t)) 18 19 #ifdef CFG_UNWIND 20 #ifdef ARM32 21 /* Get register values pushed onto the stack by _utee_panic() */ 22 static void save_panic_regs_a32_ta(struct thread_specific_data *tsd, 23 uint32_t *pushed) 24 { 25 tsd->abort_regs = (struct thread_abort_regs){ 26 .elr = pushed[0], 27 .r0 = pushed[1], 28 .r1 = pushed[2], 29 .r2 = pushed[3], 30 .r3 = pushed[4], 31 .r4 = pushed[5], 32 .r5 = pushed[6], 33 .r6 = pushed[7], 34 .r7 = pushed[8], 35 .r8 = pushed[9], 36 .r9 = pushed[10], 37 .r10 = pushed[11], 38 .r11 = pushed[12], 39 .usr_sp = (uint32_t)pushed, 40 .usr_lr = pushed[13], 41 .spsr = read_spsr(), 42 }; 43 } 44 45 void scall_save_panic_stack(struct thread_scall_regs *regs) 46 { 47 struct thread_specific_data *tsd = thread_get_tsd(); 48 struct ts_session *s = ts_get_current_session(); 49 struct user_ta_ctx *utc = to_user_ta_ctx(s->ctx); 50 51 tsd->abort_type = ABORT_TYPE_USER_MODE_PANIC; 52 tsd->abort_descr = 0; 53 tsd->abort_va = 0; 54 55 if (vm_check_access_rights(&utc->uctx, 56 TEE_MEMORY_ACCESS_READ | 57 TEE_MEMORY_ACCESS_WRITE, 58 (uaddr_t)regs->r1, TA32_CONTEXT_MAX_SIZE)) { 59 TAMSG_RAW(""); 60 TAMSG_RAW("Can't unwind invalid user stack 0x%"PRIxUA, 61 (uaddr_t)regs->r1); 62 return; 63 } 64 65 save_panic_regs_a32_ta(tsd, (uint32_t *)regs->r1); 66 } 67 #endif /*ARM32*/ 68 69 #ifdef ARM64 70 /* Get register values pushed onto the stack by _utee_panic() (32-bit TA) */ 71 static void save_panic_regs_a32_ta(struct thread_specific_data *tsd, 72 uint32_t *pushed) 73 { 74 tsd->abort_regs = (struct thread_abort_regs){ 75 .elr = pushed[0], 76 .x0 = pushed[1], 77 .x1 = pushed[2], 78 .x2 = pushed[3], 79 .x3 = pushed[4], 80 .x4 = pushed[5], 81 .x5 = pushed[6], 82 .x6 = pushed[7], 83 .x7 = pushed[8], 84 .x8 = pushed[9], 85 .x9 = pushed[10], 86 .x10 = pushed[11], 87 .x11 = pushed[12], 88 .x13 = (uint64_t)pushed, 89 .x14 = pushed[13], 90 .spsr = (SPSR_MODE_RW_32 << SPSR_MODE_RW_SHIFT), 91 }; 92 } 93 94 /* Get register values pushed onto the stack by _utee_panic() (64-bit TA) */ 95 static void save_panic_regs_a64_ta(struct thread_specific_data *tsd, 96 uint64_t *pushed) 97 { 98 TEE_Result res = TEE_SUCCESS; 99 uint64_t x29 = 0; 100 uint64_t elr = 0; 101 102 res = GET_USER_SCALAR(x29, &pushed[0]); 103 if (res) 104 x29 = 0; 105 106 res = GET_USER_SCALAR(elr, &pushed[1]); 107 if (res) 108 elr = 0; 109 110 tsd->abort_regs = (struct thread_abort_regs){ 111 .x29 = x29, 112 .elr = elr, 113 .spsr = (SPSR_64_MODE_EL0 << SPSR_64_MODE_EL_SHIFT), 114 }; 115 } 116 117 void scall_save_panic_stack(struct thread_scall_regs *regs) 118 { 119 struct thread_specific_data *tsd = thread_get_tsd(); 120 struct ts_session *s = ts_get_current_session(); 121 struct user_ta_ctx *utc = to_user_ta_ctx(s->ctx); 122 123 if (vm_check_access_rights(&utc->uctx, 124 TEE_MEMORY_ACCESS_READ | 125 TEE_MEMORY_ACCESS_WRITE, 126 (uaddr_t)regs->x1, 127 utc->uctx.is_32bit ? 128 TA32_CONTEXT_MAX_SIZE : 129 TA64_CONTEXT_MAX_SIZE)) { 130 TAMSG_RAW(""); 131 TAMSG_RAW("Can't unwind invalid user stack 0x%"PRIxUA, 132 (uaddr_t)regs->x1); 133 return; 134 } 135 136 tsd->abort_type = ABORT_TYPE_USER_MODE_PANIC; 137 tsd->abort_descr = 0; 138 tsd->abort_va = 0; 139 140 if (utc->uctx.is_32bit) 141 save_panic_regs_a32_ta(tsd, (uint32_t *)regs->x1); 142 else 143 save_panic_regs_a64_ta(tsd, (uint64_t *)regs->x1); 144 } 145 #endif /*ARM64*/ 146 147 #else /* CFG_UNWIND */ 148 void scall_save_panic_stack(struct thread_scall_regs *regs __unused) 149 { 150 struct thread_specific_data *tsd = thread_get_tsd(); 151 152 tsd->abort_type = ABORT_TYPE_USER_MODE_PANIC; 153 } 154 #endif /* CFG_UNWIND */ 155