Introduce KERNEL_LOCK into arm64 code. arm_do_pending_intr was changed to check if any pending would be serviced before the loop to avoid obtaining KERNEL_LOCK, otherwise KERNEL_LOCK would be acquired even if the previous IPL level was > IPL_SOFTTTY. This would unnessarily grab the kernel lock as well as possibly introduce a deadlock if KERNEL_LOCK was always obtained in the code at that location.
This prevents grabbing a kernel lock if the interrupt was taken above IPL_SOFTTTY. diff --git a/sys/arch/arm64/arm64/intr.c b/sys/arch/arm64/arm64/intr.c index f41cc8fbda9..7b26ccb5457 100644 --- a/sys/arch/arm64/arm64/intr.c +++ b/sys/arch/arm64/arm64/intr.c @@ -446,12 +446,17 @@ arm_do_pending_intr(int pcpl) oldirqstate = disable_interrupts(); \ } - do { + while (ci->ci_ipending & arm_smask[pcpl]) { + KERNEL_LOCK(); + DO_SOFTINT(SIR_TTY, IPL_SOFTTTY); DO_SOFTINT(SIR_NET, IPL_SOFTNET); DO_SOFTINT(SIR_CLOCK, IPL_SOFTCLOCK); DO_SOFTINT(SIR_SOFT, IPL_SOFT); - } while (ci->ci_ipending & arm_smask[pcpl]); + + KERNEL_UNLOCK(); + } + /* Don't use splx... we are here already! */ arm_intr_func.setipl(pcpl); diff --git a/sys/arch/arm64/arm64/syscall.c b/sys/arch/arm64/arm64/syscall.c index a497cd74e74..39ab96133c1 100644 --- a/sys/arch/arm64/arm64/syscall.c +++ b/sys/arch/arm64/arm64/syscall.c @@ -130,5 +130,7 @@ child_return(arg) frame->tf_x[1] = 1; frame->tf_spsr &= ~PSR_C; /* carry bit */ + KERNEL_UNLOCK(); + mi_child_return(p); } diff --git a/sys/arch/arm64/arm64/trap.c b/sys/arch/arm64/arm64/trap.c index 1dc151fe143..b1a4664af8b 100644 --- a/sys/arch/arm64/arm64/trap.c +++ b/sys/arch/arm64/arm64/trap.c @@ -173,7 +173,9 @@ data_abort(struct trapframe *frame, uint64_t esr, int lower, int exe) /* Fault in the user page: */ if (!pmap_fault_fixup(map->pmap, va, access_type, 1)) { + KERNEL_LOCK(); error = uvm_fault(map, va, ftype, access_type); + KERNEL_UNLOCK(); } //PROC_LOCK(p); @@ -185,7 +187,9 @@ data_abort(struct trapframe *frame, uint64_t esr, int lower, int exe) * kernel. */ if (!pmap_fault_fixup(map->pmap, va, access_type, 0)) { + KERNEL_LOCK(); error = uvm_fault(map, va, ftype, access_type); + KERNEL_UNLOCK(); } } @@ -198,7 +202,9 @@ data_abort(struct trapframe *frame, uint64_t esr, int lower, int exe) sv.sival_ptr = (u_int64_t *)far; dumpregs(frame); + KERNEL_LOCK(); trapsignal(p, sig, 0, SEGV_ACCERR, sv); + KERNEL_UNLOCK(); } else { if (curcpu()->ci_idepth == 0 && pcb->pcb_onfault != 0) { Dale Rahn dr...@dalerahn.com