kernel - Fix signal delivery races
authorMatthew Dillon <dillon@apollo.backplane.com>
Fri, 29 Jul 2011 08:19:29 +0000 (01:19 -0700)
committerMatthew Dillon <dillon@apollo.backplane.com>
Fri, 29 Jul 2011 08:19:29 +0000 (01:19 -0700)
* The send side was using p->p_token but the processing code from trap
  was still using the mp_lock.  Fix the trap processing code to use
  p->p_token.

* This fixes several nasty races that can cause signals to be lost and
  vkernels to freeze, and possibly other programs which depend on signals
  between threads.

sys/kern/kern_sig.c
sys/platform/pc32/i386/trap.c
sys/platform/pc64/x86_64/trap.c
sys/platform/vkernel/i386/trap.c
sys/platform/vkernel64/x86_64/trap.c

index d82b1a9..e5651b8 100644 (file)
@@ -1916,6 +1916,8 @@ issignal(struct lwp *lp, int maytrace)
 /*
  * Take the action for the specified signal
  * from the current set of pending signals.
+ *
+ * Caller must hold p->p_token
  */
 void
 postsig(int sig)
index 2e2e502..b2c3b8f 100644 (file)
@@ -274,10 +274,10 @@ recheck:
         * to restore the virtual kernel's vmspace before posting the upcall.
         */
        if (p->p_flag & P_UPCALLPEND) {
+               lwkt_gettoken(&p->p_token);
                p->p_flag &= ~P_UPCALLPEND;
-               get_mplock();
                postupcall(lp);
-               rel_mplock();
+               lwkt_reltoken(&p->p_token);
                goto recheck;
        }
 
@@ -288,9 +288,9 @@ recheck:
         * WARNING!  postsig() can exit and not return.
         */
        if ((sig = CURSIG_TRACE(lp)) != 0) {
-               get_mplock();
+               lwkt_gettoken(&p->p_token);
                postsig(sig);
-               rel_mplock();
+               lwkt_reltoken(&p->p_token);
                goto recheck;
        }
 
index 16e2831..a0e0b87 100644 (file)
@@ -238,10 +238,10 @@ recheck:
         * to restore the virtual kernel's vmspace before posting the upcall.
         */
        if (p->p_flag & P_UPCALLPEND) {
+               lwkt_gettoken(&p->p_token);
                p->p_flag &= ~P_UPCALLPEND;
-               get_mplock();
                postupcall(lp);
-               rel_mplock();
+               lwkt_reltoken(&p->p_token);
                goto recheck;
        }
 
@@ -252,9 +252,9 @@ recheck:
         * WARNING!  postsig() can exit and not return.
         */
        if ((sig = CURSIG_TRACE(lp)) != 0) {
-               get_mplock();
+               lwkt_gettoken(&p->p_token);
                postsig(sig);
-               rel_mplock();
+               lwkt_reltoken(&p->p_token);
                goto recheck;
        }
 
index ff69ae1..fc025de 100644 (file)
@@ -247,10 +247,10 @@ recheck:
         * Post any pending upcalls
         */
        if (p->p_flag & P_UPCALLPEND) {
-               get_mplock();
+               lwkt_gettoken(&p->p_token);
                p->p_flag &= ~P_UPCALLPEND;
                postupcall(lp);
-               rel_mplock();
+               lwkt_reltoken(&p->p_token);
                goto recheck;
        }
 
@@ -260,9 +260,9 @@ recheck:
         * WARNING!  postsig() can exit and not return.
         */
        if ((sig = CURSIG_TRACE(lp)) != 0) {
-               get_mplock();
+               lwkt_gettoken(&p->p_token);
                postsig(sig);
-               rel_mplock();
+               lwkt_reltoken(&p->p_token);
                goto recheck;
        }
 
index e481861..ca73b68 100644 (file)
@@ -247,10 +247,10 @@ recheck:
         * Post any pending upcalls
         */
        if (p->p_flag & P_UPCALLPEND) {
-               get_mplock();
+               lwkt_gettoken(&p->p_token);
                p->p_flag &= ~P_UPCALLPEND;
                postupcall(lp);
-               rel_mplock();
+               lwkt_reltoken(&p->p_token);
                goto recheck;
        }
 
@@ -260,9 +260,9 @@ recheck:
         * WARNING!  postsig() can exit and not return.
         */
        if ((sig = CURSIG_TRACE(lp)) != 0) {
-               get_mplock();
+               lwkt_gettoken(&p->p_token);
                postsig(sig);
-               rel_mplock();
+               lwkt_reltoken(&p->p_token);
                goto recheck;
        }