diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2018-02-02 09:33:36 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2018-02-02 09:33:36 +0000 |
commit | 96f499c9b2587a04c8369e4c3ae3a885ef453756 (patch) | |
tree | aa12477fed9019c9d0726d79e7d7a14ed93a04f8 /sys | |
parent | 773257cd8109703e80bb04cf2628c000543e852f (diff) |
Enable interrupts in (synchronous) trap handlers.
ok patrick@
Diffstat (limited to 'sys')
-rw-r--r-- | sys/arch/arm64/arm64/trap.c | 23 |
1 files changed, 14 insertions, 9 deletions
diff --git a/sys/arch/arm64/arm64/trap.c b/sys/arch/arm64/arm64/trap.c index 29321aec439..843d3541b25 100644 --- a/sys/arch/arm64/arm64/trap.c +++ b/sys/arch/arm64/arm64/trap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: trap.c,v 1.15 2018/01/17 10:22:25 kettenis Exp $ */ +/* $OpenBSD: trap.c,v 1.16 2018/02/02 09:33:35 kettenis Exp $ */ /*- * Copyright (c) 2014 Andrew Turner * All rights reserved. @@ -126,7 +126,8 @@ svc_handler(struct trapframe *frame) void dumpregs(struct trapframe*); static void -data_abort(struct trapframe *frame, uint64_t esr, int lower, int exe) +data_abort(struct trapframe *frame, uint64_t esr, uint64_t far, + int lower, int exe) { struct vm_map *map; struct proc *p; @@ -135,13 +136,11 @@ data_abort(struct trapframe *frame, uint64_t esr, int lower, int exe) vm_prot_t access_type; vaddr_t va; union sigval sv; - uint64_t far; int error = 0, sig, code; pcb = curcpu()->ci_curpcb; p = curcpu()->ci_curproc; - far = READ_SPECIALREG(far_el1); va = trunc_page(far); if (va >= VM_MAXUSER_ADDRESS) curcpu()->ci_flush_bp(); @@ -230,11 +229,14 @@ void do_el1h_sync(struct trapframe *frame) { uint32_t exception; - uint64_t esr; + uint64_t esr, far; /* Read the esr register to get the exception details */ esr = READ_SPECIALREG(esr_el1); exception = ESR_ELx_EXCEPTION(esr); + far = READ_SPECIALREG(far_el1); + + enable_interrupts(); /* * Sanity check we are in an exception er can handle. The IL bit @@ -255,7 +257,7 @@ do_el1h_sync(struct trapframe *frame) case EXCP_TRAP_FP: panic("VFP exception in the kernel"); case EXCP_DATA_ABORT: - data_abort(frame, esr, 0, 0); + data_abort(frame, esr, far, 0, 0); break; case EXCP_BRK: case EXCP_WATCHPT_EL1: @@ -290,10 +292,13 @@ do_el0_sync(struct trapframe *frame) struct proc *p = curproc; union sigval sv; uint32_t exception; - uint64_t esr; + uint64_t esr, far; esr = READ_SPECIALREG(esr_el1); exception = ESR_ELx_EXCEPTION(esr); + far = READ_SPECIALREG(far_el1); + + enable_interrupts(); refreshcreds(p); @@ -316,7 +321,7 @@ do_el0_sync(struct trapframe *frame) break; case EXCP_INSN_ABORT_L: vfp_save(); - data_abort(frame, esr, 1, 1); + data_abort(frame, esr, far, 1, 1); break; case EXCP_PC_ALIGN: vfp_save(); @@ -336,7 +341,7 @@ do_el0_sync(struct trapframe *frame) break; case EXCP_DATA_ABORT_L: vfp_save(); - data_abort(frame, esr, 1, 0); + data_abort(frame, esr, far, 1, 0); break; case EXCP_BRK: vfp_save(); |