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 <kernel/user_ta.h> 33 #include <mm/core_mmu.h> 34 #include <mm/tee_pager.h> 35 #include <tee/tee_svc.h> 36 #include <trace.h> 37 #include <arm.h> 38 39 enum fault_type { 40 FAULT_TYPE_USER_TA_PANIC, 41 FAULT_TYPE_USER_TA_VFP, 42 FAULT_TYPE_PAGEABLE, 43 FAULT_TYPE_IGNORE, 44 }; 45 46 static __maybe_unused const char *abort_type_to_str(uint32_t abort_type) 47 { 48 if (abort_type == ABORT_TYPE_DATA) 49 return "data"; 50 if (abort_type == ABORT_TYPE_PREFETCH) 51 return "prefetch"; 52 return "undef"; 53 } 54 55 static __maybe_unused void print_detailed_abort( 56 struct abort_info *ai __maybe_unused, 57 const char *ctx __maybe_unused) 58 { 59 EMSG_RAW("\n"); 60 EMSG_RAW("%s %s-abort at address 0x%" PRIxVA "\n", 61 ctx, abort_type_to_str(ai->abort_type), ai->va); 62 #ifdef ARM32 63 EMSG_RAW(" fsr 0x%08x ttbr0 0x%08x ttbr1 0x%08x cidr 0x%X\n", 64 ai->fault_descr, read_ttbr0(), read_ttbr1(), 65 read_contextidr()); 66 EMSG_RAW(" cpu #%zu cpsr 0x%08x\n", 67 get_core_pos(), ai->regs->spsr); 68 EMSG_RAW(" r0 0x%08x r4 0x%08x r8 0x%08x r12 0x%08x\n", 69 ai->regs->r0, ai->regs->r4, ai->regs->r8, ai->regs->ip); 70 EMSG_RAW(" r1 0x%08x r5 0x%08x r9 0x%08x sp 0x%08x\n", 71 ai->regs->r1, ai->regs->r5, ai->regs->r9, 72 read_mode_sp(ai->regs->spsr & CPSR_MODE_MASK)); 73 EMSG_RAW(" r2 0x%08x r6 0x%08x r10 0x%08x lr 0x%08x\n", 74 ai->regs->r2, ai->regs->r6, ai->regs->r10, 75 read_mode_lr(ai->regs->spsr & CPSR_MODE_MASK)); 76 EMSG_RAW(" r3 0x%08x r7 0x%08x r11 0x%08x pc 0x%08x\n", 77 ai->regs->r3, ai->regs->r7, ai->regs->r11, ai->pc); 78 #endif /*ARM32*/ 79 #ifdef ARM64 80 EMSG_RAW(" esr 0x%08x ttbr0 0x%08" PRIx64 " ttbr1 0x%08" PRIx64 " cidr 0x%X\n", 81 ai->fault_descr, read_ttbr0_el1(), read_ttbr1_el1(), 82 read_contextidr_el1()); 83 EMSG_RAW(" cpu #%zu cpsr 0x%08x\n", 84 get_core_pos(), (uint32_t)ai->regs->spsr); 85 EMSG_RAW("x0 %016" PRIx64 " x1 %016" PRIx64, 86 ai->regs->x0, ai->regs->x1); 87 EMSG_RAW("x2 %016" PRIx64 " x3 %016" PRIx64, 88 ai->regs->x2, ai->regs->x3); 89 EMSG_RAW("x4 %016" PRIx64 " x5 %016" PRIx64, 90 ai->regs->x4, ai->regs->x5); 91 EMSG_RAW("x6 %016" PRIx64 " x7 %016" PRIx64, 92 ai->regs->x6, ai->regs->x7); 93 EMSG_RAW("x8 %016" PRIx64 " x9 %016" PRIx64, 94 ai->regs->x8, ai->regs->x9); 95 EMSG_RAW("x10 %016" PRIx64 " x11 %016" PRIx64, 96 ai->regs->x10, ai->regs->x11); 97 EMSG_RAW("x12 %016" PRIx64 " x13 %016" PRIx64, 98 ai->regs->x12, ai->regs->x13); 99 EMSG_RAW("x14 %016" PRIx64 " x15 %016" PRIx64, 100 ai->regs->x14, ai->regs->x15); 101 EMSG_RAW("x16 %016" PRIx64 " x17 %016" PRIx64, 102 ai->regs->x16, ai->regs->x17); 103 EMSG_RAW("x18 %016" PRIx64 " x19 %016" PRIx64, 104 ai->regs->x18, ai->regs->x19); 105 EMSG_RAW("x20 %016" PRIx64 " x21 %016" PRIx64, 106 ai->regs->x20, ai->regs->x21); 107 EMSG_RAW("x22 %016" PRIx64 " x23 %016" PRIx64, 108 ai->regs->x22, ai->regs->x23); 109 EMSG_RAW("x24 %016" PRIx64 " x25 %016" PRIx64, 110 ai->regs->x24, ai->regs->x25); 111 EMSG_RAW("x26 %016" PRIx64 " x27 %016" PRIx64, 112 ai->regs->x26, ai->regs->x27); 113 EMSG_RAW("x28 %016" PRIx64 " x29 %016" PRIx64, 114 ai->regs->x28, ai->regs->x29); 115 EMSG_RAW("x30 %016" PRIx64 " elr %016" PRIx64, 116 ai->regs->x30, ai->regs->elr); 117 EMSG_RAW("sp_el0 %016" PRIx64, ai->regs->sp_el0); 118 #endif /*ARM64*/ 119 } 120 121 static void print_user_abort(struct abort_info *ai __maybe_unused) 122 { 123 #ifdef CFG_TEE_CORE_TA_TRACE 124 print_detailed_abort(ai, "user TA"); 125 tee_ta_dump_current(); 126 #endif 127 } 128 129 void abort_print(struct abort_info *ai __maybe_unused) 130 { 131 #if (TRACE_LEVEL >= TRACE_INFO) 132 print_detailed_abort(ai, "core"); 133 #endif /*TRACE_LEVEL >= TRACE_DEBUG*/ 134 } 135 136 void abort_print_error(struct abort_info *ai __maybe_unused) 137 { 138 #if (TRACE_LEVEL >= TRACE_INFO) 139 /* full verbose log at DEBUG level */ 140 print_detailed_abort(ai, "core"); 141 #else 142 #ifdef ARM32 143 EMSG("%s-abort at 0x%" PRIxVA "\n" 144 "FSR 0x%x PC 0x%x TTBR0 0x%X CONTEXIDR 0x%X\n" 145 "CPUID 0x%x CPSR 0x%x (read from SPSR)", 146 abort_type_to_str(ai->abort_type), 147 ai->va, ai->fault_descr, ai->pc, read_ttbr0(), read_contextidr(), 148 read_mpidr(), read_spsr()); 149 #endif /*ARM32*/ 150 #ifdef ARM64 151 EMSG("%s-abort at 0x%" PRIxVA "\n" 152 "ESR 0x%x PC 0x%x TTBR0 0x%" PRIx64 " CONTEXIDR 0x%X\n" 153 "CPUID 0x%" PRIx64 " CPSR 0x%x (read from SPSR)", 154 abort_type_to_str(ai->abort_type), 155 ai->va, ai->fault_descr, ai->pc, read_ttbr0_el1(), 156 read_contextidr_el1(), 157 read_mpidr_el1(), (uint32_t)ai->regs->spsr); 158 #endif /*ARM64*/ 159 #endif /*TRACE_LEVEL >= TRACE_DEBUG*/ 160 } 161 162 #ifdef ARM32 163 static void set_abort_info(uint32_t abort_type, struct thread_abort_regs *regs, 164 struct abort_info *ai) 165 { 166 switch (abort_type) { 167 case ABORT_TYPE_DATA: 168 ai->fault_descr = read_dfsr(); 169 ai->va = read_dfar(); 170 break; 171 case ABORT_TYPE_PREFETCH: 172 ai->fault_descr = read_ifsr(); 173 ai->va = read_ifar(); 174 break; 175 default: 176 ai->fault_descr = 0; 177 ai->va = regs->elr; 178 break; 179 } 180 ai->abort_type = abort_type; 181 ai->pc = regs->elr; 182 ai->regs = regs; 183 } 184 #endif /*ARM32*/ 185 186 #ifdef ARM64 187 static void set_abort_info(uint32_t abort_type __unused, 188 struct thread_abort_regs *regs, struct abort_info *ai) 189 { 190 ai->fault_descr = read_esr_el1(); 191 switch ((ai->fault_descr >> ESR_EC_SHIFT) & ESR_EC_MASK) { 192 case ESR_EC_IABT_EL0: 193 case ESR_EC_IABT_EL1: 194 ai->abort_type = ABORT_TYPE_PREFETCH; 195 ai->va = read_far_el1(); 196 break; 197 case ESR_EC_DABT_EL0: 198 case ESR_EC_DABT_EL1: 199 case ESR_EC_SP_ALIGN: 200 ai->abort_type = ABORT_TYPE_DATA; 201 ai->va = read_far_el1(); 202 break; 203 default: 204 ai->abort_type = ABORT_TYPE_UNDEF; 205 ai->va = regs->elr; 206 } 207 ai->pc = regs->elr; 208 ai->regs = regs; 209 } 210 #endif /*ARM64*/ 211 212 #ifdef ARM32 213 static void handle_user_ta_panic(struct abort_info *ai) 214 { 215 /* 216 * It was a user exception, stop user execution and return 217 * to TEE Core. 218 */ 219 ai->regs->r0 = TEE_ERROR_TARGET_DEAD; 220 ai->regs->r1 = true; 221 ai->regs->r2 = 0xdeadbeef; 222 ai->regs->elr = (uint32_t)thread_unwind_user_mode; 223 ai->regs->spsr = read_cpsr(); 224 ai->regs->spsr &= ~CPSR_MODE_MASK; 225 ai->regs->spsr |= CPSR_MODE_SVC; 226 ai->regs->spsr &= ~CPSR_FIA; 227 ai->regs->spsr |= read_spsr() & CPSR_FIA; 228 /* Select Thumb or ARM mode */ 229 if (ai->regs->elr & 1) 230 ai->regs->spsr |= CPSR_T; 231 else 232 ai->regs->spsr &= ~CPSR_T; 233 } 234 #endif /*ARM32*/ 235 236 #ifdef ARM64 237 static void handle_user_ta_panic(struct abort_info *ai) 238 { 239 uint32_t daif; 240 241 /* 242 * It was a user exception, stop user execution and return 243 * to TEE Core. 244 */ 245 ai->regs->x0 = TEE_ERROR_TARGET_DEAD; 246 ai->regs->x1 = true; 247 ai->regs->x2 = 0xdeadbeef; 248 ai->regs->elr = (vaddr_t)thread_unwind_user_mode; 249 ai->regs->sp_el0 = thread_get_saved_thread_sp(); 250 251 daif = (ai->regs->spsr >> SPSR_32_AIF_SHIFT) & SPSR_32_AIF_MASK; 252 /* XXX what about DAIF_D? */ 253 ai->regs->spsr = SPSR_64(SPSR_64_MODE_EL1, SPSR_64_MODE_SP_EL0, daif); 254 } 255 #endif /*ARM64*/ 256 257 #ifdef CFG_WITH_VFP 258 static void handle_user_ta_vfp(void) 259 { 260 TEE_Result res; 261 struct tee_ta_session *s; 262 263 res = tee_ta_get_current_session(&s); 264 if (res != TEE_SUCCESS) 265 panic(); 266 267 thread_user_enable_vfp(&to_user_ta_ctx(s->ctx)->vfp); 268 } 269 #endif /*CFG_WITH_VFP*/ 270 271 #ifdef ARM32 272 /* Returns true if the exception originated from user mode */ 273 static bool is_user_exception(struct abort_info *ai) 274 { 275 return (ai->regs->spsr & ARM32_CPSR_MODE_MASK) == ARM32_CPSR_MODE_USR; 276 } 277 #endif /*ARM32*/ 278 279 #ifdef ARM64 280 /* Returns true if the exception originated from user mode */ 281 static bool is_user_exception(struct abort_info *ai) 282 { 283 uint32_t spsr = ai->regs->spsr; 284 285 if (spsr & (SPSR_MODE_RW_32 << SPSR_MODE_RW_SHIFT)) 286 return true; 287 if (((spsr >> SPSR_64_MODE_EL_SHIFT) & SPSR_64_MODE_EL_MASK) == 288 SPSR_64_MODE_EL0) 289 return true; 290 return false; 291 } 292 #endif /*ARM64*/ 293 294 #ifdef ARM32 295 /* Returns true if the exception originated from abort mode */ 296 static bool is_abort_in_abort_handler(struct abort_info *ai) 297 { 298 return (ai->regs->spsr & ARM32_CPSR_MODE_MASK) == ARM32_CPSR_MODE_ABT; 299 } 300 #endif /*ARM32*/ 301 302 #ifdef ARM64 303 /* Returns true if the exception originated from abort mode */ 304 static bool is_abort_in_abort_handler(struct abort_info *ai __unused) 305 { 306 return false; 307 } 308 #endif /*ARM64*/ 309 310 #ifdef ARM32 311 312 #define T32_INSTR(w1, w0) \ 313 ((((uint32_t)(w0) & 0xffff) << 16) | ((uint32_t)(w1) & 0xffff)) 314 315 #define T32_VTRANS32_MASK T32_INSTR(0xff << 8, (7 << 9) | 1 << 4) 316 #define T32_VTRANS32_VAL T32_INSTR(0xee << 8, (5 << 9) | 1 << 4) 317 318 #define T32_VTRANS64_MASK T32_INSTR((0xff << 8) | (7 << 5), 7 << 9) 319 #define T32_VTRANS64_VAL T32_INSTR((0xec << 8) | (2 << 5), 5 << 9) 320 321 #define T32_VLDST_MASK T32_INSTR((0xff << 8) | (1 << 4), 0) 322 #define T32_VLDST_VAL T32_INSTR( 0xf9 << 8 , 0) 323 324 #define T32_VXLDST_MASK T32_INSTR(0xfc << 8, 7 << 9) 325 #define T32_VXLDST_VAL T32_INSTR(0xec << 8, 5 << 9) 326 327 #define T32_VPROC_MASK T32_INSTR(0xef << 8, 0) 328 #define T32_VPROC_VAL T32_VPROC_MASK 329 330 #define A32_INSTR(x) ((uint32_t)(x)) 331 332 #define A32_VTRANS32_MASK A32_INSTR((0xf << 24) | (7 << 9) | (1 << 4)) 333 #define A32_VTRANS32_VAL A32_INSTR((0xe << 24) | (5 << 9) | (1 << 4)) 334 335 #define A32_VTRANS64_MASK A32_INSTR((0x7f << 21) | (7 << 9)) 336 #define A32_VTRANS64_VAL A32_INSTR((0x62 << 21) | (5 << 9)) 337 338 #define A32_VLDST_MASK A32_INSTR((0xff << 24) | (1 << 20)) 339 #define A32_VLDST_VAL A32_INSTR((0xf4 << 24)) 340 341 #define A32_VXLDST_MASK A32_INSTR((7 << 25) | (7 << 9)) 342 #define A32_VXLDST_VAL A32_INSTR((6 << 25) | (5 << 9)) 343 344 #define A32_VPROC_MASK A32_INSTR(0x7f << 25) 345 #define A32_VPROC_VAL A32_INSTR(0x79 << 25) 346 347 static bool is_vfp_fault(struct abort_info *ai) 348 { 349 TEE_Result res; 350 uint32_t instr; 351 352 if ((ai->abort_type != ABORT_TYPE_UNDEF) || vfp_is_enabled()) 353 return false; 354 355 res = tee_svc_copy_from_user(NULL, &instr, (void *)ai->pc, 356 sizeof(instr)); 357 if (res != TEE_SUCCESS) 358 return false; 359 360 if (ai->regs->spsr & CPSR_T) { 361 /* Thumb mode */ 362 return ((instr & T32_VTRANS32_MASK) == T32_VTRANS32_VAL) || 363 ((instr & T32_VTRANS64_MASK) == T32_VTRANS64_VAL) || 364 ((instr & T32_VLDST_MASK) == T32_VLDST_VAL) || 365 ((instr & T32_VXLDST_MASK) == T32_VXLDST_VAL) || 366 ((instr & T32_VPROC_MASK) == T32_VPROC_VAL); 367 } else { 368 /* ARM mode */ 369 return ((instr & A32_VTRANS32_MASK) == A32_VTRANS32_VAL) || 370 ((instr & A32_VTRANS64_MASK) == A32_VTRANS64_VAL) || 371 ((instr & A32_VLDST_MASK) == A32_VLDST_VAL) || 372 ((instr & A32_VXLDST_MASK) == A32_VXLDST_VAL) || 373 ((instr & A32_VPROC_MASK) == A32_VPROC_VAL); 374 } 375 } 376 #endif /*ARM32*/ 377 378 #ifdef ARM64 379 static bool is_vfp_fault(struct abort_info *ai) 380 { 381 switch ((ai->fault_descr >> ESR_EC_SHIFT) & ESR_EC_MASK) { 382 case ESR_EC_FP_ASIMD: 383 case ESR_EC_AARCH32_FP: 384 case ESR_EC_AARCH64_FP: 385 return true; 386 default: 387 return false; 388 } 389 } 390 #endif /*ARM64*/ 391 392 static enum fault_type get_fault_type(struct abort_info *ai) 393 { 394 if (is_user_exception(ai)) { 395 if (is_vfp_fault(ai)) 396 return FAULT_TYPE_USER_TA_VFP; 397 print_user_abort(ai); 398 DMSG("[abort] abort in User mode (TA will panic)"); 399 return FAULT_TYPE_USER_TA_PANIC; 400 } 401 402 if (is_abort_in_abort_handler(ai)) { 403 abort_print_error(ai); 404 EMSG("[abort] abort in abort handler (trap CPU)"); 405 panic(); 406 } 407 408 if (ai->abort_type == ABORT_TYPE_UNDEF) { 409 abort_print_error(ai); 410 EMSG("[abort] undefined abort (trap CPU)"); 411 panic(); 412 } 413 414 switch (core_mmu_get_fault_type(ai->fault_descr)) { 415 case CORE_MMU_FAULT_ALIGNMENT: 416 abort_print_error(ai); 417 EMSG("[abort] alignement fault! (trap CPU)"); 418 panic(); 419 break; 420 421 case CORE_MMU_FAULT_ACCESS_BIT: 422 abort_print_error(ai); 423 EMSG("[abort] access bit fault! (trap CPU)"); 424 panic(); 425 break; 426 427 case CORE_MMU_FAULT_DEBUG_EVENT: 428 abort_print(ai); 429 DMSG("[abort] Ignoring debug event!"); 430 return FAULT_TYPE_IGNORE; 431 432 case CORE_MMU_FAULT_TRANSLATION: 433 case CORE_MMU_FAULT_WRITE_PERMISSION: 434 case CORE_MMU_FAULT_READ_PERMISSION: 435 return FAULT_TYPE_PAGEABLE; 436 437 case CORE_MMU_FAULT_ASYNC_EXTERNAL: 438 abort_print(ai); 439 DMSG("[abort] Ignoring async external abort!"); 440 return FAULT_TYPE_IGNORE; 441 442 case CORE_MMU_FAULT_OTHER: 443 default: 444 abort_print(ai); 445 DMSG("[abort] Unhandled fault!"); 446 return FAULT_TYPE_IGNORE; 447 } 448 } 449 450 void abort_handler(uint32_t abort_type, struct thread_abort_regs *regs) 451 { 452 struct abort_info ai; 453 454 set_abort_info(abort_type, regs, &ai); 455 456 switch (get_fault_type(&ai)) { 457 case FAULT_TYPE_IGNORE: 458 break; 459 case FAULT_TYPE_USER_TA_PANIC: 460 vfp_disable(); 461 handle_user_ta_panic(&ai); 462 break; 463 #ifdef CFG_WITH_VFP 464 case FAULT_TYPE_USER_TA_VFP: 465 handle_user_ta_vfp(); 466 break; 467 #endif 468 case FAULT_TYPE_PAGEABLE: 469 default: 470 thread_kernel_save_vfp(); 471 tee_pager_handle_fault(&ai); 472 thread_kernel_restore_vfp(); 473 break; 474 } 475 } 476