The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/opencrypto/crypto.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*      $OpenBSD: crypto.c,v 1.38 2002/06/11 11:14:29 beck Exp $        */
    2 /*
    3  * The author of this code is Angelos D. Keromytis (angelos@cis.upenn.edu)
    4  *
    5  * This code was written by Angelos D. Keromytis in Athens, Greece, in
    6  * February 2000. Network Security Technologies Inc. (NSTI) kindly
    7  * supported the development of this code.
    8  *
    9  * Copyright (c) 2000, 2001 Angelos D. Keromytis
   10  *
   11  * Permission to use, copy, and modify this software with or without fee
   12  * is hereby granted, provided that this entire notice is included in
   13  * all source code copies of any software which is or includes a copy or
   14  * modification of this software.
   15  *
   16  * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
   17  * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
   18  * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
   19  * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
   20  * PURPOSE.
   21  */
   22 
   23 #include <sys/cdefs.h>
   24 __FBSDID("$FreeBSD: releng/5.2/sys/opencrypto/crypto.c 117058 2003-06-30 05:09:32Z sam $");
   25 
   26 #define CRYPTO_TIMING                           /* enable timing support */
   27 
   28 #include <sys/param.h>
   29 #include <sys/systm.h>
   30 #include <sys/eventhandler.h>
   31 #include <sys/kernel.h>
   32 #include <sys/kthread.h>
   33 #include <sys/lock.h>
   34 #include <sys/mutex.h>
   35 #include <sys/malloc.h>
   36 #include <sys/proc.h>
   37 #include <sys/sysctl.h>
   38 
   39 #include <vm/uma.h>
   40 #include <opencrypto/cryptodev.h>
   41 #include <opencrypto/xform.h>                   /* XXX for M_XDATA */
   42 
   43 /*
   44  * Crypto drivers register themselves by allocating a slot in the
   45  * crypto_drivers table with crypto_get_driverid() and then registering
   46  * each algorithm they support with crypto_register() and crypto_kregister().
   47  */
   48 static  struct mtx crypto_drivers_mtx;          /* lock on driver table */
   49 #define CRYPTO_DRIVER_LOCK()    mtx_lock(&crypto_drivers_mtx)
   50 #define CRYPTO_DRIVER_UNLOCK()  mtx_unlock(&crypto_drivers_mtx)
   51 static  struct cryptocap *crypto_drivers = NULL;
   52 static  int crypto_drivers_num = 0;
   53 
   54 /*
   55  * There are two queues for crypto requests; one for symmetric (e.g.
   56  * cipher) operations and one for asymmetric (e.g. MOD)operations.
   57  * A single mutex is used to lock access to both queues.  We could
   58  * have one per-queue but having one simplifies handling of block/unblock
   59  * operations.
   60  */
   61 static  TAILQ_HEAD(,cryptop) crp_q;             /* request queues */
   62 static  TAILQ_HEAD(,cryptkop) crp_kq;
   63 static  struct mtx crypto_q_mtx;
   64 #define CRYPTO_Q_LOCK()         mtx_lock(&crypto_q_mtx)
   65 #define CRYPTO_Q_UNLOCK()       mtx_unlock(&crypto_q_mtx)
   66 
   67 /*
   68  * There are two queues for processing completed crypto requests; one
   69  * for the symmetric and one for the asymmetric ops.  We only need one
   70  * but have two to avoid type futzing (cryptop vs. cryptkop).  A single
   71  * mutex is used to lock access to both queues.  Note that this lock
   72  * must be separate from the lock on request queues to insure driver
   73  * callbacks don't generate lock order reversals.
   74  */
   75 static  TAILQ_HEAD(,cryptop) crp_ret_q;         /* callback queues */
   76 static  TAILQ_HEAD(,cryptkop) crp_ret_kq;
   77 static  struct mtx crypto_ret_q_mtx;
   78 #define CRYPTO_RETQ_LOCK()      mtx_lock(&crypto_ret_q_mtx)
   79 #define CRYPTO_RETQ_UNLOCK()    mtx_unlock(&crypto_ret_q_mtx)
   80 
   81 static  uma_zone_t cryptop_zone;
   82 static  uma_zone_t cryptodesc_zone;
   83 
   84 int     crypto_userasymcrypto = 1;      /* userland may do asym crypto reqs */
   85 SYSCTL_INT(_kern, OID_AUTO, userasymcrypto, CTLFLAG_RW,
   86            &crypto_userasymcrypto, 0,
   87            "Enable/disable user-mode access to asymmetric crypto support");
   88 int     crypto_devallowsoft = 0;        /* only use hardware crypto for asym */
   89 SYSCTL_INT(_kern, OID_AUTO, cryptodevallowsoft, CTLFLAG_RW,
   90            &crypto_devallowsoft, 0,
   91            "Enable/disable use of software asym crypto support");
   92 
   93 MALLOC_DEFINE(M_CRYPTO_DATA, "crypto", "crypto session records");
   94 
   95 static  void crypto_proc(void);
   96 static  struct proc *cryptoproc;
   97 static  void crypto_ret_proc(void);
   98 static  struct proc *cryptoretproc;
   99 static  void crypto_destroy(void);
  100 static  int crypto_invoke(struct cryptop *crp, int hint);
  101 static  int crypto_kinvoke(struct cryptkop *krp, int hint);
  102 
  103 static  struct cryptostats cryptostats;
  104 SYSCTL_STRUCT(_kern, OID_AUTO, crypto_stats, CTLFLAG_RW, &cryptostats,
  105             cryptostats, "Crypto system statistics");
  106 
  107 #ifdef CRYPTO_TIMING
  108 static  int crypto_timing = 0;
  109 SYSCTL_INT(_debug, OID_AUTO, crypto_timing, CTLFLAG_RW,
  110            &crypto_timing, 0, "Enable/disable crypto timing support");
  111 #endif
  112 
  113 static int
  114 crypto_init(void)
  115 {
  116         int error;
  117 
  118         mtx_init(&crypto_drivers_mtx, "crypto", "crypto driver table",
  119                 MTX_DEF|MTX_QUIET);
  120 
  121         TAILQ_INIT(&crp_q);
  122         TAILQ_INIT(&crp_kq);
  123         mtx_init(&crypto_q_mtx, "crypto", "crypto op queues", MTX_DEF);
  124 
  125         TAILQ_INIT(&crp_ret_q);
  126         TAILQ_INIT(&crp_ret_kq);
  127         mtx_init(&crypto_ret_q_mtx, "crypto", "crypto return queues", MTX_DEF);
  128 
  129         cryptop_zone = uma_zcreate("cryptop", sizeof (struct cryptop),
  130                                     0, 0, 0, 0,
  131                                     UMA_ALIGN_PTR, UMA_ZONE_ZINIT);
  132         cryptodesc_zone = uma_zcreate("cryptodesc", sizeof (struct cryptodesc),
  133                                     0, 0, 0, 0,
  134                                     UMA_ALIGN_PTR, UMA_ZONE_ZINIT);
  135         if (cryptodesc_zone == NULL || cryptop_zone == NULL) {
  136                 printf("crypto_init: cannot setup crypto zones\n");
  137                 error = ENOMEM;
  138                 goto bad;
  139         }
  140 
  141         crypto_drivers_num = CRYPTO_DRIVERS_INITIAL;
  142         crypto_drivers = malloc(crypto_drivers_num *
  143             sizeof(struct cryptocap), M_CRYPTO_DATA, M_NOWAIT | M_ZERO);
  144         if (crypto_drivers == NULL) {
  145                 printf("crypto_init: cannot setup crypto drivers\n");
  146                 error = ENOMEM;
  147                 goto bad;
  148         }
  149 
  150         error = kthread_create((void (*)(void *)) crypto_proc, NULL,
  151                     &cryptoproc, 0, 0, "crypto");
  152         if (error) {
  153                 printf("crypto_init: cannot start crypto thread; error %d",
  154                         error);
  155                 goto bad;
  156         }
  157 
  158         error = kthread_create((void (*)(void *)) crypto_ret_proc, NULL,
  159                     &cryptoretproc, 0, 0, "crypto returns");
  160         if (error) {
  161                 printf("crypto_init: cannot start cryptoret thread; error %d",
  162                         error);
  163                 goto bad;
  164         }
  165         return 0;
  166 bad:
  167         crypto_destroy();
  168         return error;
  169 }
  170 
  171 /*
  172  * Signal a crypto thread to terminate.  We use the driver
  173  * table lock to synchronize the sleep/wakeups so that we
  174  * are sure the threads have terminated before we release
  175  * the data structures they use.  See crypto_finis below
  176  * for the other half of this song-and-dance.
  177  */
  178 static void
  179 crypto_terminate(struct proc **pp, void *q)
  180 {
  181         struct proc *p;
  182 
  183         mtx_assert(&crypto_drivers_mtx, MA_OWNED);
  184         p = *pp;
  185         *pp = NULL;
  186         if (p) {
  187                 wakeup_one(q);
  188                 PROC_LOCK(p);           /* NB: insure we don't miss wakeup */
  189                 CRYPTO_DRIVER_UNLOCK(); /* let crypto_finis progress */
  190                 msleep(p, &p->p_mtx, PWAIT, "crypto_destroy", 0);
  191                 PROC_UNLOCK(p);
  192                 CRYPTO_DRIVER_LOCK();
  193         }
  194 }
  195 
  196 static void
  197 crypto_destroy(void)
  198 {
  199         /*
  200          * Terminate any crypto threads.
  201          */
  202         CRYPTO_DRIVER_LOCK();
  203         crypto_terminate(&cryptoproc, &crp_q);
  204         crypto_terminate(&cryptoretproc, &crp_ret_q);
  205         CRYPTO_DRIVER_UNLOCK();
  206 
  207         /* XXX flush queues??? */
  208 
  209         /* 
  210          * Reclaim dynamically allocated resources.
  211          */
  212         if (crypto_drivers != NULL)
  213                 free(crypto_drivers, M_CRYPTO_DATA);
  214 
  215         if (cryptodesc_zone != NULL)
  216                 uma_zdestroy(cryptodesc_zone);
  217         if (cryptop_zone != NULL)
  218                 uma_zdestroy(cryptop_zone);
  219         mtx_destroy(&crypto_q_mtx);
  220         mtx_destroy(&crypto_ret_q_mtx);
  221         mtx_destroy(&crypto_drivers_mtx);
  222 }
  223 
  224 /*
  225  * Initialization code, both for static and dynamic loading.
  226  */
  227 static int
  228 crypto_modevent(module_t mod, int type, void *unused)
  229 {
  230         int error = EINVAL;
  231 
  232         switch (type) {
  233         case MOD_LOAD:
  234                 error = crypto_init();
  235                 if (error == 0 && bootverbose)
  236                         printf("crypto: <crypto core>\n");
  237                 break;
  238         case MOD_UNLOAD:
  239                 /*XXX disallow if active sessions */
  240                 error = 0;
  241                 crypto_destroy();
  242                 return 0;
  243         }
  244         return error;
  245 }
  246 
  247 static moduledata_t crypto_mod = {
  248         "crypto",
  249         crypto_modevent,
  250         0
  251 };
  252 MODULE_VERSION(crypto, 1);
  253 DECLARE_MODULE(crypto, crypto_mod, SI_SUB_DRIVERS, SI_ORDER_FIRST);
  254 
  255 /*
  256  * Create a new session.
  257  */
  258 int
  259 crypto_newsession(u_int64_t *sid, struct cryptoini *cri, int hard)
  260 {
  261         struct cryptoini *cr;
  262         u_int32_t hid, lid;
  263         int err = EINVAL;
  264 
  265         CRYPTO_DRIVER_LOCK();
  266 
  267         if (crypto_drivers == NULL)
  268                 goto done;
  269 
  270         /*
  271          * The algorithm we use here is pretty stupid; just use the
  272          * first driver that supports all the algorithms we need.
  273          *
  274          * XXX We need more smarts here (in real life too, but that's
  275          * XXX another story altogether).
  276          */
  277 
  278         for (hid = 0; hid < crypto_drivers_num; hid++) {
  279                 struct cryptocap *cap = &crypto_drivers[hid];
  280                 /*
  281                  * If it's not initialized or has remaining sessions
  282                  * referencing it, skip.
  283                  */
  284                 if (cap->cc_newsession == NULL ||
  285                     (cap->cc_flags & CRYPTOCAP_F_CLEANUP))
  286                         continue;
  287 
  288                 /* Hardware required -- ignore software drivers. */
  289                 if (hard > 0 && (cap->cc_flags & CRYPTOCAP_F_SOFTWARE))
  290                         continue;
  291                 /* Software required -- ignore hardware drivers. */
  292                 if (hard < 0 && (cap->cc_flags & CRYPTOCAP_F_SOFTWARE) == 0)
  293                         continue;
  294 
  295                 /* See if all the algorithms are supported. */
  296                 for (cr = cri; cr; cr = cr->cri_next)
  297                         if (cap->cc_alg[cr->cri_alg] == 0)
  298                                 break;
  299 
  300                 if (cr == NULL) {
  301                         /* Ok, all algorithms are supported. */
  302 
  303                         /*
  304                          * Can't do everything in one session.
  305                          *
  306                          * XXX Fix this. We need to inject a "virtual" session layer right
  307                          * XXX about here.
  308                          */
  309 
  310                         /* Call the driver initialization routine. */
  311                         lid = hid;              /* Pass the driver ID. */
  312                         err = (*cap->cc_newsession)(cap->cc_arg, &lid, cri);
  313                         if (err == 0) {
  314                                 /* XXX assert (hid &~ 0xffffff) == 0 */
  315                                 /* XXX assert (cap->cc_flags &~ 0xff) == 0 */
  316                                 (*sid) = ((cap->cc_flags & 0xff) << 24) | hid;
  317                                 (*sid) <<= 32;
  318                                 (*sid) |= (lid & 0xffffffff);
  319                                 cap->cc_sessions++;
  320                         }
  321                         break;
  322                 }
  323         }
  324 done:
  325         CRYPTO_DRIVER_UNLOCK();
  326         return err;
  327 }
  328 
  329 /*
  330  * Delete an existing session (or a reserved session on an unregistered
  331  * driver).
  332  */
  333 int
  334 crypto_freesession(u_int64_t sid)
  335 {
  336         u_int32_t hid;
  337         int err;
  338 
  339         CRYPTO_DRIVER_LOCK();
  340 
  341         if (crypto_drivers == NULL) {
  342                 err = EINVAL;
  343                 goto done;
  344         }
  345 
  346         /* Determine two IDs. */
  347         hid = CRYPTO_SESID2HID(sid);
  348 
  349         if (hid >= crypto_drivers_num) {
  350                 err = ENOENT;
  351                 goto done;
  352         }
  353 
  354         if (crypto_drivers[hid].cc_sessions)
  355                 crypto_drivers[hid].cc_sessions--;
  356 
  357         /* Call the driver cleanup routine, if available. */
  358         if (crypto_drivers[hid].cc_freesession)
  359                 err = crypto_drivers[hid].cc_freesession(
  360                                 crypto_drivers[hid].cc_arg, sid);
  361         else
  362                 err = 0;
  363 
  364         /*
  365          * If this was the last session of a driver marked as invalid,
  366          * make the entry available for reuse.
  367          */
  368         if ((crypto_drivers[hid].cc_flags & CRYPTOCAP_F_CLEANUP) &&
  369             crypto_drivers[hid].cc_sessions == 0)
  370                 bzero(&crypto_drivers[hid], sizeof(struct cryptocap));
  371 
  372 done:
  373         CRYPTO_DRIVER_UNLOCK();
  374         return err;
  375 }
  376 
  377 /*
  378  * Return an unused driver id.  Used by drivers prior to registering
  379  * support for the algorithms they handle.
  380  */
  381 int32_t
  382 crypto_get_driverid(u_int32_t flags)
  383 {
  384         struct cryptocap *newdrv;
  385         int i;
  386 
  387         CRYPTO_DRIVER_LOCK();
  388 
  389         for (i = 0; i < crypto_drivers_num; i++)
  390                 if (crypto_drivers[i].cc_process == NULL &&
  391                     (crypto_drivers[i].cc_flags & CRYPTOCAP_F_CLEANUP) == 0 &&
  392                     crypto_drivers[i].cc_sessions == 0)
  393                         break;
  394 
  395         /* Out of entries, allocate some more. */
  396         if (i == crypto_drivers_num) {
  397                 /* Be careful about wrap-around. */
  398                 if (2 * crypto_drivers_num <= crypto_drivers_num) {
  399                         CRYPTO_DRIVER_UNLOCK();
  400                         printf("crypto: driver count wraparound!\n");
  401                         return -1;
  402                 }
  403 
  404                 newdrv = malloc(2 * crypto_drivers_num *
  405                     sizeof(struct cryptocap), M_CRYPTO_DATA, M_NOWAIT|M_ZERO);
  406                 if (newdrv == NULL) {
  407                         CRYPTO_DRIVER_UNLOCK();
  408                         printf("crypto: no space to expand driver table!\n");
  409                         return -1;
  410                 }
  411 
  412                 bcopy(crypto_drivers, newdrv,
  413                     crypto_drivers_num * sizeof(struct cryptocap));
  414 
  415                 crypto_drivers_num *= 2;
  416 
  417                 free(crypto_drivers, M_CRYPTO_DATA);
  418                 crypto_drivers = newdrv;
  419         }
  420 
  421         /* NB: state is zero'd on free */
  422         crypto_drivers[i].cc_sessions = 1;      /* Mark */
  423         crypto_drivers[i].cc_flags = flags;
  424         if (bootverbose)
  425                 printf("crypto: assign driver %u, flags %u\n", i, flags);
  426 
  427         CRYPTO_DRIVER_UNLOCK();
  428 
  429         return i;
  430 }
  431 
  432 static struct cryptocap *
  433 crypto_checkdriver(u_int32_t hid)
  434 {
  435         if (crypto_drivers == NULL)
  436                 return NULL;
  437         return (hid >= crypto_drivers_num ? NULL : &crypto_drivers[hid]);
  438 }
  439 
  440 /*
  441  * Register support for a key-related algorithm.  This routine
  442  * is called once for each algorithm supported a driver.
  443  */
  444 int
  445 crypto_kregister(u_int32_t driverid, int kalg, u_int32_t flags,
  446     int (*kprocess)(void*, struct cryptkop *, int),
  447     void *karg)
  448 {
  449         struct cryptocap *cap;
  450         int err;
  451 
  452         CRYPTO_DRIVER_LOCK();
  453 
  454         cap = crypto_checkdriver(driverid);
  455         if (cap != NULL &&
  456             (CRK_ALGORITM_MIN <= kalg && kalg <= CRK_ALGORITHM_MAX)) {
  457                 /*
  458                  * XXX Do some performance testing to determine placing.
  459                  * XXX We probably need an auxiliary data structure that
  460                  * XXX describes relative performances.
  461                  */
  462 
  463                 cap->cc_kalg[kalg] = flags | CRYPTO_ALG_FLAG_SUPPORTED;
  464                 if (bootverbose)
  465                         printf("crypto: driver %u registers key alg %u flags %u\n"
  466                                 , driverid
  467                                 , kalg
  468                                 , flags
  469                         );
  470 
  471                 if (cap->cc_kprocess == NULL) {
  472                         cap->cc_karg = karg;
  473                         cap->cc_kprocess = kprocess;
  474                 }
  475                 err = 0;
  476         } else
  477                 err = EINVAL;
  478 
  479         CRYPTO_DRIVER_UNLOCK();
  480         return err;
  481 }
  482 
  483 /*
  484  * Register support for a non-key-related algorithm.  This routine
  485  * is called once for each such algorithm supported by a driver.
  486  */
  487 int
  488 crypto_register(u_int32_t driverid, int alg, u_int16_t maxoplen,
  489     u_int32_t flags,
  490     int (*newses)(void*, u_int32_t*, struct cryptoini*),
  491     int (*freeses)(void*, u_int64_t),
  492     int (*process)(void*, struct cryptop *, int),
  493     void *arg)
  494 {
  495         struct cryptocap *cap;
  496         int err;
  497 
  498         CRYPTO_DRIVER_LOCK();
  499 
  500         cap = crypto_checkdriver(driverid);
  501         /* NB: algorithms are in the range [1..max] */
  502         if (cap != NULL &&
  503             (CRYPTO_ALGORITHM_MIN <= alg && alg <= CRYPTO_ALGORITHM_MAX)) {
  504                 /*
  505                  * XXX Do some performance testing to determine placing.
  506                  * XXX We probably need an auxiliary data structure that
  507                  * XXX describes relative performances.
  508                  */
  509 
  510                 cap->cc_alg[alg] = flags | CRYPTO_ALG_FLAG_SUPPORTED;
  511                 cap->cc_max_op_len[alg] = maxoplen;
  512                 if (bootverbose)
  513                         printf("crypto: driver %u registers alg %u flags %u maxoplen %u\n"
  514                                 , driverid
  515                                 , alg
  516                                 , flags
  517                                 , maxoplen
  518                         );
  519 
  520                 if (cap->cc_process == NULL) {
  521                         cap->cc_arg = arg;
  522                         cap->cc_newsession = newses;
  523                         cap->cc_process = process;
  524                         cap->cc_freesession = freeses;
  525                         cap->cc_sessions = 0;           /* Unmark */
  526                 }
  527                 err = 0;
  528         } else
  529                 err = EINVAL;
  530 
  531         CRYPTO_DRIVER_UNLOCK();
  532         return err;
  533 }
  534 
  535 /*
  536  * Unregister a crypto driver. If there are pending sessions using it,
  537  * leave enough information around so that subsequent calls using those
  538  * sessions will correctly detect the driver has been unregistered and
  539  * reroute requests.
  540  */
  541 int
  542 crypto_unregister(u_int32_t driverid, int alg)
  543 {
  544         int i, err;
  545         u_int32_t ses;
  546         struct cryptocap *cap;
  547 
  548         CRYPTO_DRIVER_LOCK();
  549 
  550         cap = crypto_checkdriver(driverid);
  551         if (cap != NULL &&
  552             (CRYPTO_ALGORITHM_MIN <= alg && alg <= CRYPTO_ALGORITHM_MAX) &&
  553             cap->cc_alg[alg] != 0) {
  554                 cap->cc_alg[alg] = 0;
  555                 cap->cc_max_op_len[alg] = 0;
  556 
  557                 /* Was this the last algorithm ? */
  558                 for (i = 1; i <= CRYPTO_ALGORITHM_MAX; i++)
  559                         if (cap->cc_alg[i] != 0)
  560                                 break;
  561 
  562                 if (i == CRYPTO_ALGORITHM_MAX + 1) {
  563                         ses = cap->cc_sessions;
  564                         bzero(cap, sizeof(struct cryptocap));
  565                         if (ses != 0) {
  566                                 /*
  567                                  * If there are pending sessions, just mark as invalid.
  568                                  */
  569                                 cap->cc_flags |= CRYPTOCAP_F_CLEANUP;
  570                                 cap->cc_sessions = ses;
  571                         }
  572                 }
  573                 err = 0;
  574         } else
  575                 err = EINVAL;
  576 
  577         CRYPTO_DRIVER_UNLOCK();
  578         return err;
  579 }
  580 
  581 /*
  582  * Unregister all algorithms associated with a crypto driver.
  583  * If there are pending sessions using it, leave enough information
  584  * around so that subsequent calls using those sessions will
  585  * correctly detect the driver has been unregistered and reroute
  586  * requests.
  587  */
  588 int
  589 crypto_unregister_all(u_int32_t driverid)
  590 {
  591         int i, err;
  592         u_int32_t ses;
  593         struct cryptocap *cap;
  594 
  595         CRYPTO_DRIVER_LOCK();
  596 
  597         cap = crypto_checkdriver(driverid);
  598         if (cap != NULL) {
  599                 for (i = CRYPTO_ALGORITHM_MIN; i <= CRYPTO_ALGORITHM_MAX; i++) {
  600                         cap->cc_alg[i] = 0;
  601                         cap->cc_max_op_len[i] = 0;
  602                 }
  603                 ses = cap->cc_sessions;
  604                 bzero(cap, sizeof(struct cryptocap));
  605                 if (ses != 0) {
  606                         /*
  607                          * If there are pending sessions, just mark as invalid.
  608                          */
  609                         cap->cc_flags |= CRYPTOCAP_F_CLEANUP;
  610                         cap->cc_sessions = ses;
  611                 }
  612                 err = 0;
  613         } else
  614                 err = EINVAL;
  615 
  616         CRYPTO_DRIVER_UNLOCK();
  617         return err;
  618 }
  619 
  620 /*
  621  * Clear blockage on a driver.  The what parameter indicates whether
  622  * the driver is now ready for cryptop's and/or cryptokop's.
  623  */
  624 int
  625 crypto_unblock(u_int32_t driverid, int what)
  626 {
  627         struct cryptocap *cap;
  628         int needwakeup, err;
  629 
  630         CRYPTO_Q_LOCK();
  631         cap = crypto_checkdriver(driverid);
  632         if (cap != NULL) {
  633                 needwakeup = 0;
  634                 if (what & CRYPTO_SYMQ) {
  635                         needwakeup |= cap->cc_qblocked;
  636                         cap->cc_qblocked = 0;
  637                 }
  638                 if (what & CRYPTO_ASYMQ) {
  639                         needwakeup |= cap->cc_kqblocked;
  640                         cap->cc_kqblocked = 0;
  641                 }
  642                 if (needwakeup)
  643                         wakeup_one(&crp_q);
  644                 err = 0;
  645         } else
  646                 err = EINVAL;
  647         CRYPTO_Q_UNLOCK();
  648 
  649         return err;
  650 }
  651 
  652 /*
  653  * Add a crypto request to a queue, to be processed by the kernel thread.
  654  */
  655 int
  656 crypto_dispatch(struct cryptop *crp)
  657 {
  658         u_int32_t hid = CRYPTO_SESID2HID(crp->crp_sid);
  659         int result;
  660 
  661         cryptostats.cs_ops++;
  662 
  663 #ifdef CRYPTO_TIMING
  664         if (crypto_timing)
  665                 binuptime(&crp->crp_tstamp);
  666 #endif
  667 
  668         CRYPTO_Q_LOCK();
  669         if ((crp->crp_flags & CRYPTO_F_BATCH) == 0) {
  670                 struct cryptocap *cap;
  671                 /*
  672                  * Caller marked the request to be processed
  673                  * immediately; dispatch it directly to the
  674                  * driver unless the driver is currently blocked.
  675                  */
  676                 cap = crypto_checkdriver(hid);
  677                 if (cap && !cap->cc_qblocked) {
  678                         result = crypto_invoke(crp, 0);
  679                         if (result == ERESTART) {
  680                                 /*
  681                                  * The driver ran out of resources, mark the
  682                                  * driver ``blocked'' for cryptop's and put
  683                                  * the request on the queue.
  684                                  *
  685                                  * XXX ops are placed at the tail so their
  686                                  * order is preserved but this can place them
  687                                  * behind batch'd ops.
  688                                  */
  689                                 crypto_drivers[hid].cc_qblocked = 1;
  690                                 TAILQ_INSERT_TAIL(&crp_q, crp, crp_next);
  691                                 cryptostats.cs_blocks++;
  692                                 result = 0;
  693                         }
  694                 } else {
  695                         /*
  696                          * The driver is blocked, just queue the op until
  697                          * it unblocks and the kernel thread gets kicked.
  698                          */
  699                         TAILQ_INSERT_TAIL(&crp_q, crp, crp_next);
  700                         result = 0;
  701                 }
  702         } else {
  703                 int wasempty;
  704                 /*
  705                  * Caller marked the request as ``ok to delay'';
  706                  * queue it for the dispatch thread.  This is desirable
  707                  * when the operation is low priority and/or suitable
  708                  * for batching.
  709                  */
  710                 wasempty = TAILQ_EMPTY(&crp_q);
  711                 TAILQ_INSERT_TAIL(&crp_q, crp, crp_next);
  712                 if (wasempty)
  713                         wakeup_one(&crp_q);
  714                 result = 0;
  715         }
  716         CRYPTO_Q_UNLOCK();
  717 
  718         return result;
  719 }
  720 
  721 /*
  722  * Add an asymetric crypto request to a queue,
  723  * to be processed by the kernel thread.
  724  */
  725 int
  726 crypto_kdispatch(struct cryptkop *krp)
  727 {
  728         struct cryptocap *cap;
  729         int result;
  730 
  731         cryptostats.cs_kops++;
  732 
  733         CRYPTO_Q_LOCK();
  734         cap = crypto_checkdriver(krp->krp_hid);
  735         if (cap && !cap->cc_kqblocked) {
  736                 result = crypto_kinvoke(krp, 0);
  737                 if (result == ERESTART) {
  738                         /*
  739                          * The driver ran out of resources, mark the
  740                          * driver ``blocked'' for cryptkop's and put
  741                          * the request back in the queue.  It would
  742                          * best to put the request back where we got
  743                          * it but that's hard so for now we put it
  744                          * at the front.  This should be ok; putting
  745                          * it at the end does not work.
  746                          */
  747                         crypto_drivers[krp->krp_hid].cc_kqblocked = 1;
  748                         TAILQ_INSERT_TAIL(&crp_kq, krp, krp_next);
  749                         cryptostats.cs_kblocks++;
  750                 }
  751         } else {
  752                 /*
  753                  * The driver is blocked, just queue the op until
  754                  * it unblocks and the kernel thread gets kicked.
  755                  */
  756                 TAILQ_INSERT_TAIL(&crp_kq, krp, krp_next);
  757                 result = 0;
  758         }
  759         CRYPTO_Q_UNLOCK();
  760 
  761         return result;
  762 }
  763 
  764 /*
  765  * Dispatch an assymetric crypto request to the appropriate crypto devices.
  766  */
  767 static int
  768 crypto_kinvoke(struct cryptkop *krp, int hint)
  769 {
  770         u_int32_t hid;
  771         int error;
  772 
  773         mtx_assert(&crypto_q_mtx, MA_OWNED);
  774 
  775         /* Sanity checks. */
  776         if (krp == NULL)
  777                 return EINVAL;
  778         if (krp->krp_callback == NULL) {
  779                 free(krp, M_XDATA);             /* XXX allocated in cryptodev */
  780                 return EINVAL;
  781         }
  782 
  783         for (hid = 0; hid < crypto_drivers_num; hid++) {
  784                 if ((crypto_drivers[hid].cc_flags & CRYPTOCAP_F_SOFTWARE) &&
  785                     !crypto_devallowsoft)
  786                         continue;
  787                 if (crypto_drivers[hid].cc_kprocess == NULL)
  788                         continue;
  789                 if ((crypto_drivers[hid].cc_kalg[krp->krp_op] &
  790                     CRYPTO_ALG_FLAG_SUPPORTED) == 0)
  791                         continue;
  792                 break;
  793         }
  794         if (hid < crypto_drivers_num) {
  795                 krp->krp_hid = hid;
  796                 error = crypto_drivers[hid].cc_kprocess(
  797                                 crypto_drivers[hid].cc_karg, krp, hint);
  798         } else
  799                 error = ENODEV;
  800 
  801         if (error) {
  802                 krp->krp_status = error;
  803                 crypto_kdone(krp);
  804         }
  805         return 0;
  806 }
  807 
  808 #ifdef CRYPTO_TIMING
  809 static void
  810 crypto_tstat(struct cryptotstat *ts, struct bintime *bt)
  811 {
  812         struct bintime now, delta;
  813         struct timespec t;
  814         uint64_t u;
  815 
  816         binuptime(&now);
  817         u = now.frac;
  818         delta.frac = now.frac - bt->frac;
  819         delta.sec = now.sec - bt->sec;
  820         if (u < delta.frac)
  821                 delta.sec--;
  822         bintime2timespec(&delta, &t);
  823         timespecadd(&ts->acc, &t);
  824         if (timespeccmp(&t, &ts->min, <))
  825                 ts->min = t;
  826         if (timespeccmp(&t, &ts->max, >))
  827                 ts->max = t;
  828         ts->count++;
  829 
  830         *bt = now;
  831 }
  832 #endif
  833 
  834 /*
  835  * Dispatch a crypto request to the appropriate crypto devices.
  836  */
  837 static int
  838 crypto_invoke(struct cryptop *crp, int hint)
  839 {
  840         u_int32_t hid;
  841         int (*process)(void*, struct cryptop *, int);
  842 
  843 #ifdef CRYPTO_TIMING
  844         if (crypto_timing)
  845                 crypto_tstat(&cryptostats.cs_invoke, &crp->crp_tstamp);
  846 #endif
  847         /* Sanity checks. */
  848         if (crp == NULL)
  849                 return EINVAL;
  850         if (crp->crp_callback == NULL) {
  851                 crypto_freereq(crp);
  852                 return EINVAL;
  853         }
  854         if (crp->crp_desc == NULL) {
  855                 crp->crp_etype = EINVAL;
  856                 crypto_done(crp);
  857                 return 0;
  858         }
  859 
  860         hid = CRYPTO_SESID2HID(crp->crp_sid);
  861         if (hid < crypto_drivers_num) {
  862                 if (crypto_drivers[hid].cc_flags & CRYPTOCAP_F_CLEANUP)
  863                         crypto_freesession(crp->crp_sid);
  864                 process = crypto_drivers[hid].cc_process;
  865         } else {
  866                 process = NULL;
  867         }
  868 
  869         if (process == NULL) {
  870                 struct cryptodesc *crd;
  871                 u_int64_t nid;
  872 
  873                 /*
  874                  * Driver has unregistered; migrate the session and return
  875                  * an error to the caller so they'll resubmit the op.
  876                  */
  877                 for (crd = crp->crp_desc; crd->crd_next; crd = crd->crd_next)
  878                         crd->CRD_INI.cri_next = &(crd->crd_next->CRD_INI);
  879 
  880                 if (crypto_newsession(&nid, &(crp->crp_desc->CRD_INI), 0) == 0)
  881                         crp->crp_sid = nid;
  882 
  883                 crp->crp_etype = EAGAIN;
  884                 crypto_done(crp);
  885                 return 0;
  886         } else {
  887                 /*
  888                  * Invoke the driver to process the request.
  889                  */
  890                 return (*process)(crypto_drivers[hid].cc_arg, crp, hint);
  891         }
  892 }
  893 
  894 /*
  895  * Release a set of crypto descriptors.
  896  */
  897 void
  898 crypto_freereq(struct cryptop *crp)
  899 {
  900         struct cryptodesc *crd;
  901 
  902         if (crp == NULL)
  903                 return;
  904 
  905         while ((crd = crp->crp_desc) != NULL) {
  906                 crp->crp_desc = crd->crd_next;
  907                 uma_zfree(cryptodesc_zone, crd);
  908         }
  909 
  910         uma_zfree(cryptop_zone, crp);
  911 }
  912 
  913 /*
  914  * Acquire a set of crypto descriptors.
  915  */
  916 struct cryptop *
  917 crypto_getreq(int num)
  918 {
  919         struct cryptodesc *crd;
  920         struct cryptop *crp;
  921 
  922         crp = uma_zalloc(cryptop_zone, M_NOWAIT|M_ZERO);
  923         if (crp != NULL) {
  924                 while (num--) {
  925                         crd = uma_zalloc(cryptodesc_zone, M_NOWAIT|M_ZERO);
  926                         if (crd == NULL) {
  927                                 crypto_freereq(crp);
  928                                 return NULL;
  929                         }
  930 
  931                         crd->crd_next = crp->crp_desc;
  932                         crp->crp_desc = crd;
  933                 }
  934         }
  935         return crp;
  936 }
  937 
  938 /*
  939  * Invoke the callback on behalf of the driver.
  940  */
  941 void
  942 crypto_done(struct cryptop *crp)
  943 {
  944         KASSERT((crp->crp_flags & CRYPTO_F_DONE) == 0,
  945                 ("crypto_done: op already done, flags 0x%x", crp->crp_flags));
  946         crp->crp_flags |= CRYPTO_F_DONE;
  947         if (crp->crp_etype != 0)
  948                 cryptostats.cs_errs++;
  949 #ifdef CRYPTO_TIMING
  950         if (crypto_timing)
  951                 crypto_tstat(&cryptostats.cs_done, &crp->crp_tstamp);
  952 #endif
  953         /*
  954          * CBIMM means unconditionally do the callback immediately;
  955          * CBIFSYNC means do the callback immediately only if the
  956          * operation was done synchronously.  Both are used to avoid
  957          * doing extraneous context switches; the latter is mostly
  958          * used with the software crypto driver.
  959          */
  960         if ((crp->crp_flags & CRYPTO_F_CBIMM) ||
  961             ((crp->crp_flags & CRYPTO_F_CBIFSYNC) &&
  962              (CRYPTO_SESID2CAPS(crp->crp_sid) & CRYPTOCAP_F_SYNC))) {
  963                 /*
  964                  * Do the callback directly.  This is ok when the
  965                  * callback routine does very little (e.g. the
  966                  * /dev/crypto callback method just does a wakeup).
  967                  */
  968 #ifdef CRYPTO_TIMING
  969                 if (crypto_timing) {
  970                         /*
  971                          * NB: We must copy the timestamp before
  972                          * doing the callback as the cryptop is
  973                          * likely to be reclaimed.
  974                          */
  975                         struct bintime t = crp->crp_tstamp;
  976                         crypto_tstat(&cryptostats.cs_cb, &t);
  977                         crp->crp_callback(crp);
  978                         crypto_tstat(&cryptostats.cs_finis, &t);
  979                 } else
  980 #endif
  981                         crp->crp_callback(crp);
  982         } else {
  983                 int wasempty;
  984                 /*
  985                  * Normal case; queue the callback for the thread.
  986                  */
  987                 CRYPTO_RETQ_LOCK();
  988                 wasempty = TAILQ_EMPTY(&crp_ret_q);
  989                 TAILQ_INSERT_TAIL(&crp_ret_q, crp, crp_next);
  990 
  991                 if (wasempty)
  992                         wakeup_one(&crp_ret_q); /* shared wait channel */
  993                 CRYPTO_RETQ_UNLOCK();
  994         }
  995 }
  996 
  997 /*
  998  * Invoke the callback on behalf of the driver.
  999  */
 1000 void
 1001 crypto_kdone(struct cryptkop *krp)
 1002 {
 1003         int wasempty;
 1004 
 1005         if (krp->krp_status != 0)
 1006                 cryptostats.cs_kerrs++;
 1007         CRYPTO_RETQ_LOCK();
 1008         wasempty = TAILQ_EMPTY(&crp_ret_kq);
 1009         TAILQ_INSERT_TAIL(&crp_ret_kq, krp, krp_next);
 1010 
 1011         if (wasempty)
 1012                 wakeup_one(&crp_ret_q);         /* shared wait channel */
 1013         CRYPTO_RETQ_UNLOCK();
 1014 }
 1015 
 1016 int
 1017 crypto_getfeat(int *featp)
 1018 {
 1019         int hid, kalg, feat = 0;
 1020 
 1021         if (!crypto_userasymcrypto)
 1022                 goto out;         
 1023 
 1024         CRYPTO_DRIVER_LOCK();
 1025         for (hid = 0; hid < crypto_drivers_num; hid++) {
 1026                 if ((crypto_drivers[hid].cc_flags & CRYPTOCAP_F_SOFTWARE) &&
 1027                     !crypto_devallowsoft) {
 1028                         continue;
 1029                 }
 1030                 if (crypto_drivers[hid].cc_kprocess == NULL)
 1031                         continue;
 1032                 for (kalg = 0; kalg < CRK_ALGORITHM_MAX; kalg++)
 1033                         if ((crypto_drivers[hid].cc_kalg[kalg] &
 1034                             CRYPTO_ALG_FLAG_SUPPORTED) != 0)
 1035                                 feat |=  1 << kalg;
 1036         }
 1037         CRYPTO_DRIVER_UNLOCK();
 1038 out:
 1039         *featp = feat;
 1040         return (0);
 1041 }
 1042 
 1043 /*
 1044  * Terminate a thread at module unload.  The process that
 1045  * initiated this is waiting for us to signal that we're gone;
 1046  * wake it up and exit.  We use the driver table lock to insure
 1047  * we don't do the wakeup before they're waiting.  There is no
 1048  * race here because the waiter sleeps on the proc lock for the
 1049  * thread so it gets notified at the right time because of an
 1050  * extra wakeup that's done in exit1().
 1051  */
 1052 static void
 1053 crypto_finis(void *chan)
 1054 {
 1055         CRYPTO_DRIVER_LOCK();
 1056         wakeup_one(chan);
 1057         CRYPTO_DRIVER_UNLOCK();
 1058         mtx_lock(&Giant);
 1059         kthread_exit(0);
 1060 }
 1061 
 1062 /*
 1063  * Crypto thread, dispatches crypto requests.
 1064  */
 1065 static void
 1066 crypto_proc(void)
 1067 {
 1068         struct cryptop *crp, *submit;
 1069         struct cryptkop *krp;
 1070         struct cryptocap *cap;
 1071         int result, hint;
 1072 
 1073         CRYPTO_Q_LOCK();
 1074         for (;;) {
 1075                 /*
 1076                  * Find the first element in the queue that can be
 1077                  * processed and look-ahead to see if multiple ops
 1078                  * are ready for the same driver.
 1079                  */
 1080                 submit = NULL;
 1081                 hint = 0;
 1082                 TAILQ_FOREACH(crp, &crp_q, crp_next) {
 1083                         u_int32_t hid = CRYPTO_SESID2HID(crp->crp_sid);
 1084                         cap = crypto_checkdriver(hid);
 1085                         if (cap == NULL || cap->cc_process == NULL) {
 1086                                 /* Op needs to be migrated, process it. */
 1087                                 if (submit == NULL)
 1088                                         submit = crp;
 1089                                 break;
 1090                         }
 1091                         if (!cap->cc_qblocked) {
 1092                                 if (submit != NULL) {
 1093                                         /*
 1094                                          * We stop on finding another op,
 1095                                          * regardless whether its for the same
 1096                                          * driver or not.  We could keep
 1097                                          * searching the queue but it might be
 1098                                          * better to just use a per-driver
 1099                                          * queue instead.
 1100                                          */
 1101                                         if (CRYPTO_SESID2HID(submit->crp_sid) == hid)
 1102                                                 hint = CRYPTO_HINT_MORE;
 1103                                         break;
 1104                                 } else {
 1105                                         submit = crp;
 1106                                         if ((submit->crp_flags & CRYPTO_F_BATCH) == 0)
 1107                                                 break;
 1108                                         /* keep scanning for more are q'd */
 1109                                 }
 1110                         }
 1111                 }
 1112                 if (submit != NULL) {
 1113                         TAILQ_REMOVE(&crp_q, submit, crp_next);
 1114                         result = crypto_invoke(submit, hint);
 1115                         if (result == ERESTART) {
 1116                                 /*
 1117                                  * The driver ran out of resources, mark the
 1118                                  * driver ``blocked'' for cryptop's and put
 1119                                  * the request back in the queue.  It would
 1120                                  * best to put the request back where we got
 1121                                  * it but that's hard so for now we put it
 1122                                  * at the front.  This should be ok; putting
 1123                                  * it at the end does not work.
 1124                                  */
 1125                                 /* XXX validate sid again? */
 1126                                 crypto_drivers[CRYPTO_SESID2HID(submit->crp_sid)].cc_qblocked = 1;
 1127                                 TAILQ_INSERT_HEAD(&crp_q, submit, crp_next);
 1128                                 cryptostats.cs_blocks++;
 1129                         }
 1130                 }
 1131 
 1132                 /* As above, but for key ops */
 1133                 TAILQ_FOREACH(krp, &crp_kq, krp_next) {
 1134                         cap = crypto_checkdriver(krp->krp_hid);
 1135                         if (cap == NULL || cap->cc_kprocess == NULL) {
 1136                                 /* Op needs to be migrated, process it. */
 1137                                 break;
 1138                         }
 1139                         if (!cap->cc_kqblocked)
 1140                                 break;
 1141                 }
 1142                 if (krp != NULL) {
 1143                         TAILQ_REMOVE(&crp_kq, krp, krp_next);
 1144                         result = crypto_kinvoke(krp, 0);
 1145                         if (result == ERESTART) {
 1146                                 /*
 1147                                  * The driver ran out of resources, mark the
 1148                                  * driver ``blocked'' for cryptkop's and put
 1149                                  * the request back in the queue.  It would
 1150                                  * best to put the request back where we got
 1151                                  * it but that's hard so for now we put it
 1152                                  * at the front.  This should be ok; putting
 1153                                  * it at the end does not work.
 1154                                  */
 1155                                 /* XXX validate sid again? */
 1156                                 crypto_drivers[krp->krp_hid].cc_kqblocked = 1;
 1157                                 TAILQ_INSERT_HEAD(&crp_kq, krp, krp_next);
 1158                                 cryptostats.cs_kblocks++;
 1159                         }
 1160                 }
 1161 
 1162                 if (submit == NULL && krp == NULL) {
 1163                         /*
 1164                          * Nothing more to be processed.  Sleep until we're
 1165                          * woken because there are more ops to process.
 1166                          * This happens either by submission or by a driver
 1167                          * becoming unblocked and notifying us through
 1168                          * crypto_unblock.  Note that when we wakeup we
 1169                          * start processing each queue again from the
 1170                          * front. It's not clear that it's important to
 1171                          * preserve this ordering since ops may finish
 1172                          * out of order if dispatched to different devices
 1173                          * and some become blocked while others do not.
 1174                          */
 1175                         msleep(&crp_q, &crypto_q_mtx, PWAIT, "crypto_wait", 0);
 1176                         if (cryptoproc == NULL)
 1177                                 break;
 1178                         cryptostats.cs_intrs++;
 1179                 }
 1180         }
 1181         CRYPTO_Q_UNLOCK();
 1182 
 1183         crypto_finis(&crp_q);
 1184 }
 1185 
 1186 /*
 1187  * Crypto returns thread, does callbacks for processed crypto requests.
 1188  * Callbacks are done here, rather than in the crypto drivers, because
 1189  * callbacks typically are expensive and would slow interrupt handling.
 1190  */
 1191 static void
 1192 crypto_ret_proc(void)
 1193 {
 1194         struct cryptop *crpt;
 1195         struct cryptkop *krpt;
 1196 
 1197         CRYPTO_RETQ_LOCK();
 1198         for (;;) {
 1199                 /* Harvest return q's for completed ops */
 1200                 crpt = TAILQ_FIRST(&crp_ret_q);
 1201                 if (crpt != NULL)
 1202                         TAILQ_REMOVE(&crp_ret_q, crpt, crp_next);
 1203 
 1204                 krpt = TAILQ_FIRST(&crp_ret_kq);
 1205                 if (krpt != NULL)
 1206                         TAILQ_REMOVE(&crp_ret_kq, krpt, krp_next);
 1207 
 1208                 if (crpt != NULL || krpt != NULL) {
 1209                         CRYPTO_RETQ_UNLOCK();
 1210                         /*
 1211                          * Run callbacks unlocked.
 1212                          */
 1213                         if (crpt != NULL) {
 1214 #ifdef CRYPTO_TIMING
 1215                                 if (crypto_timing) {
 1216                                         /*
 1217                                          * NB: We must copy the timestamp before
 1218                                          * doing the callback as the cryptop is
 1219                                          * likely to be reclaimed.
 1220                                          */
 1221                                         struct bintime t = crpt->crp_tstamp;
 1222                                         crypto_tstat(&cryptostats.cs_cb, &t);
 1223                                         crpt->crp_callback(crpt);
 1224                                         crypto_tstat(&cryptostats.cs_finis, &t);
 1225                                 } else
 1226 #endif
 1227                                         crpt->crp_callback(crpt);
 1228                         }
 1229                         if (krpt != NULL)
 1230                                 krpt->krp_callback(krpt);
 1231                         CRYPTO_RETQ_LOCK();
 1232                 } else {
 1233                         /*
 1234                          * Nothing more to be processed.  Sleep until we're
 1235                          * woken because there are more returns to process.
 1236                          */
 1237                         msleep(&crp_ret_q, &crypto_ret_q_mtx, PWAIT,
 1238                                 "crypto_ret_wait", 0);
 1239                         if (cryptoretproc == NULL)
 1240                                 break;
 1241                         cryptostats.cs_rets++;
 1242                 }
 1243         }
 1244         CRYPTO_RETQ_UNLOCK();
 1245 
 1246         crypto_finis(&crp_ret_q);
 1247 }

Cache object: 2162c70ea7bbdb5073954d53e3805d20


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.