tech-kern archive

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

Re: final -- I think -- opencrypto mutex/condvar patch



On Sun, Feb 03, 2008 at 03:24:08PM -0500, Thor Lancelot Simon wrote:
> 
> Patch attached and at http://www.panix.com/~tls/ocf-mtx6.diff

Of course my usual idiocy this time was that half the patch made it.
Attached, for real.

Thor
Index: opencrypto/crypto.c
===================================================================
RCS file: /cvsroot/src/sys/opencrypto/crypto.c,v
retrieving revision 1.22
diff -u -p -r1.22 crypto.c
--- opencrypto/crypto.c 1 Feb 2008 04:52:35 -0000       1.22
+++ opencrypto/crypto.c 3 Feb 2008 20:25:58 -0000
@@ -26,9 +26,6 @@
 #include <sys/cdefs.h>
 __KERNEL_RCSID(0, "$NetBSD: crypto.c,v 1.22 2008/02/01 04:52:35 tls Exp $");
 
-/* XXX FIXME: should be defopt'ed */
-#define CRYPTO_TIMING                  /* enable cryptop timing stuff */
-
 #include <sys/param.h>
 #include <sys/reboot.h>
 #include <sys/systm.h>
@@ -40,11 +37,14 @@ __KERNEL_RCSID(0, "$NetBSD: crypto.c,v 1
 #include <sys/sysctl.h>
 #include <sys/intr.h>
 
+#include "opt_ocf.h"
 #include <opencrypto/cryptodev.h>
 #include <opencrypto/xform.h>                  /* XXX for M_XDATA */
 
-  #define splcrypto splnet
-  /* below is kludges to check whats still missing */
+kcondvar_t cryptoret_cv;
+kmutex_t crypto_mtx;
+
+/* below are kludges for residual code wrtitten to FreeBSD interfaces */
   #define SWI_CRYPTO 17
   #define register_swi(lvl, fn)  \
   softint_establish(SOFTINT_NET, (void (*)(void*))fn, NULL)
@@ -78,18 +78,57 @@ static      TAILQ_HEAD(,cryptkop) crp_kq =
  * but have two to avoid type futzing (cryptop vs. cryptkop).  See below
  * for how synchronization is handled.
  */
-static TAILQ_HEAD(,cryptop) crp_ret_q =        /* callback queues */
+static TAILQ_HEAD(crprethead, cryptop) crp_ret_q =     /* callback queues */
                TAILQ_HEAD_INITIALIZER(crp_ret_q);
-static TAILQ_HEAD(,cryptkop) crp_ret_kq =
+static TAILQ_HEAD(krprethead, cryptkop) crp_ret_kq =
                TAILQ_HEAD_INITIALIZER(crp_ret_kq);
 
 /*
+ * XXX these functions are ghastly hacks for when the submission
+ * XXX routines discover a request that was not CBIMM is already
+ * XXX done, and must be yanked from the retq (where _done) put it
+ * XXX as cryptoret won't get the chance.  The queue is walked backwards
+ * XXX as the request is generally the last one queued.
+ *
+ *      call with the lock held, or else.
+ */
+int
+crypto_ret_q_remove(struct cryptop *crp)
+{
+       struct cryptop * acrp;
+
+       TAILQ_FOREACH_REVERSE(acrp, &crp_ret_q, crprethead, crp_next) {
+               if (acrp == crp) {
+                       TAILQ_REMOVE(&crp_ret_q, crp, crp_next);
+                       crp->crp_flags &= (~CRYPTO_F_ONRETQ);
+                       return 1;
+               }
+       }
+       return 0;
+}
+
+int
+crypto_ret_kq_remove(struct cryptkop *krp)
+{
+       struct cryptkop * akrp;
+
+       TAILQ_FOREACH_REVERSE(akrp, &crp_ret_kq, krprethead, krp_next) {
+               if (akrp == krp) {
+                       TAILQ_REMOVE(&crp_ret_kq, krp, krp_next);
+                       krp->krp_flags &= (~CRYPTO_F_ONRETQ);
+                       return 1;
+               }
+       }
+       return 0;
+}
+
+/*
  * Crypto op and desciptor data structures are allocated
  * from separate private zones(FreeBSD)/pools(netBSD/OpenBSD) .
  */
 struct pool cryptop_pool;
 struct pool cryptodesc_pool;
-int crypto_pool_initialized = 0;
+struct pool cryptkop_pool;
 
 int    crypto_usercrypto = 1;          /* userland may open /dev/crypto */
 int    crypto_userasymcrypto = 1;      /* userland may do asym crypto reqs */
@@ -170,14 +209,23 @@ static    int crypto_invoke(struct cryptop 
 static int crypto_kinvoke(struct cryptkop *krp, int hint);
 
 static struct cryptostats cryptostats;
+#ifdef CRYPTO_TIMING
 static int crypto_timing = 0;
-
+#endif
 
 static int
 crypto_init0(void)
 {
        int error;
 
+       mutex_init(&crypto_mtx, MUTEX_DEFAULT, IPL_NET);
+       cv_init(&cryptoret_cv, "crypto_wait");
+       pool_init(&cryptop_pool, sizeof(struct cryptop), 0, 0,  
+                 0, "cryptop", NULL, IPL_NET); 
+       pool_init(&cryptodesc_pool, sizeof(struct cryptodesc), 0, 0,
+                 0, "cryptodesc", NULL, IPL_NET);
+       pool_init(&cryptkop_pool, sizeof(struct cryptkop), 0, 0,
+                 0, "cryptkop", NULL, IPL_NET);
 
        crypto_drivers = malloc(CRYPTO_DRIVERS_INITIAL *
            sizeof(struct cryptocap), M_CRYPTO_DATA, M_NOWAIT | M_ZERO);
@@ -217,7 +265,7 @@ crypto_destroy(void)
 }
 
 /*
- * Create a new session.
+ * Create a new session.  Must be called with crypto_mtx held.
  */
 int
 crypto_newsession(u_int64_t *sid, struct cryptoini *cri, int hard)
@@ -225,9 +273,8 @@ crypto_newsession(u_int64_t *sid, struct
        struct cryptoini *cr;
        u_int32_t hid, lid;
        int err = EINVAL;
-       int s;
 
-       s = splcrypto();
+       KASSERT(mutex_owned(&crypto_mtx));
 
        if (crypto_drivers == NULL)
                goto done;
@@ -288,22 +335,20 @@ crypto_newsession(u_int64_t *sid, struct
                }
        }
 done:
-       splx(s);
        return err;
 }
 
 /*
  * Delete an existing session (or a reserved session on an unregistered
- * driver).
+ * driver).  Must be called with crypto_mtx mutex held.
  */
 int
 crypto_freesession(u_int64_t sid)
 {
        u_int32_t hid;
        int err = 0;
-       int s;
 
-       s = splcrypto();
+       KASSERT(mutex_owned(&crypto_mtx));
 
        if (crypto_drivers == NULL) {
                err = EINVAL;
@@ -322,9 +367,10 @@ crypto_freesession(u_int64_t sid)
                crypto_drivers[hid].cc_sessions--;
 
        /* Call the driver cleanup routine, if available. */
-       if (crypto_drivers[hid].cc_freesession)
+       if (crypto_drivers[hid].cc_freesession) {
                err = crypto_drivers[hid].cc_freesession(
                                crypto_drivers[hid].cc_arg, sid);
+       }
        else
                err = 0;
 
@@ -337,7 +383,6 @@ crypto_freesession(u_int64_t sid)
                bzero(&crypto_drivers[hid], sizeof(struct cryptocap));
 
 done:
-       splx(s);
        return err;
 }
 
@@ -349,11 +394,11 @@ int32_t
 crypto_get_driverid(u_int32_t flags)
 {
        struct cryptocap *newdrv;
-       int i, s;
+       int i;
 
-       crypto_init();
+       crypto_init();          /* XXX oh, this is foul! */
 
-       s = splcrypto();
+       mutex_spin_enter(&crypto_mtx);
        for (i = 0; i < crypto_drivers_num; i++)
                if (crypto_drivers[i].cc_process == NULL &&
                    (crypto_drivers[i].cc_flags & CRYPTOCAP_F_CLEANUP) == 0 &&
@@ -364,7 +409,7 @@ crypto_get_driverid(u_int32_t flags)
        if (i == crypto_drivers_num) {
                /* Be careful about wrap-around. */
                if (2 * crypto_drivers_num <= crypto_drivers_num) {
-                       splx(s);
+                       mutex_spin_exit(&crypto_mtx);
                        printf("crypto: driver count wraparound!\n");
                        return -1;
                }
@@ -372,7 +417,7 @@ crypto_get_driverid(u_int32_t flags)
                newdrv = malloc(2 * crypto_drivers_num *
                    sizeof(struct cryptocap), M_CRYPTO_DATA, M_NOWAIT|M_ZERO);
                if (newdrv == NULL) {
-                       splx(s);
+                       mutex_spin_exit(&crypto_mtx);
                        printf("crypto: no space to expand driver table!\n");
                        return -1;
                }
@@ -393,7 +438,7 @@ crypto_get_driverid(u_int32_t flags)
        if (bootverbose)
                printf("crypto: assign driver %u, flags %u\n", i, flags);
 
-       splx(s);
+       mutex_spin_exit(&crypto_mtx);
 
        return i;
 }
@@ -415,11 +460,10 @@ crypto_kregister(u_int32_t driverid, int
     int (*kprocess)(void*, struct cryptkop *, int),
     void *karg)
 {
-       int s;
        struct cryptocap *cap;
        int err;
 
-       s = splcrypto();
+       mutex_spin_enter(&crypto_mtx);
 
        cap = crypto_checkdriver(driverid);
        if (cap != NULL &&
@@ -431,12 +475,14 @@ crypto_kregister(u_int32_t driverid, int
                 */
 
                cap->cc_kalg[kalg] = flags | CRYPTO_ALG_FLAG_SUPPORTED;
-               if (bootverbose)
-                       printf("crypto: driver %u registers key alg %u flags 
%u\n"
-                               , driverid
-                               , kalg
-                               , flags
+               if (bootverbose) {
+                       printf("crypto: driver %u registers key alg %u "
+                              " flags %u\n",
+                               driverid,
+                               kalg,
+                               flags
                        );
+               }
 
                if (cap->cc_kprocess == NULL) {
                        cap->cc_karg = karg;
@@ -446,7 +492,7 @@ crypto_kregister(u_int32_t driverid, int
        } else
                err = EINVAL;
 
-       splx(s);
+       mutex_spin_exit(&crypto_mtx);
        return err;
 }
 
@@ -463,9 +509,9 @@ crypto_register(u_int32_t driverid, int 
     void *arg)
 {
        struct cryptocap *cap;
-       int s, err;
+       int err;
 
-       s = splcrypto();
+       mutex_spin_enter(&crypto_mtx);
 
        cap = crypto_checkdriver(driverid);
        /* NB: algorithms are in the range [1..max] */
@@ -479,13 +525,15 @@ crypto_register(u_int32_t driverid, int 
 
                cap->cc_alg[alg] = flags | CRYPTO_ALG_FLAG_SUPPORTED;
                cap->cc_max_op_len[alg] = maxoplen;
-               if (bootverbose)
-                       printf("crypto: driver %u registers alg %u flags %u 
maxoplen %u\n"
-                               , driverid
-                               , alg
-                               , flags
-                               , maxoplen
+               if (bootverbose) {
+                       printf("crypto: driver %u registers alg %u "
+                               "flags %u maxoplen %u\n",
+                               driverid,
+                               alg,
+                               flags,
+                               maxoplen
                        );
+               }
 
                if (cap->cc_process == NULL) {
                        cap->cc_arg = arg;
@@ -498,7 +546,7 @@ crypto_register(u_int32_t driverid, int 
        } else
                err = EINVAL;
 
-       splx(s);
+       mutex_spin_exit(&crypto_mtx);
        return err;
 }
 
@@ -511,11 +559,11 @@ crypto_register(u_int32_t driverid, int 
 int
 crypto_unregister(u_int32_t driverid, int alg)
 {
-       int i, err, s;
+       int i, err;
        u_int32_t ses;
        struct cryptocap *cap;
 
-       s = splcrypto();
+       mutex_spin_enter(&crypto_mtx);
 
        cap = crypto_checkdriver(driverid);
        if (cap != NULL &&
@@ -544,7 +592,7 @@ crypto_unregister(u_int32_t driverid, in
        } else
                err = EINVAL;
 
-       splx(s);
+       mutex_spin_exit(&crypto_mtx);
        return err;
 }
 
@@ -554,14 +602,19 @@ crypto_unregister(u_int32_t driverid, in
  * around so that subsequent calls using those sessions will
  * correctly detect the driver has been unregistered and reroute
  * requests.
+ *
+ * XXX careful.  Don't change this to call crypto_unregister() for each
+ * XXX registered algorithm unless you drop the mutex across the calls;
+ * XXX you can't take it recursively.
  */
 int
 crypto_unregister_all(u_int32_t driverid)
 {
-       int i, err, s = splcrypto();
+       int i, err;
        u_int32_t ses;
        struct cryptocap *cap;
 
+       mutex_spin_enter(&crypto_mtx);
        cap = crypto_checkdriver(driverid);
        if (cap != NULL) {
                for (i = CRYPTO_ALGORITHM_MIN; i <= CRYPTO_ALGORITHM_MAX; i++) {
@@ -581,7 +634,7 @@ crypto_unregister_all(u_int32_t driverid
        } else
                err = EINVAL;
 
-       splx(s);
+       mutex_spin_exit(&crypto_mtx);
        return err;
 }
 
@@ -593,9 +646,9 @@ int
 crypto_unblock(u_int32_t driverid, int what)
 {
        struct cryptocap *cap;
-       int needwakeup, err, s;
+       int needwakeup, err;
 
-       s = splcrypto();
+       mutex_spin_enter(&crypto_mtx);
        cap = crypto_checkdriver(driverid);
        if (cap != NULL) {
                needwakeup = 0;
@@ -608,12 +661,13 @@ crypto_unblock(u_int32_t driverid, int w
                        cap->cc_kqblocked = 0;
                }
                if (needwakeup) {
+                       mutex_spin_exit(&crypto_mtx);
                        setsoftcrypto(softintr_cookie);
                }
                err = 0;
        } else
                err = EINVAL;
-       splx(s);
+       mutex_spin_exit(&crypto_mtx);
 
        return err;
 }
@@ -626,9 +680,9 @@ int
 crypto_dispatch(struct cryptop *crp)
 {
        u_int32_t hid = SESID2HID(crp->crp_sid);
-       int s, result;
+       int result;
 
-       s = splcrypto();
+       mutex_spin_enter(&crypto_mtx);
 
        cryptostats.cs_ops++;
 
@@ -645,6 +699,7 @@ crypto_dispatch(struct cryptop *crp)
                 */
                cap = crypto_checkdriver(hid);
                if (cap && !cap->cc_qblocked) {
+                       mutex_spin_exit(&crypto_mtx);
                        result = crypto_invoke(crp, 0);
                        if (result == ERESTART) {
                                /*
@@ -652,10 +707,12 @@ crypto_dispatch(struct cryptop *crp)
                                 * driver ``blocked'' for cryptop's and put
                                 * the op on the queue.
                                 */
+                               mutex_spin_enter(&crypto_mtx);
                                crypto_drivers[hid].cc_qblocked = 1;
                                TAILQ_INSERT_HEAD(&crp_q, crp, crp_next);
                                cryptostats.cs_blocks++;
                        }
+                       goto out_released;
                } else {
                        /*
                         * The driver is blocked, just queue the op until
@@ -674,13 +731,17 @@ crypto_dispatch(struct cryptop *crp)
                 */
                TAILQ_INSERT_TAIL(&crp_q, crp, crp_next);
                if (wasempty) {
+                       mutex_spin_exit(&crypto_mtx);
                        setsoftcrypto(softintr_cookie);
+                       result = 0;
+                       goto out_released;
                }
 
                result = 0;
        }
-       splx(s);
 
+       mutex_spin_exit(&crypto_mtx);
+out_released:
        return result;
 }
 
@@ -692,13 +753,14 @@ int
 crypto_kdispatch(struct cryptkop *krp)
 {
        struct cryptocap *cap;
-       int s, result;
+       int result;
 
-       s = splcrypto();
+       mutex_spin_enter(&crypto_mtx);
        cryptostats.cs_kops++;
 
        cap = crypto_checkdriver(krp->krp_hid);
        if (cap && !cap->cc_kqblocked) {
+               mutex_spin_exit(&crypto_mtx);
                result = crypto_kinvoke(krp, 0);
                if (result == ERESTART) {
                        /*
@@ -706,6 +768,7 @@ crypto_kdispatch(struct cryptkop *krp)
                         * driver ``blocked'' for cryptop's and put
                         * the op on the queue.
                         */
+                       mutex_spin_enter(&crypto_mtx);
                        crypto_drivers[krp->krp_hid].cc_kqblocked = 1;
                        TAILQ_INSERT_HEAD(&crp_kq, krp, krp_next);
                        cryptostats.cs_kblocks++;
@@ -718,7 +781,7 @@ crypto_kdispatch(struct cryptkop *krp)
                TAILQ_INSERT_TAIL(&crp_kq, krp, krp_next);
                result = 0;
        }
-       splx(s);
+       mutex_spin_exit(&crypto_mtx);
 
        return result;
 }
@@ -736,7 +799,7 @@ crypto_kinvoke(struct cryptkop *krp, int
        if (krp == NULL)
                return EINVAL;
        if (krp->krp_callback == NULL) {
-               free(krp, M_XDATA);             /* XXX allocated in cryptodev */
+               pool_put(&cryptkop_pool, krp);
                return EINVAL;
        }
 
@@ -818,9 +881,11 @@ crypto_invoke(struct cryptop *crp, int h
 
        hid = SESID2HID(crp->crp_sid);
        if (hid < crypto_drivers_num) {
+               mutex_enter(&crypto_mtx);
                if (crypto_drivers[hid].cc_flags & CRYPTOCAP_F_CLEANUP)
                        crypto_freesession(crp->crp_sid);
                process = crypto_drivers[hid].cc_process;
+               mutex_exit(&crypto_mtx);
        } else {
                process = NULL;
        }
@@ -833,6 +898,7 @@ crypto_invoke(struct cryptop *crp, int h
                 * Driver has unregistered; migrate the session and return
                 * an error to the caller so they'll resubmit the op.
                 */
+               mutex_enter(&crypto_mtx);
                for (crd = crp->crp_desc; crd->crd_next; crd = crd->crd_next)
                        crd->CRD_INI.cri_next = &(crd->crd_next->CRD_INI);
 
@@ -840,12 +906,15 @@ crypto_invoke(struct cryptop *crp, int h
                        crp->crp_sid = nid;
 
                crp->crp_etype = EAGAIN;
+               mutex_exit(&crypto_mtx);
+
                crypto_done(crp);
                return 0;
        } else {
                /*
                 * Invoke the driver to process the request.
                 */
+               DPRINTF(("calling process for %08x\n", (uint32_t)crp));
                return (*process)(crypto_drivers[hid].cc_arg, crp, hint);
        }
 }
@@ -857,20 +926,15 @@ void
 crypto_freereq(struct cryptop *crp)
 {
        struct cryptodesc *crd;
-       int s;
 
        if (crp == NULL)
                return;
 
-       s = splcrypto();
-
        while ((crd = crp->crp_desc) != NULL) {
                crp->crp_desc = crd->crd_next;
                pool_put(&cryptodesc_pool, crd);
        }
-
        pool_put(&cryptop_pool, crp);
-       splx(s);
 }
 
 /*
@@ -881,29 +945,17 @@ crypto_getreq(int num)
 {
        struct cryptodesc *crd;
        struct cryptop *crp;
-       int s;
-
-       s = splcrypto();
-
-       if (crypto_pool_initialized == 0) {
-               pool_init(&cryptop_pool, sizeof(struct cryptop), 0, 0,
-                   0, "cryptop", NULL, IPL_NET);
-               pool_init(&cryptodesc_pool, sizeof(struct cryptodesc), 0, 0,
-                   0, "cryptodesc", NULL, IPL_NET);
-               crypto_pool_initialized = 1;
-       }
 
        crp = pool_get(&cryptop_pool, 0);
        if (crp == NULL) {
-               splx(s);
                return NULL;
        }
        bzero(crp, sizeof(struct cryptop));
+       cv_init(&crp->crp_cv, "crydev");
 
        while (num--) {
                crd = pool_get(&cryptodesc_pool, 0);
                if (crd == NULL) {
-                       splx(s);
                        crypto_freereq(crp);
                        return NULL;
                }
@@ -913,7 +965,6 @@ crypto_getreq(int num)
                crp->crp_desc = crd;
        }
 
-       splx(s);
        return crp;
 }
 
@@ -923,6 +974,8 @@ crypto_getreq(int num)
 void
 crypto_done(struct cryptop *crp)
 {
+       int wasempty;
+
        if (crp->crp_etype != 0)
                cryptostats.cs_errs++;
 #ifdef CRYPTO_TIMING
@@ -930,26 +983,24 @@ crypto_done(struct cryptop *crp)
                crypto_tstat(&cryptostats.cs_done, &crp->crp_tstamp);
 #endif
        /*
-        * On netbsd 1.6O, CBIMM does its wake_one() before the requestor
-        * has done its tsleep().
+        * Normal case; queue the callback for the thread.
+        *
+        * The return queue is manipulated by the swi thread
+        * and, potentially, by crypto device drivers calling
+        * back to mark operations completed.  Thus we need
+        * to mask both while manipulating the return queue.
         */
-       {
-               int s, wasempty;
-               /*
-                * Normal case; queue the callback for the thread.
-                *
-                * The return queue is manipulated by the swi thread
-                * and, potentially, by crypto device drivers calling
-                * back to mark operations completed.  Thus we need
-                * to mask both while manipulating the return queue.
-                */
-               s = splcrypto();
-               wasempty = TAILQ_EMPTY(&crp_ret_q);
-               TAILQ_INSERT_TAIL(&crp_ret_q, crp, crp_next);
-               if (wasempty)
-                       wakeup_one(&crp_ret_q);
-               splx(s);
+       mutex_spin_enter(&crypto_mtx);
+       wasempty = TAILQ_EMPTY(&crp_ret_q);
+       DPRINTF(("crypto_done: queueing %08x\n", (uint32_t)crp));
+       crp->crp_flags |= CRYPTO_F_ONRETQ|CRYPTO_F_DONE;
+       TAILQ_INSERT_TAIL(&crp_ret_q, crp, crp_next);
+       if (wasempty) {
+               DPRINTF(("crypto_done: waking cryptoret, %08x " \
+                       "hit empty queue\n.", (uint32_t)crp));
+               cv_signal(&cryptoret_cv);
        }
+       mutex_spin_exit(&crypto_mtx);
 }
 
 /*
@@ -958,7 +1009,7 @@ crypto_done(struct cryptop *crp)
 void
 crypto_kdone(struct cryptkop *krp)
 {
-       int s, wasempty;
+       int wasempty;
 
        if (krp->krp_status != 0)
                cryptostats.cs_kerrs++;
@@ -968,21 +1019,21 @@ crypto_kdone(struct cryptkop *krp)
         * back to mark operations completed.  Thus we need
         * to mask both while manipulating the return queue.
         */
-       s = splcrypto();
+       mutex_spin_enter(&crypto_mtx);
        wasempty = TAILQ_EMPTY(&crp_ret_kq);
+       krp->krp_flags |= CRYPTO_F_ONRETQ|CRYPTO_F_DONE;
        TAILQ_INSERT_TAIL(&crp_ret_kq, krp, krp_next);
        if (wasempty)
-               wakeup_one(&crp_ret_q);
-       splx(s);
+               cv_signal(&cryptoret_cv);
+       mutex_spin_exit(&crypto_mtx);
 }
 
 int
 crypto_getfeat(int *featp)
 {
        int hid, kalg, feat = 0;
-       int s;
 
-       s = splcrypto();
+       mutex_spin_enter(&crypto_mtx);
 
        if (crypto_userasymcrypto == 0)
                goto out;
@@ -1000,7 +1051,7 @@ crypto_getfeat(int *featp)
                                feat |=  1 << kalg;
        }
 out:
-       splx(s);
+       mutex_spin_exit(&crypto_mtx);
        *featp = feat;
        return (0);
 }
@@ -1014,11 +1065,11 @@ cryptointr(void)
        struct cryptop *crp, *submit;
        struct cryptkop *krp;
        struct cryptocap *cap;
-       int result, hint, s;
+       int result, hint;
 
        printf("crypto softint\n");
        cryptostats.cs_intrs++;
-       s = splcrypto();
+       mutex_spin_enter(&crypto_mtx);
        do {
                /*
                 * Find the first element in the queue that can be
@@ -1059,7 +1110,11 @@ cryptointr(void)
                }
                if (submit != NULL) {
                        TAILQ_REMOVE(&crp_q, submit, crp_next);
+                       mutex_spin_exit(&crypto_mtx);
                        result = crypto_invoke(submit, hint);
+                       /* we must take here as the TAILQ op or kinvoke
+                          may need this mutex below.  sigh. */
+                       mutex_spin_enter(&crypto_mtx);  
                        if (result == ERESTART) {
                                /*
                                 * The driver ran out of resources, mark the
@@ -1089,7 +1144,10 @@ cryptointr(void)
                }
                if (krp != NULL) {
                        TAILQ_REMOVE(&crp_kq, krp, krp_next);
+                       mutex_spin_exit(&crypto_mtx);
                        result = crypto_kinvoke(krp, 0);
+                       /* the next iteration will want the mutex. :-/ */
+                       mutex_spin_enter(&crypto_mtx);
                        if (result == ERESTART) {
                                /*
                                 * The driver ran out of resources, mark the
@@ -1107,7 +1165,7 @@ cryptointr(void)
                        }
                }
        } while (submit != NULL || krp != NULL);
-       splx(s);
+       mutex_spin_exit(&crypto_mtx);
 }
 
 /*
@@ -1118,19 +1176,24 @@ cryptoret(void)
 {
        struct cryptop *crp;
        struct cryptkop *krp;
-       int s;
 
-       s = splcrypto();
        for (;;) {
+               mutex_spin_enter(&crypto_mtx);
+
                crp = TAILQ_FIRST(&crp_ret_q);
-               if (crp != NULL)
+               if (crp != NULL) {
                        TAILQ_REMOVE(&crp_ret_q, crp, crp_next);
+                       crp->crp_flags &= ~CRYPTO_F_ONRETQ;
+               }
                krp = TAILQ_FIRST(&crp_ret_kq);
-               if (krp != NULL)
+               if (krp != NULL) {
                        TAILQ_REMOVE(&crp_ret_kq, krp, krp_next);
+                       krp->krp_flags &= ~CRYPTO_F_ONRETQ;
+               }
 
+               /* drop before calling any callbacks. */
+               mutex_spin_exit(&crypto_mtx);
                if (crp != NULL || krp != NULL) {
-                       splx(s);                /* lower ipl for callbacks */
                        if (crp != NULL) {
 #ifdef CRYPTO_TIMING
                                if (crypto_timing) {
@@ -1145,18 +1208,23 @@ cryptoret(void)
                                        crypto_tstat(&cryptostats.cs_finis, &t);
                                } else
 #endif
+                               {
+#if 0          /* too loud */
+                                       DCPRINTF(("cryptoret: calling back " \
+                                               "%08x for crp %08x\n", \
+                                               (uint32_t)crp->crp_callback, \
+                                               (uint32_t)crp));
+#endif
                                        crp->crp_callback(crp);
+                               }
                        }
                        if (krp != NULL)
                                krp->krp_callback(krp);
-                       s  = splcrypto();
                } else {
-                       (void) tsleep(&crp_ret_q, PLOCK, "crypto_wait", 0);
+                       mutex_spin_enter(&crypto_mtx);
+                       cv_wait(&cryptoret_cv, &crypto_mtx);
+                       mutex_spin_exit(&crypto_mtx);
                        cryptostats.cs_rets++;
                }
        }
 }
-
-
-
-
Index: opencrypto/cryptodev.c
===================================================================
RCS file: /cvsroot/src/sys/opencrypto/cryptodev.c,v
retrieving revision 1.32
diff -u -p -r1.32 cryptodev.c
--- opencrypto/cryptodev.c      2 Feb 2008 02:39:00 -0000       1.32
+++ opencrypto/cryptodev.c      3 Feb 2008 20:26:00 -0000
@@ -52,16 +52,10 @@ __KERNEL_RCSID(0, "$NetBSD: cryptodev.c,
 #include <sys/device.h>
 #include <sys/kauth.h>
 
+#include "opt_ocf.h"
 #include <opencrypto/cryptodev.h>
 #include <opencrypto/xform.h>
 
-  #define splcrypto splnet
-#ifdef CRYPTO_DEBUG
-#define DPRINTF(a) uprintf a
-#else
-#define DPRINTF(a)
-#endif
-
 struct csession {
        TAILQ_ENTRY(csession) next;
        u_int64_t       sid;
@@ -178,12 +172,14 @@ cryptof_ioctl(struct file *fp, u_long cm
                 if ((error = falloc(l, &criofp, &criofd)) != 0)
                         return error;
                 criofcr = pool_get(&fcrpl, PR_WAITOK);
+               mutex_spin_enter(&crypto_mtx);
                 TAILQ_INIT(&criofcr->csessions);
                 /*
                  * Don't ever return session 0, to allow detection of
                  * failed creation attempts with multi-create ioctl.
                  */
                 criofcr->sesn = 1;
+               mutex_spin_exit(&crypto_mtx);
                 (void)fdclone(l, criofp, criofd, (FREAD|FWRITE),
                              &cryptofops, criofcr);
                 *(u_int32_t *)data = criofd;
@@ -310,7 +306,8 @@ cryptof_ioctl(struct file *fp, u_long cm
                                        goto bail;
                        }
                }
-
+               /* crypto_newsession requires that we hold the mutex. */
+               mutex_spin_enter(&crypto_mtx);
                error = crypto_newsession(&sid, (txform ? &crie : &cria),
                            crypto_devallowsoft);
                if (error) {
@@ -332,6 +329,7 @@ cryptof_ioctl(struct file *fp, u_long cm
                sop->ses = cse->ses;
 
 bail:
+               mutex_spin_exit(&crypto_mtx);
                if (error) {
                        if (crie.cri_key)
                                FREE(crie.cri_key, M_XDATA);
@@ -340,16 +338,20 @@ bail:
                }
                break;
        case CIOCFSESSION:
+               mutex_spin_enter(&crypto_mtx);
                ses = *(u_int32_t *)data;
                cse = csefind(fcr, ses);
                if (cse == NULL)
                        return (EINVAL);
                csedelete(fcr, cse);
                error = csefree(cse);
+               mutex_spin_exit(&crypto_mtx);
                break;
        case CIOCCRYPT:
+               mutex_spin_enter(&crypto_mtx);
                cop = (struct crypt_op *)data;
                cse = csefind(fcr, cop->ses);
+               mutex_spin_exit(&crypto_mtx);
                if (cse == NULL) {
                        DPRINTF(("csefind failed\n"));
                        return (EINVAL);
@@ -374,7 +376,7 @@ cryptodev_op(struct csession *cse, struc
 {
        struct cryptop *crp = NULL;
        struct cryptodesc *crde = NULL, *crda = NULL;
-       int error, s;
+       int error;
 
        if (cop->len > 256*1024-4)
                return (E2BIG);
@@ -480,14 +482,33 @@ cryptodev_op(struct csession *cse, struc
                crp->crp_mac=cse->tmp_mac;
        }
 
-       s = splcrypto();        /* NB: only needed with CRYPTO_F_CBIMM */
+       /*
+        * XXX there was a comment here which said that we went to
+        * XXX splcrypto() but needed to only if CRYPTO_F_CBIMM,
+        * XXX disabled on NetBSD since 1.6O due to a race condition.
+        * XXX But crypto_dispatch went to splcrypto() itself!  (And
+        * XXX now takes the crypto_mtx mutex itself).  We do, however,
+        * XXX need to hold the mutex across the call to cv_wait().
+        * XXX     (should we arrange for crypto_dispatch to return to
+        * XXX      us with it held?  it seems quite ugly to do so.)
+        */
        error = crypto_dispatch(crp);
-       if (error == 0 && (crp->crp_flags & CRYPTO_F_DONE) == 0)
-               error = tsleep(crp, PSOCK, "crydev", 0);
-       splx(s);
-       if (error) {
+       mutex_spin_enter(&crypto_mtx);
+       if (error != 0) {
+               DPRINTF(("cryptodev_op: not waiting, error.\n"));
+               mutex_spin_exit(&crypto_mtx);
                goto bail;
        }
+       while (!(crp->crp_flags & CRYPTO_F_DONE)) {
+               DPRINTF(("cryptodev_op: sleeping on cv %08x for crp %08x\n", \
+                       (uint32_t)&crp->crp_cv, (uint32_t)crp));
+               cv_wait(&crp->crp_cv, &crypto_mtx);     /* XXX cv_wait_sig? */
+       }
+       if (crp->crp_flags & CRYPTO_F_ONRETQ) {
+               DPRINTF(("cryptodev_op: DONE, not woken by cryptoret.\n"));
+               (void)crypto_ret_q_remove(crp);
+       }
+       mutex_spin_exit(&crypto_mtx);
 
        if (crp->crp_etype != 0) {
                error = crp->crp_etype;
@@ -521,11 +542,20 @@ cryptodev_cb(void *op)
 {
        struct cryptop *crp = (struct cryptop *) op;
        struct csession *cse = (struct csession *)crp->crp_opaque;
+       int error = 0;
 
+       mutex_spin_enter(&crypto_mtx);
        cse->error = crp->crp_etype;
-       if (crp->crp_etype == EAGAIN)
-               return crypto_dispatch(crp);
-       wakeup_one(crp);
+       if (crp->crp_etype == EAGAIN) {
+               /* always drop mutex to call dispatch routine */
+               mutex_spin_exit(&crypto_mtx);
+               error = crypto_dispatch(crp);
+               mutex_spin_enter(&crypto_mtx);
+       }
+       if (error != 0 || (crp->crp_flags & CRYPTO_F_DONE)) {
+               cv_signal(&crp->crp_cv);
+       }
+       mutex_spin_exit(&crypto_mtx);
        return (0);
 }
 
@@ -534,7 +564,9 @@ cryptodevkey_cb(void *op)
 {
        struct cryptkop *krp = (struct cryptkop *) op;
 
-       wakeup_one(krp);
+       mutex_spin_enter(&crypto_mtx);
+       cv_signal(&krp->krp_cv);
+       mutex_spin_exit(&crypto_mtx);
        return (0);
 }
 
@@ -600,10 +632,11 @@ cryptodev_key(struct crypt_kop *kop)
                return (EINVAL);
        }
 
-       krp = (struct cryptkop *)malloc(sizeof *krp, M_XDATA, M_WAITOK);
+       krp = pool_get(&cryptkop_pool, PR_WAITOK);
        if (!krp)
                return (ENOMEM);
        bzero(krp, sizeof *krp);
+       cv_init(&krp->krp_cv, "crykdev");
        krp->krp_op = kop->crk_op;
        krp->krp_status = kop->crk_status;
        krp->krp_iparams = kop->crk_iparams;
@@ -626,10 +659,19 @@ cryptodev_key(struct crypt_kop *kop)
        }
 
        error = crypto_kdispatch(krp);
-       if (error == 0)
-               error = tsleep(krp, PSOCK, "crydev", 0);
-       if (error)
+       if (error != 0) {
                goto fail;
+       }
+
+       mutex_spin_enter(&crypto_mtx);
+       while (!(krp->krp_flags & CRYPTO_F_DONE)) {
+               cv_wait(&krp->krp_cv, &crypto_mtx);     /* XXX cv_wait_sig? */
+       }
+       if (krp->krp_flags & CRYPTO_F_ONRETQ) {
+               DPRINTF(("cryptodev_key: DONE early, not via cryptoret.\n"));
+               (void)crypto_ret_kq_remove(krp);
+       }
+       mutex_spin_exit(&crypto_mtx);
 
        if (krp->krp_status != 0) {
                error = krp->krp_status;
@@ -652,7 +694,7 @@ fail:
                        if (krp->krp_param[i].crp_p)
                                FREE(krp->krp_param[i].crp_p, M_XDATA);
                }
-               free(krp, M_XDATA);
+               pool_put(&cryptkop_pool, krp);
        }
        return (error);
 }
@@ -664,6 +706,7 @@ cryptof_close(struct file *fp, struct lw
        struct fcrypt *fcr = (struct fcrypt *)fp->f_data;
        struct csession *cse;
 
+       mutex_spin_enter(&crypto_mtx);
        while ((cse = TAILQ_FIRST(&fcr->csessions))) {
                TAILQ_REMOVE(&fcr->csessions, cse, next);
                (void)csefree(cse);
@@ -671,43 +714,54 @@ cryptof_close(struct file *fp, struct lw
        pool_put(&fcrpl, fcr);
 
        fp->f_data = NULL;
+       mutex_spin_exit(&crypto_mtx);
 
        return 0;
 }
 
+/* csefind: call with crypto_mtx held. */
 static struct csession *
 csefind(struct fcrypt *fcr, u_int ses)
 {
-       struct csession *cse;
+       struct csession *cse, *ret = NULL;
 
+       KASSERT(mutex_owned(&crypto_mtx));
        TAILQ_FOREACH(cse, &fcr->csessions, next)
                if (cse->ses == ses)
-                       return (cse);
-       return (NULL);
+                       ret = cse;
+       return (ret);
 }
 
+/* csedelete: call with crypto_mtx held. */
 static int
 csedelete(struct fcrypt *fcr, struct csession *cse_del)
 {
        struct csession *cse;
+       int ret = 0;
 
+       KASSERT(mutex_owned(&crypto_mtx));
        TAILQ_FOREACH(cse, &fcr->csessions, next) {
                if (cse == cse_del) {
                        TAILQ_REMOVE(&fcr->csessions, cse, next);
-                       return (1);
+                       ret = 1;
                }
        }
-       return (0);
+       return (ret);
 }
 
+/* cseadd: call with crypto_mtx held. */
 static struct csession *
 cseadd(struct fcrypt *fcr, struct csession *cse)
 {
+       KASSERT(mutex_owned(&crypto_mtx));
+       /* don't let session ID wrap! */
+       if (fcr->sesn + 1 == 0) return NULL;
        TAILQ_INSERT_TAIL(&fcr->csessions, cse, next);
        cse->ses = fcr->sesn++;
        return (cse);
 }
 
+/* csecreate: call with crypto_mtx held. */
 static struct csession *
 csecreate(struct fcrypt *fcr, u_int64_t sid, void *key, u_int64_t keylen,
     void *mackey, u_int64_t mackeylen, u_int32_t cipher, u_int32_t mac,
@@ -715,10 +769,7 @@ csecreate(struct fcrypt *fcr, u_int64_t 
 {
        struct csession *cse;
 
-       /* Don't let the session ID wrap! */
-       if (fcr->sesn + 1 == 0)
-               return NULL;
-
+       KASSERT(mutex_owned(&crypto_mtx));
        cse = pool_get(&csepl, PR_NOWAIT);
        if (cse == NULL)
                return NULL;
@@ -734,16 +785,18 @@ csecreate(struct fcrypt *fcr, u_int64_t 
        if (cseadd(fcr, cse))
                return (cse);
        else {
-               FREE(cse, M_XDATA);
+               pool_put(&csepl, cse);
                return NULL;
        }
 }
 
+/* csefree: call with crypto_mtx held. */
 static int
 csefree(struct csession *cse)
 {
        int error;
 
+       KASSERT(mutex_owned(&crypto_mtx));
        error = crypto_freesession(cse->sid);
        if (cse->key)
                FREE(cse->key, M_XDATA);
@@ -768,12 +821,14 @@ cryptoopen(dev_t dev, int flag, int mode
                return error;
 
        fcr = pool_get(&fcrpl, PR_WAITOK);
+       mutex_spin_enter(&crypto_mtx);
        TAILQ_INIT(&fcr->csessions);
        /*
         * Don't ever return session 0, to allow detection of
         * failed creation attempts with multi-create ioctl.
         */
        fcr->sesn = 1;
+       mutex_spin_exit(&crypto_mtx);
        return fdclone(l, fp, fd, flag, &cryptofops, fcr);
 }
 
Index: opencrypto/cryptodev.h
===================================================================
RCS file: /cvsroot/src/sys/opencrypto/cryptodev.h,v
retrieving revision 1.11
diff -u -p -r1.11 cryptodev.h
--- opencrypto/cryptodev.h      2 Feb 2008 02:39:00 -0000       1.11
+++ opencrypto/cryptodev.h      3 Feb 2008 20:26:00 -0000
@@ -282,6 +282,7 @@ struct cryptop {
 #define        CRYPTO_F_CBIMM          0x0010  /* Do callback immediately */
 #define        CRYPTO_F_DONE           0x0020  /* Operation completed */
 #define        CRYPTO_F_CBIFSYNC       0x0040  /* Do CBIMM if op is 
synchronous */
+#define        CRYPTO_F_ONRETQ         0x0080  /* Request is on return queue */
 
        void *          crp_buf;        /* Data to be processed */
        void *          crp_opaque;     /* Opaque pointer, passed along */
@@ -291,6 +292,7 @@ struct cryptop {
 
        void *          crp_mac;
        struct timespec crp_tstamp;     /* performance time stamp */
+       kcondvar_t      crp_cv;
 };
 
 #define CRYPTO_BUF_CONTIG      0x0
@@ -315,6 +317,8 @@ struct cryptkop {
        u_int32_t       krp_hid;
        struct crparam  krp_param[CRK_MAXPARAM];        /* kvm */
        int             (*krp_callback)(struct cryptkop *);
+       int             krp_flags;      /* same values as crp_flags */
+       kcondvar_t      krp_cv;
 };
 
 /* Crypto capabilities structure */
@@ -387,6 +391,8 @@ void        cuio_copyback(struct uio *, int, in
 int    cuio_apply(struct uio *, int, int,
            int (*f)(void *, void *, unsigned int), void *);
 
+extern int crypto_ret_q_remove(struct cryptop *);
+extern int crypto_ret_kq_remove(struct cryptkop *);
 extern void crypto_freereq(struct cryptop *crp);
 extern struct cryptop *crypto_getreq(int num);
 
@@ -394,6 +400,17 @@ extern     int crypto_usercrypto;          /* userla
 extern int crypto_userasymcrypto;      /* userland may do asym crypto reqs */
 extern int crypto_devallowsoft;        /* only use hardware crypto */
 
+/*
+ * Asymmetric operations are allocated in cryptodev.c but can be
+ * freed in crypto.c.
+ */
+extern struct pool     cryptkop_pool;
+
+/*
+ * Mutual exclusion and its unwelcome friends.
+ */
+
+extern kmutex_t        crypto_mtx;
 
 /*
  * initialize the crypto framework subsystem (not the pseudo-device).
@@ -418,6 +435,21 @@ extern     void cuio_copydata(struct uio* ui
 extern void cuio_copyback(struct uio* uio, int off, int len, void *cp);
 extern int     cuio_getptr(struct uio *, int loc, int *off);
 
+#ifdef CRYPTO_DEBUG    /* yuck, netipsec defines these differently */
+#ifndef DPRINTF
+#define DPRINTF(a) uprintf a
+#endif
+#ifndef DCPRINTF
+#define DCPRINTF(a) printf a
+#endif
+#else
+#ifndef DPRINTF
+#define DPRINTF(a)
+#endif
+#ifndef DCPRINTF
+#define DCPRINTF(a)
+#endif
+#endif
 
 #endif /* _KERNEL */
 #endif /* _CRYPTO_CRYPTO_H_ */
Index: opencrypto/cryptosoft.c
===================================================================
RCS file: /cvsroot/src/sys/opencrypto/cryptosoft.c,v
retrieving revision 1.19
diff -u -p -r1.19 cryptosoft.c
--- opencrypto/cryptosoft.c     2 Feb 2008 04:46:29 -0000       1.19
+++ opencrypto/cryptosoft.c     3 Feb 2008 20:26:00 -0000
@@ -33,6 +33,7 @@ __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c
 #include <sys/sysctl.h>
 #include <sys/errno.h>
 
+#include "opt_ocf.h"
 #include <opencrypto/cryptodev.h>
 #include <opencrypto/cryptosoft.h>
 #include <opencrypto/xform.h>
@@ -1008,6 +1009,7 @@ swcr_process(void *arg, struct cryptop *
        }
 
 done:
+       DPRINTF(("request %08x done\n", (uint32_t)crp));
        crypto_done(crp);
        return 0;
 }
Index: opencrypto/cryptosoft_xform.c
===================================================================
RCS file: /cvsroot/src/sys/opencrypto/cryptosoft_xform.c,v
retrieving revision 1.7
diff -u -p -r1.7 cryptosoft_xform.c
--- opencrypto/cryptosoft_xform.c       2 Feb 2008 02:39:00 -0000       1.7
+++ opencrypto/cryptosoft_xform.c       3 Feb 2008 20:26:00 -0000
@@ -326,9 +326,8 @@ des1_setkey(u_int8_t **sched, const u_in
        int err;
 
        MALLOC(p, des_key_schedule *, sizeof (des_key_schedule),
-               M_CRYPTO_DATA, M_NOWAIT);
+               M_CRYPTO_DATA, M_NOWAIT|M_ZERO);
        if (p != NULL) {
-               bzero(p, sizeof(des_key_schedule));
                des_set_key((des_cblock *)__UNCONST(key), p[0]);
                err = 0;
        } else
@@ -370,9 +369,8 @@ des3_setkey(u_int8_t **sched, const u_in
        int err;
 
        MALLOC(p, des_key_schedule *, 3*sizeof (des_key_schedule),
-               M_CRYPTO_DATA, M_NOWAIT);
+               M_CRYPTO_DATA, M_NOWAIT|M_ZERO);
        if (p != NULL) {
-               bzero(p, 3*sizeof(des_key_schedule));
                des_set_key((des_cblock *)__UNCONST(key +  0), p[0]);
                des_set_key((des_cblock *)__UNCONST(key +  8), p[1]);
                des_set_key((des_cblock *)__UNCONST(key + 16), p[2]);
@@ -395,22 +393,14 @@ static void
 blf_encrypt(void *key, u_int8_t *blk)
 {
 
-#if defined(__NetBSD__)
        BF_ecb_encrypt(blk, blk, (BF_KEY *)key, 1);
-#else
-       blf_ecb_encrypt((blf_ctx *) key, blk, 8);
-#endif
 }
 
 static void
 blf_decrypt(void *key, u_int8_t *blk)
 {
 
-#if defined(__NetBSD__)
        BF_ecb_encrypt(blk, blk, (BF_KEY *)key, 0);
-#else
-       blf_ecb_decrypt((blf_ctx *) key, blk, 8);
-#endif
 }
 
 static int
@@ -418,21 +408,10 @@ blf_setkey(u_int8_t **sched, const u_int
 {
        int err;
 
-#if defined(__FreeBSD__) || defined(__NetBSD__)
-#define        BLF_SIZ sizeof(BF_KEY)
-#else
-#define        BLF_SIZ sizeof(blf_ctx)
-#endif
-
-       MALLOC(*sched, u_int8_t *, BLF_SIZ,
-               M_CRYPTO_DATA, M_NOWAIT);
+       MALLOC(*sched, u_int8_t *, sizeof(BF_KEY),
+               M_CRYPTO_DATA, M_NOWAIT|M_ZERO);
        if (*sched != NULL) {
-               bzero(*sched, BLF_SIZ);
-#if defined(__FreeBSD__) || defined(__NetBSD__)
                BF_set_key((BF_KEY *) *sched, len, key);
-#else
-               blf_key((blf_ctx *)*sched, key, len);
-#endif
                err = 0;
        } else
                err = ENOMEM;
@@ -442,7 +421,7 @@ blf_setkey(u_int8_t **sched, const u_int
 static void
 blf_zerokey(u_int8_t **sched)
 {
-       bzero(*sched, BLF_SIZ);
+       bzero(*sched, sizeof(BF_KEY));
        FREE(*sched, M_CRYPTO_DATA);
        *sched = NULL;
 }
@@ -465,9 +444,8 @@ cast5_setkey(u_int8_t **sched, const u_i
        int err;
 
        MALLOC(*sched, u_int8_t *, sizeof(cast128_key), M_CRYPTO_DATA,
-              M_NOWAIT);
+              M_NOWAIT|M_ZERO);
        if (*sched != NULL) {
-               bzero(*sched, sizeof(cast128_key));
                cast128_setkey((cast128_key *)*sched, key, len);
                err = 0;
        } else
@@ -505,7 +483,7 @@ skipjack_setkey(u_int8_t **sched, const 
         * Will this break a pdp-10, Cray-1, or GE-645 port?
         */
        MALLOC(*sched, u_int8_t *, 10 * (sizeof(u_int8_t *) + 0x100),
-               M_CRYPTO_DATA, M_NOWAIT);
+               M_CRYPTO_DATA, M_NOWAIT|M_ZERO);
 
        if (*sched != NULL) {
 
@@ -513,8 +491,6 @@ skipjack_setkey(u_int8_t **sched, const 
                u_int8_t* table = (u_int8_t*) &key_tables[10];
                int k;
 
-               bzero(*sched, 10 * sizeof(u_int8_t *)+0x100);
-
                for (k = 0; k < 10; k++) {
                        key_tables[k] = table;
                        table += 0x100;
@@ -553,9 +529,8 @@ rijndael128_setkey(u_int8_t **sched, con
        int err;
 
        MALLOC(*sched, u_int8_t *, sizeof(rijndael_ctx), M_CRYPTO_DATA,
-           M_NOWAIT);
+           M_NOWAIT|M_ZERO);
        if (*sched != NULL) {
-               bzero(*sched, sizeof(rijndael_ctx));
                rijndael_set_key((rijndael_ctx *) *sched, key, len * 8);
                err = 0;
        } else
Index: opencrypto/files.opencrypto
===================================================================
RCS file: /cvsroot/src/sys/opencrypto/files.opencrypto,v
retrieving revision 1.18
diff -u -p -r1.18 files.opencrypto
--- opencrypto/files.opencrypto 27 Oct 2006 21:20:48 -0000      1.18
+++ opencrypto/files.opencrypto 3 Feb 2008 20:26:00 -0000
@@ -23,3 +23,5 @@ file  opencrypto/deflate.c            swcrypto        # wr
 # (and thus crypto hardware accelerators).
 defpseudo crypto: opencrypto
 file   opencrypto/cryptodev.c          crypto
+
+defflag opt_ocf.h      CRYPTO_DEBUG CRYPTO_TIMING
Index: netipsec/xform_ah.c
===================================================================
RCS file: /cvsroot/src/sys/netipsec/xform_ah.c,v
retrieving revision 1.19
diff -u -p -r1.19 xform_ah.c
--- netipsec/xform_ah.c 28 Oct 2007 15:48:23 -0000      1.19
+++ netipsec/xform_ah.c 3 Feb 2008 20:26:01 -0000
@@ -230,8 +230,13 @@ ah_init(struct secasvar *sav, struct xfo
        int error;
 
        error = ah_init0(sav, xsp, &cria);
-       return error ? error :
-                crypto_newsession(&sav->tdb_cryptoid, &cria, crypto_support);
+       if (!error) {
+               mutex_spin_enter(&crypto_mtx);
+               error = crypto_newsession(&sav->tdb_cryptoid,
+                                          &cria, crypto_support);
+               mutex_spin_exit(&crypto_mtx);
+       }
+       return error;
 }
 
 /*
@@ -247,7 +252,9 @@ ah_zeroize(struct secasvar *sav)
        if (sav->key_auth)
                bzero(_KEYBUF(sav->key_auth), _KEYLEN(sav->key_auth));
 
+       mutex_spin_enter(&crypto_mtx);
        err = crypto_freesession(sav->tdb_cryptoid);
+       mutex_spin_exit(&crypto_mtx);
        sav->tdb_cryptoid = 0;
        sav->tdb_authalgxform = NULL;
        sav->tdb_xform = NULL;
Index: netipsec/xform_esp.c
===================================================================
RCS file: /cvsroot/src/sys/netipsec/xform_esp.c,v
retrieving revision 1.16
diff -u -p -r1.16 xform_esp.c
--- netipsec/xform_esp.c        27 Jun 2007 20:38:33 -0000      1.16
+++ netipsec/xform_esp.c        3 Feb 2008 20:26:03 -0000
@@ -231,6 +231,7 @@ esp_init(struct secasvar *sav, struct xf
        crie.cri_key = _KEYBUF(sav->key_enc);
        /* XXX Rounds ? */
 
+       mutex_spin_enter(&crypto_mtx);
        if (sav->tdb_authalgxform && sav->tdb_encalgxform) {
                /* init both auth & enc */
                crie.cri_next = &cria;
@@ -247,6 +248,7 @@ esp_init(struct secasvar *sav, struct xf
                DPRINTF(("esp_init: no encoding OR authentication xform!\n"));
                error = EINVAL;
        }
+       mutex_spin_exit(&crypto_mtx);
        return error;
 }
 
Index: netipsec/xform_ipcomp.c
===================================================================
RCS file: /cvsroot/src/sys/netipsec/xform_ipcomp.c,v
retrieving revision 1.16
diff -u -p -r1.16 xform_ipcomp.c
--- netipsec/xform_ipcomp.c     29 Dec 2007 14:56:35 -0000      1.16
+++ netipsec/xform_ipcomp.c     3 Feb 2008 20:26:03 -0000
@@ -106,6 +106,7 @@ ipcomp_init(struct secasvar *sav, struct
 {
        struct comp_algo *tcomp;
        struct cryptoini cric;
+       int ses;
 
        /* NB: algorithm really comes in alg_enc and not alg_comp! */
        tcomp = ipcomp_algorithm_lookup(sav->alg_enc);
@@ -122,7 +123,10 @@ ipcomp_init(struct secasvar *sav, struct
        bzero(&cric, sizeof (cric));
        cric.cri_alg = sav->tdb_compalgxform->type;
 
-       return crypto_newsession(&sav->tdb_cryptoid, &cric, crypto_support);
+       mutex_spin_enter(&crypto_mtx);
+       ses = crypto_newsession(&sav->tdb_cryptoid, &cric, crypto_support);
+       mutex_spin_exit(&crypto_mtx);
+       return ses;
 }
 
 /*
@@ -133,7 +137,9 @@ ipcomp_zeroize(struct secasvar *sav)
 {
        int err;
 
+       mutex_spin_enter(&crypto_mtx);
        err = crypto_freesession(sav->tdb_cryptoid);
+       mutex_spin_exit(&crypto_mtx);
        sav->tdb_cryptoid = 0;
        return err;
 }


Home | Main Index | Thread Index | Old Index