1e5acd89cSAndrew Turner /*- 2e5acd89cSAndrew Turner * Copyright (c) 2014 Andrew Turner 3e5acd89cSAndrew Turner * All rights reserved. 4e5acd89cSAndrew Turner * 5e5acd89cSAndrew Turner * Redistribution and use in source and binary forms, with or without 6e5acd89cSAndrew Turner * modification, are permitted provided that the following conditions 7e5acd89cSAndrew Turner * are met: 8e5acd89cSAndrew Turner * 1. Redistributions of source code must retain the above copyright 9e5acd89cSAndrew Turner * notice, this list of conditions and the following disclaimer. 10e5acd89cSAndrew Turner * 2. Redistributions in binary form must reproduce the above copyright 11e5acd89cSAndrew Turner * notice, this list of conditions and the following disclaimer in the 12e5acd89cSAndrew Turner * documentation and/or other materials provided with the distribution. 13e5acd89cSAndrew Turner * 14e5acd89cSAndrew Turner * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15e5acd89cSAndrew Turner * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16e5acd89cSAndrew Turner * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17e5acd89cSAndrew Turner * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18e5acd89cSAndrew Turner * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19e5acd89cSAndrew Turner * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20e5acd89cSAndrew Turner * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21e5acd89cSAndrew Turner * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22e5acd89cSAndrew Turner * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23e5acd89cSAndrew Turner * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24e5acd89cSAndrew Turner * SUCH DAMAGE. 25e5acd89cSAndrew Turner * 26e5acd89cSAndrew Turner */ 27e5acd89cSAndrew Turner 28e5acd89cSAndrew Turner #include <sys/cdefs.h> 29e5acd89cSAndrew Turner __FBSDID("$FreeBSD$"); 30e5acd89cSAndrew Turner 31e5acd89cSAndrew Turner #include <sys/param.h> 32e5acd89cSAndrew Turner #include <sys/systm.h> 33e5acd89cSAndrew Turner #include <sys/kernel.h> 34e5acd89cSAndrew Turner #include <sys/lock.h> 35e5acd89cSAndrew Turner #include <sys/mutex.h> 36e5acd89cSAndrew Turner #include <sys/pioctl.h> 37e5acd89cSAndrew Turner #include <sys/proc.h> 38e5acd89cSAndrew Turner #include <sys/ptrace.h> 39e5acd89cSAndrew Turner #include <sys/syscall.h> 40e5acd89cSAndrew Turner #include <sys/sysent.h> 41e5acd89cSAndrew Turner #ifdef KDB 42e5acd89cSAndrew Turner #include <sys/kdb.h> 43e5acd89cSAndrew Turner #endif 44e5acd89cSAndrew Turner 45e5acd89cSAndrew Turner #include <vm/vm.h> 46e5acd89cSAndrew Turner #include <vm/pmap.h> 47e5acd89cSAndrew Turner #include <vm/vm_kern.h> 48e5acd89cSAndrew Turner #include <vm/vm_map.h> 49cb02f6b9SAndrew Turner #include <vm/vm_param.h> 50e5acd89cSAndrew Turner #include <vm/vm_extern.h> 51e5acd89cSAndrew Turner 52e5acd89cSAndrew Turner #include <machine/frame.h> 53e5acd89cSAndrew Turner #include <machine/pcb.h> 54e5acd89cSAndrew Turner #include <machine/pcpu.h> 55e5acd89cSAndrew Turner #include <machine/vmparam.h> 56e5acd89cSAndrew Turner 57b78ee15eSRuslan Bukin #ifdef KDTRACE_HOOKS 58b78ee15eSRuslan Bukin #include <sys/dtrace_bsd.h> 59b78ee15eSRuslan Bukin #endif 60b78ee15eSRuslan Bukin 61e5acd89cSAndrew Turner #ifdef VFP 62e5acd89cSAndrew Turner #include <machine/vfp.h> 63e5acd89cSAndrew Turner #endif 64e5acd89cSAndrew Turner 65e5acd89cSAndrew Turner #ifdef KDB 66e5acd89cSAndrew Turner #include <machine/db_machdep.h> 67e5acd89cSAndrew Turner #endif 68e5acd89cSAndrew Turner 69e5acd89cSAndrew Turner #ifdef DDB 70e5acd89cSAndrew Turner #include <ddb/db_output.h> 71e5acd89cSAndrew Turner #endif 72e5acd89cSAndrew Turner 739d77aa2aSAndrew Turner extern register_t fsu_intr_fault; 74e5acd89cSAndrew Turner 75e5acd89cSAndrew Turner /* Called from exception.S */ 76e5acd89cSAndrew Turner void do_el1h_sync(struct trapframe *); 77e5acd89cSAndrew Turner void do_el0_sync(struct trapframe *); 78e5acd89cSAndrew Turner void do_el0_error(struct trapframe *); 79e5acd89cSAndrew Turner 80b78ee15eSRuslan Bukin int (*dtrace_invop_jump_addr)(struct trapframe *); 81b78ee15eSRuslan Bukin 82e5acd89cSAndrew Turner static __inline void 83cb02f6b9SAndrew Turner call_trapsignal(struct thread *td, int sig, int code, void *addr) 84e5acd89cSAndrew Turner { 85e5acd89cSAndrew Turner ksiginfo_t ksi; 86e5acd89cSAndrew Turner 87e5acd89cSAndrew Turner ksiginfo_init_trap(&ksi); 88e5acd89cSAndrew Turner ksi.ksi_signo = sig; 89cb02f6b9SAndrew Turner ksi.ksi_code = code; 90cb02f6b9SAndrew Turner ksi.ksi_addr = addr; 91e5acd89cSAndrew Turner trapsignal(td, &ksi); 92e5acd89cSAndrew Turner } 93e5acd89cSAndrew Turner 94e5acd89cSAndrew Turner int 95e5acd89cSAndrew Turner cpu_fetch_syscall_args(struct thread *td, struct syscall_args *sa) 96e5acd89cSAndrew Turner { 97e5acd89cSAndrew Turner struct proc *p; 98e5acd89cSAndrew Turner register_t *ap; 99e5acd89cSAndrew Turner int nap; 100e5acd89cSAndrew Turner 101e5acd89cSAndrew Turner nap = 8; 102e5acd89cSAndrew Turner p = td->td_proc; 103e5acd89cSAndrew Turner ap = td->td_frame->tf_x; 104e5acd89cSAndrew Turner 105e5acd89cSAndrew Turner sa->code = td->td_frame->tf_x[8]; 106e5acd89cSAndrew Turner 107e5acd89cSAndrew Turner if (sa->code == SYS_syscall || sa->code == SYS___syscall) { 108e5acd89cSAndrew Turner sa->code = *ap++; 109e5acd89cSAndrew Turner nap--; 110e5acd89cSAndrew Turner } 111e5acd89cSAndrew Turner 112e5acd89cSAndrew Turner if (p->p_sysent->sv_mask) 113e5acd89cSAndrew Turner sa->code &= p->p_sysent->sv_mask; 114e5acd89cSAndrew Turner if (sa->code >= p->p_sysent->sv_size) 115e5acd89cSAndrew Turner sa->callp = &p->p_sysent->sv_table[0]; 116e5acd89cSAndrew Turner else 117e5acd89cSAndrew Turner sa->callp = &p->p_sysent->sv_table[sa->code]; 118e5acd89cSAndrew Turner 119e5acd89cSAndrew Turner sa->narg = sa->callp->sy_narg; 120e5acd89cSAndrew Turner memcpy(sa->args, ap, nap * sizeof(register_t)); 121e5acd89cSAndrew Turner if (sa->narg > nap) 1226bc3fe5fSPedro F. Giffuni panic("ARM64TODO: Could we have more than 8 args?"); 123e5acd89cSAndrew Turner 124e5acd89cSAndrew Turner td->td_retval[0] = 0; 125e5acd89cSAndrew Turner td->td_retval[1] = 0; 126e5acd89cSAndrew Turner 127e5acd89cSAndrew Turner return (0); 128e5acd89cSAndrew Turner } 129e5acd89cSAndrew Turner 130e5acd89cSAndrew Turner #include "../../kern/subr_syscall.c" 131e5acd89cSAndrew Turner 132e5acd89cSAndrew Turner static void 133e5acd89cSAndrew Turner svc_handler(struct trapframe *frame) 134e5acd89cSAndrew Turner { 135e5acd89cSAndrew Turner struct syscall_args sa; 136e5acd89cSAndrew Turner struct thread *td; 137e5acd89cSAndrew Turner int error; 138e5acd89cSAndrew Turner 139e5acd89cSAndrew Turner td = curthread; 140e5acd89cSAndrew Turner td->td_frame = frame; 141e5acd89cSAndrew Turner 142e5acd89cSAndrew Turner error = syscallenter(td, &sa); 143e5acd89cSAndrew Turner syscallret(td, error, &sa); 144e5acd89cSAndrew Turner } 145e5acd89cSAndrew Turner 146e5acd89cSAndrew Turner static void 147e5acd89cSAndrew Turner data_abort(struct trapframe *frame, uint64_t esr, int lower) 148e5acd89cSAndrew Turner { 149e5acd89cSAndrew Turner struct vm_map *map; 150e5acd89cSAndrew Turner struct thread *td; 151e5acd89cSAndrew Turner struct proc *p; 152e5acd89cSAndrew Turner struct pcb *pcb; 153e5acd89cSAndrew Turner vm_prot_t ftype; 154e5acd89cSAndrew Turner vm_offset_t va; 155e5acd89cSAndrew Turner uint64_t far; 156cb02f6b9SAndrew Turner int error, sig, ucode; 157e5acd89cSAndrew Turner 158e5acd89cSAndrew Turner td = curthread; 159e5acd89cSAndrew Turner pcb = td->td_pcb; 160e5acd89cSAndrew Turner 161e5acd89cSAndrew Turner /* 162e5acd89cSAndrew Turner * Special case for fuswintr and suswintr. These can't sleep so 163e5acd89cSAndrew Turner * handle them early on in the trap handler. 164e5acd89cSAndrew Turner */ 1659d77aa2aSAndrew Turner if (__predict_false(pcb->pcb_onfault == (vm_offset_t)&fsu_intr_fault)) { 166e5acd89cSAndrew Turner frame->tf_elr = pcb->pcb_onfault; 167e5acd89cSAndrew Turner return; 168e5acd89cSAndrew Turner } 169e5acd89cSAndrew Turner 170e5acd89cSAndrew Turner far = READ_SPECIALREG(far_el1); 171e5acd89cSAndrew Turner p = td->td_proc; 172e5acd89cSAndrew Turner 173e5acd89cSAndrew Turner if (lower) 174e5acd89cSAndrew Turner map = &td->td_proc->p_vmspace->vm_map; 175e5acd89cSAndrew Turner else { 176e5acd89cSAndrew Turner /* The top bit tells us which range to use */ 177e5acd89cSAndrew Turner if ((far >> 63) == 1) 178e5acd89cSAndrew Turner map = kernel_map; 179e5acd89cSAndrew Turner else 180e5acd89cSAndrew Turner map = &td->td_proc->p_vmspace->vm_map; 181e5acd89cSAndrew Turner } 182e5acd89cSAndrew Turner 183e5acd89cSAndrew Turner va = trunc_page(far); 184e5acd89cSAndrew Turner ftype = ((esr >> 6) & 1) ? VM_PROT_READ | VM_PROT_WRITE : VM_PROT_READ; 185e5acd89cSAndrew Turner 186e5acd89cSAndrew Turner if (map != kernel_map) { 187e5acd89cSAndrew Turner /* 188e5acd89cSAndrew Turner * Keep swapout from messing with us during this 189e5acd89cSAndrew Turner * critical time. 190e5acd89cSAndrew Turner */ 191e5acd89cSAndrew Turner PROC_LOCK(p); 192e5acd89cSAndrew Turner ++p->p_lock; 193e5acd89cSAndrew Turner PROC_UNLOCK(p); 194e5acd89cSAndrew Turner 195e5acd89cSAndrew Turner /* Fault in the user page: */ 196e5acd89cSAndrew Turner error = vm_fault(map, va, ftype, VM_FAULT_NORMAL); 197e5acd89cSAndrew Turner 198e5acd89cSAndrew Turner PROC_LOCK(p); 199e5acd89cSAndrew Turner --p->p_lock; 200e5acd89cSAndrew Turner PROC_UNLOCK(p); 201e5acd89cSAndrew Turner } else { 202e5acd89cSAndrew Turner /* 203e5acd89cSAndrew Turner * Don't have to worry about process locking or stacks in the 204e5acd89cSAndrew Turner * kernel. 205e5acd89cSAndrew Turner */ 206e5acd89cSAndrew Turner error = vm_fault(map, va, ftype, VM_FAULT_NORMAL); 207e5acd89cSAndrew Turner } 208e5acd89cSAndrew Turner 209cb02f6b9SAndrew Turner if (error != KERN_SUCCESS) { 210e5acd89cSAndrew Turner if (lower) { 211e5acd89cSAndrew Turner sig = SIGSEGV; 212cb02f6b9SAndrew Turner if (error == KERN_PROTECTION_FAILURE) 213cb02f6b9SAndrew Turner ucode = SEGV_ACCERR; 214cb02f6b9SAndrew Turner else 215cb02f6b9SAndrew Turner ucode = SEGV_MAPERR; 216cb02f6b9SAndrew Turner call_trapsignal(td, sig, ucode, (void *)far); 217e5acd89cSAndrew Turner } else { 218e5acd89cSAndrew Turner if (td->td_intr_nesting_level == 0 && 219e5acd89cSAndrew Turner pcb->pcb_onfault != 0) { 220e5acd89cSAndrew Turner frame->tf_x[0] = error; 221e5acd89cSAndrew Turner frame->tf_elr = pcb->pcb_onfault; 222e5acd89cSAndrew Turner return; 223e5acd89cSAndrew Turner } 224e5acd89cSAndrew Turner panic("vm_fault failed: %lx", frame->tf_elr); 225e5acd89cSAndrew Turner } 226e5acd89cSAndrew Turner } 227e5acd89cSAndrew Turner 228e5acd89cSAndrew Turner if (lower) 229e5acd89cSAndrew Turner userret(td, frame); 230e5acd89cSAndrew Turner } 231e5acd89cSAndrew Turner 232ccd285e7SEd Maste static void 233ccd285e7SEd Maste print_registers(struct trapframe *frame) 234ccd285e7SEd Maste { 235ccd285e7SEd Maste u_int reg; 236ccd285e7SEd Maste 237ccd285e7SEd Maste for (reg = 0; reg < 31; reg++) { 238ccd285e7SEd Maste printf(" %sx%d: %16lx\n", (reg < 10) ? " " : "", reg, 239ccd285e7SEd Maste frame->tf_x[reg]); 240ccd285e7SEd Maste } 241ccd285e7SEd Maste printf(" sp: %16lx\n", frame->tf_sp); 242ccd285e7SEd Maste printf(" lr: %16lx\n", frame->tf_lr); 243ccd285e7SEd Maste printf(" elr: %16lx\n", frame->tf_elr); 244ccd285e7SEd Maste printf("spsr: %16lx\n", frame->tf_spsr); 245ccd285e7SEd Maste } 246ccd285e7SEd Maste 247e5acd89cSAndrew Turner void 248e5acd89cSAndrew Turner do_el1h_sync(struct trapframe *frame) 249e5acd89cSAndrew Turner { 250e5acd89cSAndrew Turner uint32_t exception; 251e5acd89cSAndrew Turner uint64_t esr; 252e5acd89cSAndrew Turner 253e5acd89cSAndrew Turner /* Read the esr register to get the exception details */ 254e5acd89cSAndrew Turner esr = READ_SPECIALREG(esr_el1); 255e5acd89cSAndrew Turner exception = ESR_ELx_EXCEPTION(esr); 256e5acd89cSAndrew Turner 257b78ee15eSRuslan Bukin #ifdef KDTRACE_HOOKS 258b78ee15eSRuslan Bukin if (dtrace_trap_func != NULL && (*dtrace_trap_func)(frame, exception)) 259b78ee15eSRuslan Bukin return; 260b78ee15eSRuslan Bukin #endif 261b78ee15eSRuslan Bukin 262e5acd89cSAndrew Turner /* 263e5acd89cSAndrew Turner * Sanity check we are in an exception er can handle. The IL bit 264e5acd89cSAndrew Turner * is used to indicate the instruction length, except in a few 265e5acd89cSAndrew Turner * exceptions described in the ARMv8 ARM. 266e5acd89cSAndrew Turner * 267e5acd89cSAndrew Turner * It is unclear in some cases if the bit is implementation defined. 268e5acd89cSAndrew Turner * The Foundation Model and QEMU disagree on if the IL bit should 269e5acd89cSAndrew Turner * be set when we are in a data fault from the same EL and the ISV 270e5acd89cSAndrew Turner * bit (bit 24) is also set. 271e5acd89cSAndrew Turner */ 272e5acd89cSAndrew Turner KASSERT((esr & ESR_ELx_IL) == ESR_ELx_IL || 273e5acd89cSAndrew Turner (exception == EXCP_DATA_ABORT && ((esr & ISS_DATA_ISV) == 0)), 274e5acd89cSAndrew Turner ("Invalid instruction length in exception")); 275e5acd89cSAndrew Turner 2763ad7e84eSAndrew Turner CTR4(KTR_TRAP, 2773ad7e84eSAndrew Turner "do_el1_sync: curthread: %p, esr %lx, elr: %lx, frame: %p", 2783ad7e84eSAndrew Turner curthread, esr, frame->tf_elr, frame); 2793ad7e84eSAndrew Turner 280e5acd89cSAndrew Turner switch(exception) { 281e5acd89cSAndrew Turner case EXCP_FP_SIMD: 282e5acd89cSAndrew Turner case EXCP_TRAP_FP: 283ccd285e7SEd Maste print_registers(frame); 284e5acd89cSAndrew Turner panic("VFP exception in the kernel"); 285e5acd89cSAndrew Turner case EXCP_DATA_ABORT: 286e5acd89cSAndrew Turner data_abort(frame, esr, 0); 287e5acd89cSAndrew Turner break; 288e5acd89cSAndrew Turner case EXCP_BRK: 289b78ee15eSRuslan Bukin #ifdef KDTRACE_HOOKS 290b78ee15eSRuslan Bukin if ((esr & ESR_ELx_ISS_MASK) == 0x40d && \ 291b78ee15eSRuslan Bukin dtrace_invop_jump_addr != 0) { 292b78ee15eSRuslan Bukin dtrace_invop_jump_addr(frame); 293b78ee15eSRuslan Bukin break; 294b78ee15eSRuslan Bukin } 295b78ee15eSRuslan Bukin #endif 296e5acd89cSAndrew Turner case EXCP_WATCHPT_EL1: 297e5acd89cSAndrew Turner case EXCP_SOFTSTP_EL1: 298e5acd89cSAndrew Turner #ifdef KDB 299e5acd89cSAndrew Turner kdb_trap(exception, 0, frame); 300e5acd89cSAndrew Turner #else 301e5acd89cSAndrew Turner panic("No debugger in kernel.\n"); 302e5acd89cSAndrew Turner #endif 303e5acd89cSAndrew Turner break; 304e5acd89cSAndrew Turner default: 305ccd285e7SEd Maste print_registers(frame); 306e5acd89cSAndrew Turner panic("Unknown kernel exception %x esr_el1 %lx\n", exception, 307e5acd89cSAndrew Turner esr); 308e5acd89cSAndrew Turner } 309e5acd89cSAndrew Turner } 310e5acd89cSAndrew Turner 311ccd285e7SEd Maste /* 3125a060174SEd Maste * The attempted execution of an instruction bit pattern that has no allocated 3138d5bb774SEd Maste * instruction results in an exception with an unknown reason. 314ccd285e7SEd Maste */ 315ccd285e7SEd Maste static void 316ccd285e7SEd Maste el0_excp_unknown(struct trapframe *frame) 317ccd285e7SEd Maste { 318ccd285e7SEd Maste struct thread *td; 319ccd285e7SEd Maste uint64_t far; 320ccd285e7SEd Maste 321ccd285e7SEd Maste td = curthread; 322ccd285e7SEd Maste far = READ_SPECIALREG(far_el1); 323ccd285e7SEd Maste call_trapsignal(td, SIGILL, ILL_ILLTRP, (void *)far); 324ccd285e7SEd Maste userret(td, frame); 325ccd285e7SEd Maste } 326ccd285e7SEd Maste 327e5acd89cSAndrew Turner void 328e5acd89cSAndrew Turner do_el0_sync(struct trapframe *frame) 329e5acd89cSAndrew Turner { 330e5acd89cSAndrew Turner uint32_t exception; 331e5acd89cSAndrew Turner uint64_t esr; 332e5acd89cSAndrew Turner 333e5acd89cSAndrew Turner /* Check we have a sane environment when entering from userland */ 334e5acd89cSAndrew Turner KASSERT((uintptr_t)get_pcpu() >= VM_MIN_KERNEL_ADDRESS, 335e5acd89cSAndrew Turner ("Invalid pcpu address from userland: %p (tpidr %lx)", 336e5acd89cSAndrew Turner get_pcpu(), READ_SPECIALREG(tpidr_el1))); 337e5acd89cSAndrew Turner 338e5acd89cSAndrew Turner esr = READ_SPECIALREG(esr_el1); 339e5acd89cSAndrew Turner exception = ESR_ELx_EXCEPTION(esr); 340e5acd89cSAndrew Turner 3413ad7e84eSAndrew Turner CTR4(KTR_TRAP, 3423ad7e84eSAndrew Turner "do_el0_sync: curthread: %p, esr %lx, elr: %lx, frame: %p", 3433ad7e84eSAndrew Turner curthread, esr, frame->tf_elr, frame); 3443ad7e84eSAndrew Turner 345e5acd89cSAndrew Turner switch(exception) { 346e5acd89cSAndrew Turner case EXCP_FP_SIMD: 347e5acd89cSAndrew Turner case EXCP_TRAP_FP: 348e5acd89cSAndrew Turner #ifdef VFP 349e5acd89cSAndrew Turner vfp_restore_state(); 350e5acd89cSAndrew Turner #else 351e5acd89cSAndrew Turner panic("VFP exception in userland"); 352e5acd89cSAndrew Turner #endif 353e5acd89cSAndrew Turner break; 354e5acd89cSAndrew Turner case EXCP_SVC: 3559028b18fSZbigniew Bodek /* 3569028b18fSZbigniew Bodek * Ensure the svc_handler is being run with interrupts enabled. 3579028b18fSZbigniew Bodek * They will be automatically restored when returning from 3589028b18fSZbigniew Bodek * exception handler. 3599028b18fSZbigniew Bodek */ 3609028b18fSZbigniew Bodek intr_enable(); 361e5acd89cSAndrew Turner svc_handler(frame); 362e5acd89cSAndrew Turner break; 363e5acd89cSAndrew Turner case EXCP_INSN_ABORT_L: 364e5acd89cSAndrew Turner case EXCP_DATA_ABORT_L: 3654cbca608SZbigniew Bodek case EXCP_DATA_ABORT: 366e5acd89cSAndrew Turner data_abort(frame, esr, 1); 367e5acd89cSAndrew Turner break; 368ccd285e7SEd Maste case EXCP_UNKNOWN: 369ccd285e7SEd Maste el0_excp_unknown(frame); 370ccd285e7SEd Maste break; 371e5acd89cSAndrew Turner default: 372ccd285e7SEd Maste print_registers(frame); 373e5acd89cSAndrew Turner panic("Unknown userland exception %x esr_el1 %lx\n", exception, 374e5acd89cSAndrew Turner esr); 375e5acd89cSAndrew Turner } 376e5acd89cSAndrew Turner } 377e5acd89cSAndrew Turner 378e5acd89cSAndrew Turner void 379e5acd89cSAndrew Turner do_el0_error(struct trapframe *frame) 380e5acd89cSAndrew Turner { 381e5acd89cSAndrew Turner 382c547d650SEd Maste panic("ARM64TODO: do_el0_error"); 383e5acd89cSAndrew Turner } 384e5acd89cSAndrew Turner 385