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

Reply via email to