* Abort handler. * * FAR, FSR, and everything what can be lost after enabling * interrupts must be grabbed before the interrupts will be * enabled. Note that when interrupts will be enabled, we * could even migrate to another CPU ... * * TODO: move quick cases to ASM */
| 276 | * TODO: move quick cases to ASM |
| 277 | */ |
| 278 | void |
| 279 | abort_handler(struct trapframe *tf, int prefetch) |
| 280 | { |
| 281 | struct thread *td; |
| 282 | vm_offset_t far, va; |
| 283 | int idx, rv; |
| 284 | uint32_t fsr; |
| 285 | struct ksig ksig; |
| 286 | struct proc *p; |
| 287 | struct pcb *pcb; |
| 288 | struct vm_map *map; |
| 289 | struct vmspace *vm; |
| 290 | vm_prot_t ftype; |
| 291 | bool usermode; |
| 292 | int bp_harden, ucode; |
| 293 | #ifdef INVARIANTS |
| 294 | void *onfault; |
| 295 | #endif |
| 296 | |
| 297 | VM_CNT_INC(v_trap); |
| 298 | td = curthread; |
| 299 | |
| 300 | fsr = (prefetch) ? cp15_ifsr_get(): cp15_dfsr_get(); |
| 301 | #if __ARM_ARCH >= 7 |
| 302 | far = (prefetch) ? cp15_ifar_get() : cp15_dfar_get(); |
| 303 | #else |
| 304 | far = (prefetch) ? TRAPF_PC(tf) : cp15_dfar_get(); |
| 305 | #endif |
| 306 | |
| 307 | idx = FSR_TO_FAULT(fsr); |
| 308 | usermode = TRAPF_USERMODE(tf); /* Abort came from user mode? */ |
| 309 | |
| 310 | /* |
| 311 | * Apply BP hardening by flushing the branch prediction cache |
| 312 | * for prefaults on kernel addresses. |
| 313 | */ |
| 314 | if (__predict_false(prefetch && far > VM_MAXUSER_ADDRESS && |
| 315 | (idx == FAULT_TRAN_L2 || idx == FAULT_PERM_L2))) { |
| 316 | bp_harden = PCPU_GET(bp_harden_kind); |
| 317 | if (bp_harden == PCPU_BP_HARDEN_KIND_BPIALL) |
| 318 | _CP15_BPIALL(); |
| 319 | else if (bp_harden == PCPU_BP_HARDEN_KIND_ICIALLU) |
| 320 | _CP15_ICIALLU(); |
| 321 | } |
| 322 | |
| 323 | if (usermode) |
| 324 | td->td_frame = tf; |
| 325 | |
| 326 | CTR6(KTR_TRAP, "%s: fsr %#x (idx %u) far %#x prefetch %u usermode %d", |
| 327 | __func__, fsr, idx, far, prefetch, usermode); |
| 328 | |
| 329 | /* |
| 330 | * Firstly, handle aborts that are not directly related to mapping. |
| 331 | */ |
| 332 | if (__predict_false(idx == FAULT_EA_IMPREC)) { |
| 333 | abort_imprecise(tf, fsr, prefetch, usermode); |
| 334 | return; |
| 335 | } |
nothing calls this directly
no test coverage detected