1 /* 2 * Copyright (c) 2015, Linaro Limited 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, 9 * this list of conditions and the following disclaimer. 10 * 11 * 2. Redistributions in binary form must reproduce the above copyright notice, 12 * this list of conditions and the following disclaimer in the documentation 13 * and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 19 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 * POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28 #include <kernel/abort.h> 29 #include <kernel/misc.h> 30 #include <kernel/tee_ta_manager.h> 31 #include <kernel/panic.h> 32 #include <mm/core_mmu.h> 33 #include <mm/tee_pager.h> 34 #include <trace.h> 35 #include <arm.h> 36 37 enum fault_type { 38 FAULT_TYPE_USER_TA_PANIC, 39 FAULT_TYPE_PAGEABLE, 40 FAULT_TYPE_IGNORE, 41 }; 42 43 static __unused const char *abort_type_to_str(uint32_t abort_type) 44 { 45 if (abort_type == ABORT_TYPE_DATA) 46 return "data"; 47 if (abort_type == ABORT_TYPE_PREFETCH) 48 return "prefetch"; 49 return "undef"; 50 } 51 52 static __unused void print_detailed_abort(struct abort_info *ai __unused, 53 const char *ctx __unused) 54 { 55 EMSG_RAW("\n"); 56 EMSG_RAW("%s %s-abort at address 0x%" PRIxVA "\n", 57 ctx, abort_type_to_str(ai->abort_type), ai->va); 58 #ifdef ARM32 59 EMSG_RAW(" fsr 0x%08x ttbr0 0x%08x ttbr1 0x%08x cidr 0x%X\n", 60 ai->fault_descr, read_ttbr0(), read_ttbr1(), 61 read_contextidr()); 62 EMSG_RAW(" cpu #%zu cpsr 0x%08x\n", 63 get_core_pos(), ai->regs->spsr); 64 EMSG_RAW(" r0 0x%08x r4 0x%08x r8 0x%08x r12 0x%08x\n", 65 ai->regs->r0, ai->regs->r4, ai->regs->r8, ai->regs->ip); 66 EMSG_RAW(" r1 0x%08x r5 0x%08x r9 0x%08x sp 0x%08x\n", 67 ai->regs->r1, ai->regs->r5, ai->regs->r9, 68 read_mode_sp(ai->regs->spsr & CPSR_MODE_MASK)); 69 EMSG_RAW(" r2 0x%08x r6 0x%08x r10 0x%08x lr 0x%08x\n", 70 ai->regs->r2, ai->regs->r6, ai->regs->r10, 71 read_mode_lr(ai->regs->spsr & CPSR_MODE_MASK)); 72 EMSG_RAW(" r3 0x%08x r7 0x%08x r11 0x%08x pc 0x%08x\n", 73 ai->regs->r3, ai->regs->r7, ai->regs->r11, ai->pc); 74 #endif /*ARM32*/ 75 #ifdef ARM64 76 EMSG_RAW(" esr 0x%08x ttbr0 0x%08" PRIx64 " ttbr1 0x%08" PRIx64 " cidr 0x%X\n", 77 ai->fault_descr, read_ttbr0_el1(), read_ttbr1_el1(), 78 read_contextidr_el1()); 79 EMSG_RAW(" cpu #%zu cpsr 0x%08x\n", 80 get_core_pos(), (uint32_t)ai->regs->spsr); 81 EMSG_RAW("x0 %016" PRIx64 " x1 %016" PRIx64, 82 ai->regs->x0, ai->regs->x1); 83 EMSG_RAW("x2 %016" PRIx64 " x3 %016" PRIx64, 84 ai->regs->x2, ai->regs->x3); 85 EMSG_RAW("x4 %016" PRIx64 " x5 %016" PRIx64, 86 ai->regs->x4, ai->regs->x5); 87 EMSG_RAW("x6 %016" PRIx64 " x7 %016" PRIx64, 88 ai->regs->x6, ai->regs->x7); 89 EMSG_RAW("x8 %016" PRIx64 " x9 %016" PRIx64, 90 ai->regs->x8, ai->regs->x9); 91 EMSG_RAW("x10 %016" PRIx64 " x11 %016" PRIx64, 92 ai->regs->x10, ai->regs->x11); 93 EMSG_RAW("x12 %016" PRIx64 " x13 %016" PRIx64, 94 ai->regs->x12, ai->regs->x13); 95 EMSG_RAW("x14 %016" PRIx64 " x15 %016" PRIx64, 96 ai->regs->x14, ai->regs->x15); 97 EMSG_RAW("x16 %016" PRIx64 " x17 %016" PRIx64, 98 ai->regs->x16, ai->regs->x17); 99 EMSG_RAW("x18 %016" PRIx64 " x19 %016" PRIx64, 100 ai->regs->x18, ai->regs->x19); 101 EMSG_RAW("x20 %016" PRIx64 " x21 %016" PRIx64, 102 ai->regs->x20, ai->regs->x21); 103 EMSG_RAW("x22 %016" PRIx64 " x23 %016" PRIx64, 104 ai->regs->x22, ai->regs->x23); 105 EMSG_RAW("x24 %016" PRIx64 " x25 %016" PRIx64, 106 ai->regs->x24, ai->regs->x25); 107 EMSG_RAW("x26 %016" PRIx64 " x27 %016" PRIx64, 108 ai->regs->x26, ai->regs->x27); 109 EMSG_RAW("x28 %016" PRIx64 " x29 %016" PRIx64, 110 ai->regs->x28, ai->regs->x29); 111 EMSG_RAW("x30 %016" PRIx64 " elr %016" PRIx64, 112 ai->regs->x30, ai->regs->elr); 113 EMSG_RAW("sp_el0 %016" PRIx64, ai->regs->sp_el0); 114 #endif /*ARM64*/ 115 } 116 117 static void print_user_abort(struct abort_info *ai __unused) 118 { 119 #ifdef CFG_TEE_CORE_TA_TRACE 120 print_detailed_abort(ai, "user TA"); 121 tee_ta_dump_current(); 122 #endif 123 } 124 125 void abort_print(struct abort_info *ai __unused) 126 { 127 #if (TRACE_LEVEL >= TRACE_INFO) 128 print_detailed_abort(ai, "core"); 129 #endif /*TRACE_LEVEL >= TRACE_DEBUG*/ 130 } 131 132 void abort_print_error(struct abort_info *ai __unused) 133 { 134 #if (TRACE_LEVEL >= TRACE_INFO) 135 /* full verbose log at DEBUG level */ 136 print_detailed_abort(ai, "core"); 137 #else 138 #ifdef ARM32 139 EMSG("%s-abort at 0x%" PRIxVA "\n" 140 "FSR 0x%x PC 0x%x TTBR0 0x%X CONTEXIDR 0x%X\n" 141 "CPUID 0x%x CPSR 0x%x (read from SPSR)", 142 abort_type_to_str(ai->abort_type), 143 ai->va, ai->fault_descr, ai->pc, read_ttbr0(), read_contextidr(), 144 read_mpidr(), read_spsr()); 145 #endif /*ARM32*/ 146 #ifdef ARM64 147 EMSG("%s-abort at 0x%" PRIxVA "\n" 148 "ESR 0x%x PC 0x%x TTBR0 0x%" PRIx64 " CONTEXIDR 0x%X\n" 149 "CPUID 0x%" PRIx64 " CPSR 0x%x (read from SPSR)", 150 abort_type_to_str(ai->abort_type), 151 ai->va, ai->fault_descr, ai->pc, read_ttbr0_el1(), 152 read_contextidr_el1(), 153 read_mpidr_el1(), (uint32_t)ai->regs->spsr); 154 #endif /*ARM64*/ 155 #endif /*TRACE_LEVEL >= TRACE_DEBUG*/ 156 } 157 158 #ifdef ARM32 159 static void set_abort_info(uint32_t abort_type, struct thread_abort_regs *regs, 160 struct abort_info *ai) 161 { 162 switch (abort_type) { 163 case ABORT_TYPE_DATA: 164 ai->fault_descr = read_dfsr(); 165 ai->va = read_dfar(); 166 break; 167 case ABORT_TYPE_PREFETCH: 168 ai->fault_descr = read_ifsr(); 169 ai->va = read_ifar(); 170 break; 171 default: 172 ai->fault_descr = 0; 173 ai->va = regs->elr; 174 break; 175 } 176 ai->abort_type = abort_type; 177 ai->pc = regs->elr; 178 ai->regs = regs; 179 } 180 #endif /*ARM32*/ 181 182 #ifdef ARM64 183 static void set_abort_info(uint32_t abort_type __unused, 184 struct thread_abort_regs *regs, struct abort_info *ai) 185 { 186 ai->fault_descr = read_esr_el1(); 187 switch ((ai->fault_descr >> ESR_EC_SHIFT) & ESR_EC_MASK) { 188 case ESR_EC_IABT_EL0: 189 case ESR_EC_IABT_EL1: 190 ai->abort_type = ABORT_TYPE_PREFETCH; 191 ai->va = read_far_el1(); 192 break; 193 case ESR_EC_DABT_EL0: 194 case ESR_EC_DABT_EL1: 195 case ESR_EC_SP_ALIGN: 196 ai->abort_type = ABORT_TYPE_DATA; 197 ai->va = read_far_el1(); 198 break; 199 default: 200 ai->abort_type = ABORT_TYPE_UNDEF; 201 ai->va = regs->elr; 202 } 203 ai->pc = regs->elr; 204 ai->regs = regs; 205 } 206 #endif /*ARM64*/ 207 208 #ifdef ARM32 209 static void handle_user_ta_panic(struct abort_info *ai) 210 { 211 /* 212 * It was a user exception, stop user execution and return 213 * to TEE Core. 214 */ 215 ai->regs->r0 = TEE_ERROR_TARGET_DEAD; 216 ai->regs->r1 = true; 217 ai->regs->r2 = 0xdeadbeef; 218 ai->regs->elr = (uint32_t)thread_unwind_user_mode; 219 ai->regs->spsr = read_cpsr(); 220 ai->regs->spsr &= ~CPSR_MODE_MASK; 221 ai->regs->spsr |= CPSR_MODE_SVC; 222 ai->regs->spsr &= ~CPSR_FIA; 223 ai->regs->spsr |= read_spsr() & CPSR_FIA; 224 /* Select Thumb or ARM mode */ 225 if (ai->regs->elr & 1) 226 ai->regs->spsr |= CPSR_T; 227 else 228 ai->regs->spsr &= ~CPSR_T; 229 } 230 #endif /*ARM32*/ 231 232 #ifdef ARM64 233 static void handle_user_ta_panic(struct abort_info *ai) 234 { 235 uint32_t daif; 236 237 /* 238 * It was a user exception, stop user execution and return 239 * to TEE Core. 240 */ 241 ai->regs->x0 = TEE_ERROR_TARGET_DEAD; 242 ai->regs->x1 = true; 243 ai->regs->x2 = 0xdeadbeef; 244 ai->regs->elr = (vaddr_t)thread_unwind_user_mode; 245 ai->regs->sp_el0 = thread_get_saved_thread_sp(); 246 247 daif = (ai->regs->spsr >> SPSR_32_AIF_SHIFT) & SPSR_32_AIF_MASK; 248 /* XXX what about DAIF_D? */ 249 ai->regs->spsr = SPSR_64(SPSR_64_MODE_EL1, SPSR_64_MODE_SP_EL0, daif); 250 } 251 #endif /*ARM64*/ 252 253 #ifdef ARM32 254 /* Returns true if the exception originated from user mode */ 255 static bool is_user_exception(struct abort_info *ai) 256 { 257 return (ai->regs->spsr & ARM32_CPSR_MODE_MASK) == ARM32_CPSR_MODE_USR; 258 } 259 #endif /*ARM32*/ 260 261 #ifdef ARM64 262 /* Returns true if the exception originated from user mode */ 263 static bool is_user_exception(struct abort_info *ai) 264 { 265 uint32_t spsr = ai->regs->spsr; 266 267 if (spsr & (SPSR_MODE_RW_32 << SPSR_MODE_RW_SHIFT)) 268 return true; 269 if (((spsr >> SPSR_64_MODE_EL_SHIFT) & SPSR_64_MODE_EL_MASK) == 270 SPSR_64_MODE_EL0) 271 return true; 272 return false; 273 } 274 #endif /*ARM64*/ 275 276 #ifdef ARM32 277 /* Returns true if the exception originated from abort mode */ 278 static bool is_abort_in_abort_handler(struct abort_info *ai) 279 { 280 return (ai->regs->spsr & ARM32_CPSR_MODE_MASK) == ARM32_CPSR_MODE_ABT; 281 } 282 #endif /*ARM32*/ 283 284 #ifdef ARM64 285 /* Returns true if the exception originated from abort mode */ 286 static bool is_abort_in_abort_handler(struct abort_info *ai __unused) 287 { 288 return false; 289 } 290 #endif /*ARM64*/ 291 292 static enum fault_type get_fault_type(struct abort_info *ai) 293 { 294 if (is_user_exception(ai)) { 295 print_user_abort(ai); 296 DMSG("[abort] abort in User mode (TA will panic)"); 297 return FAULT_TYPE_USER_TA_PANIC; 298 } 299 300 if (is_abort_in_abort_handler(ai)) { 301 abort_print_error(ai); 302 EMSG("[abort] abort in abort handler (trap CPU)"); 303 panic(); 304 } 305 306 if (ai->abort_type == ABORT_TYPE_UNDEF) { 307 abort_print_error(ai); 308 EMSG("[abort] undefined abort (trap CPU)"); 309 panic(); 310 } 311 312 switch (core_mmu_get_fault_type(ai->fault_descr)) { 313 case CORE_MMU_FAULT_ALIGNMENT: 314 abort_print_error(ai); 315 EMSG("[abort] alignement fault! (trap CPU)"); 316 panic(); 317 break; 318 319 case CORE_MMU_FAULT_ACCESS_BIT: 320 abort_print_error(ai); 321 EMSG("[abort] access bit fault! (trap CPU)"); 322 panic(); 323 break; 324 325 case CORE_MMU_FAULT_DEBUG_EVENT: 326 abort_print(ai); 327 DMSG("[abort] Ignoring debug event!"); 328 return FAULT_TYPE_IGNORE; 329 330 case CORE_MMU_FAULT_TRANSLATION: 331 case CORE_MMU_FAULT_WRITE_PERMISSION: 332 case CORE_MMU_FAULT_READ_PERMISSION: 333 return FAULT_TYPE_PAGEABLE; 334 335 case CORE_MMU_FAULT_ASYNC_EXTERNAL: 336 abort_print(ai); 337 DMSG("[abort] Ignoring async external abort!"); 338 return FAULT_TYPE_IGNORE; 339 340 case CORE_MMU_FAULT_OTHER: 341 default: 342 abort_print(ai); 343 DMSG("[abort] Unhandled fault!"); 344 return FAULT_TYPE_IGNORE; 345 } 346 } 347 348 void abort_handler(uint32_t abort_type, struct thread_abort_regs *regs) 349 { 350 struct abort_info ai; 351 352 set_abort_info(abort_type, regs, &ai); 353 354 switch (get_fault_type(&ai)) { 355 case FAULT_TYPE_IGNORE: 356 break; 357 case FAULT_TYPE_USER_TA_PANIC: 358 handle_user_ta_panic(&ai); 359 break; 360 case FAULT_TYPE_PAGEABLE: 361 default: 362 tee_pager_handle_fault(&ai); 363 break; 364 } 365 } 366