diff options
author | 2000-06-18 03:07:11 +0000 | |
---|---|---|
committer | 2000-06-18 03:07:11 +0000 | |
commit | 8a16a66f3d2dfca3b7858517fe4c193345c516b1 (patch) | |
tree | a63e7dbd99cb9ad9a7ec44b0b252c7842b33ca34 | |
parent | initial support for ssh.com's 2.2.0 (diff) | |
download | wireguard-openbsd-8a16a66f3d2dfca3b7858517fe4c193345c516b1.tar.xz wireguard-openbsd-8a16a66f3d2dfca3b7858517fe4c193345c516b1.zip |
Crypto kernel thread interface; requests are enqueued and processed by
a kernel thread. This allows a much cleaner interface with respect to
spl levels.
-rw-r--r-- | sys/crypto/crypto.c | 80 | ||||
-rw-r--r-- | sys/crypto/crypto.h | 1 |
2 files changed, 77 insertions, 4 deletions
diff --git a/sys/crypto/crypto.c b/sys/crypto/crypto.c index a88d56b300f..d9fb8d7f5cb 100644 --- a/sys/crypto/crypto.c +++ b/sys/crypto/crypto.c @@ -1,4 +1,4 @@ -/* $OpenBSD: crypto.c,v 1.7 2000/06/06 06:49:47 deraadt Exp $ */ +/* $OpenBSD: crypto.c,v 1.8 2000/06/18 03:07:11 angelos Exp $ */ /* * The author of this code is Angelos D. Keromytis (angelos@cis.upenn.edu) @@ -42,9 +42,15 @@ int crypto_drivers_num = 0; struct cryptop *cryptop_queue = NULL; struct cryptodesc *cryptodesc_queue = NULL; + int crypto_queue_num = 0; int crypto_queue_max = CRYPTO_MAX_CACHED; +struct cryptop *crp_req_queue = NULL; +struct cryptop **crp_req_queue_tail = NULL; + +int crypto_invoke(struct cryptop *); + /* * Create a new session. */ @@ -158,7 +164,7 @@ crypto_get_driverid(void) if (crypto_drivers_num == 0) { - crypto_drivers_num = CRYPTO_DRIVERS_INITIAL; + crypto_drivers_num = CRYPTO_DRIVERS_INITIAL; MALLOC(crypto_drivers, struct cryptocap *, crypto_drivers_num * sizeof(struct cryptocap), M_XDATA, M_DONTWAIT); @@ -275,11 +281,31 @@ crypto_unregister(u_int32_t driverid, int alg) } /* - * Dispatch a crypto request to the appropriate crypto devices. + * Add crypto request to a queue, to be processed by a kernel thread. */ int crypto_dispatch(struct cryptop *crp) { + int s = splhigh(); + + if (crp_req_queue == NULL) + crp_req_queue = crp; + else + crp->crp_next = NULL; + + crp_req_queue_tail = &(crp->crp_next); + wakeup((caddr_t) &crp_req_queue); + splx(s); + + return 0; +} + +/* + * Dispatch a crypto request to the appropriate crypto devices. + */ +int +crypto_invoke(struct cryptop *crp) +{ struct cryptodesc *crd; u_int64_t nid; u_int32_t hid; @@ -339,10 +365,13 @@ void crypto_freereq(struct cryptop *crp) { struct cryptodesc *crd; + int s; if (crp == NULL) return; + s = splhigh(); + while ((crd = crp->crp_desc) != NULL) { crp->crp_desc = crd->crd_next; @@ -365,6 +394,8 @@ crypto_freereq(struct cryptop *crp) cryptop_queue = crp; crypto_queue_num++; } + + splx(s); } /* @@ -375,13 +406,17 @@ crypto_getreq(int num) { struct cryptodesc *crd; struct cryptop *crp; + int s = splhigh(); if (cryptop_queue == NULL) { MALLOC(crp, struct cryptop *, sizeof(struct cryptop), M_XDATA, M_DONTWAIT); if (crp == NULL) - return NULL; + { + splx(s); + return NULL; + } } else { @@ -400,6 +435,7 @@ crypto_getreq(int num) M_XDATA, M_DONTWAIT); if (crd == NULL) { + splx(s); crypto_freereq(crp); return NULL; } @@ -416,5 +452,41 @@ crypto_getreq(int num) crp->crp_desc = crd; } + splx(s); return crp; } + +/* + * Crypto thread, runs as a kernel thread to process crypto requests. + */ +void +crypto_thread(void) +{ + struct cryptop *crp; + int s; + + s = splhigh(); + + for (;;) + { + crp = crp_req_queue; + if (crp == NULL) /* No work to do */ + { + (void) tsleep(&crp_req_queue, PLOCK, "crypto_wait", 0); + continue; + } + + /* Remove from the queue */ + crp_req_queue = crp->crp_next; + if (crp_req_queue) + crp_req_queue_tail = &crp_req_queue->crp_next; + else + crp_req_queue_tail = NULL; + + splx(s); + + crypto_invoke(crp); + + s = splhigh(); + } +} diff --git a/sys/crypto/crypto.h b/sys/crypto/crypto.h index a008bdb96da..1389301a9e8 100644 --- a/sys/crypto/crypto.h +++ b/sys/crypto/crypto.h @@ -161,5 +161,6 @@ int mbuf2pages(struct mbuf *, int *, long *, int *, int, int *); extern struct cryptop *crypto_getreq(int); extern void crypto_freereq(struct cryptop *); +extern void crypto_thread(void); #endif /* _KERNEL */ #endif /* _CRYPTO_CRYPTO_H_ */ |