Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/sommerfeld_i386mp_1]: src/sys/arch/i386/i386 Add KERNEL_{PROC, }_{LOCK, UN...



details:   https://anonhg.NetBSD.org/src/rev/f34482d7220d
branches:  sommerfeld_i386mp_1
changeset: 482269:f34482d7220d
user:      sommerfeld <sommerfeld%NetBSD.org@localhost>
date:      Fri Aug 18 13:55:44 2000 +0000

description:
Add KERNEL_{PROC,}_{LOCK,UNLOCK} calls to lock the kernel before
calling into the main kernel, either recursively (trap from kernel
space) or on behalf of a process (trap/syscall from userland)

diffstat:

 sys/arch/i386/i386/trap.c |  52 +++++++++++++++++++++++++++++++++++++++++++---
 1 files changed, 48 insertions(+), 4 deletions(-)

diffs (190 lines):

diff -r 7684aa58fd09 -r f34482d7220d sys/arch/i386/i386/trap.c
--- a/sys/arch/i386/i386/trap.c Fri Aug 18 13:54:25 2000 +0000
+++ b/sys/arch/i386/i386/trap.c Fri Aug 18 13:55:44 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: trap.c,v 1.134.2.3 2000/08/07 01:08:50 sommerfeld Exp $        */
+/*     $NetBSD: trap.c,v 1.134.2.4 2000/08/18 13:55:44 sommerfeld Exp $        */
 
 /*-
  * Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -183,6 +183,7 @@
        /* take pending signals */
        while ((sig = CURSIG(p)) != 0)
                postsig(sig);
+
        p->p_priority = p->p_usrpri;
        if (want_resched) {
                /*
@@ -366,12 +367,16 @@
        case T_STKFLT|T_USER:
        case T_ALIGNFLT|T_USER:
        case T_NMI|T_USER:
+               KERNEL_PROC_LOCK(p);
                trapsignal(p, SIGBUS, type &~ T_USER);
+               KERNEL_PROC_UNLOCK(p);          
                goto out;
 
        case T_PRIVINFLT|T_USER:        /* privileged instruction fault */
        case T_FPOPFLT|T_USER:          /* coprocessor operand fault */
+               KERNEL_PROC_LOCK(p);
                trapsignal(p, SIGILL, type &~ T_USER);
+               KERNEL_PROC_UNLOCK(p);
                goto out;
 
        case T_ASTFLT|T_USER:           /* Allow process switch */
@@ -390,12 +395,16 @@
                                goto trace;
                        return;
                }
+               KERNEL_PROC_LOCK(p);
                trapsignal(p, rv, type &~ T_USER);
+               KERNEL_PROC_UNLOCK(p);
                goto out;
 #else
                printf("pid %d killed due to lack of floating point\n",
                    p->p_pid);
+               KERNEL_PROC_LOCK(p);            
                trapsignal(p, SIGKILL, type &~ T_USER);
+               KERNEL_PROC_UNLOCK(p);          
                goto out;
 #endif
        }
@@ -403,16 +412,28 @@
        case T_BOUND|T_USER:
        case T_OFLOW|T_USER:
        case T_DIVIDE|T_USER:
+               KERNEL_PROC_LOCK(p);            
                trapsignal(p, SIGFPE, type &~ T_USER);
+               KERNEL_PROC_UNLOCK(p);          
                goto out;
 
        case T_ARITHTRAP|T_USER:
+               KERNEL_PROC_LOCK(p);            
                trapsignal(p, SIGFPE, frame.tf_err);
+               KERNEL_PROC_UNLOCK(p);          
                goto out;
 
        case T_PAGEFLT:                 /* allow page faults in kernel mode */
                if (p == 0)
                        goto we_re_toast;
+
+               /*
+                * process doing kernel-mode page fault must have
+                * been running with big lock held
+                */
+               if ((p->p_flag & P_BIGLOCK) == 0)
+                       goto we_re_toast;
+
                pcb = &p->p_addr->u_pcb;
                /*
                 * fusubail is used by [fs]uswintr() to prevent page faulting
@@ -425,17 +446,21 @@
                if (frame.tf_err & PGEX_P)
                        goto we_re_toast;
 #endif
-               /* FALLTHROUGH */
+               KERNEL_LOCK(LK_CANRECURSE|LK_EXCLUSIVE);
+               goto faultcommon;
 
        case T_PAGEFLT|T_USER: {        /* page fault */
                register vaddr_t va;
-               register struct vmspace *vm = p->p_vmspace;
+               register struct vmspace *vm;
                register vm_map_t map;
                int rv;
                vm_prot_t ftype;
                extern vm_map_t kernel_map;
                unsigned nss;
 
+               KERNEL_PROC_LOCK(p);
+       faultcommon:
+               vm = p->p_vmspace;
                if (vm == NULL)
                        goto we_re_toast;
                va = trunc_page((vaddr_t)rcr2());
@@ -488,8 +513,11 @@
                        if (nss > vm->vm_ssize)
                                vm->vm_ssize = nss;
 
-                       if (type == T_PAGEFLT)
+                       if (type == T_PAGEFLT) {
+                               KERNEL_UNLOCK();
                                return;
+                       }
+                       KERNEL_PROC_UNLOCK(p);
                        goto out;
                }
 
@@ -500,6 +528,7 @@
                            map, va, ftype, rv);
                        goto we_re_toast;
                }
+
                if (rv == KERN_RESOURCE_SHORTAGE) {
                        printf("UVM: pid %d (%s), uid %d killed: out of swap\n",
                               p->p_pid, p->p_comm,
@@ -509,6 +538,10 @@
                } else {
                        trapsignal(p, SIGSEGV, T_PAGEFLT);
                }
+               if (type == T_PAGEFLT)
+                       KERNEL_UNLOCK();
+               else
+                       KERNEL_PROC_UNLOCK(p);
                break;
        }
 
@@ -524,7 +557,9 @@
 #ifdef MATH_EMULATE
        trace:
 #endif
+               KERNEL_PROC_LOCK(p);
                trapsignal(p, SIGTRAP, type &~ T_USER);
+               KERNEL_PROC_UNLOCK(p);
                break;
 
 #if    NISA > 0 || NMCA > 0
@@ -566,6 +601,10 @@
 }
 
 #if defined(I386_CPU)
+
+#ifdef MULTIPROCESSOR
+/* XXX XXX XXX */
+#endif
 /*
  * Compensate for 386 brain damage (missing URKR)
  */
@@ -753,6 +792,7 @@
                                goto bad;
                }
        }
+       KERNEL_PROC_LOCK(p);
 #ifdef SYSCALL_DEBUG
        scdebug_call(p, code, args);
 #endif /* SYSCALL_DEBUG */
@@ -768,6 +808,7 @@
                /*
                 * Reinitialize proc pointer `p' as it may be different
                 * if this is a child returning from fork syscall.
+                * XXX is this still needed??
                 */
                p = curproc;
                frame.tf_eax = rval[0];
@@ -800,6 +841,7 @@
 #ifdef SYSCALL_DEBUG
        scdebug_ret(p, code, error, rval);
 #endif /* SYSCALL_DEBUG */
+       KERNEL_PROC_UNLOCK(p);
        userret(p, frame.tf_eip, sticks);
 #ifdef KTRACE
        if (KTRPOINT(p, KTR_SYSRET))
@@ -817,6 +859,8 @@
        tf->tf_eax = 0;
        tf->tf_eflags &= ~PSL_C;
 
+       KERNEL_PROC_UNLOCK(p);
+
        userret(p, tf->tf_eip, 0);
 #ifdef KTRACE
        if (KTRPOINT(p, KTR_SYSRET))



Home | Main Index | Thread Index | Old Index