summaryrefslogtreecommitdiff
path: root/sys/crypto
diff options
context:
space:
mode:
authorDavid Gwynne <dlg@cvs.openbsd.org>2009-09-03 07:47:28 +0000
committerDavid Gwynne <dlg@cvs.openbsd.org>2009-09-03 07:47:28 +0000
commitf946653af52e63c2b12d989c15719f713e69dc42 (patch)
treec5330b6158f25b60b48ac1c2feb6290595a4b0b7 /sys/crypto
parent3ccdbcac647b954dc66ffa0516d03435301bb981 (diff)
crypto hardware (eg, hifn) establishes its interrupt handler at
IPL_NET. when the hardware finishes some work for the crypto subsystem and therefore something in the kernel that wanted crypto done, it calls crypto_done from that interrupt handler. one of the things that uses crypto is ipsec. when crypto is done for ipsec it then pushes the packet along the network stack. the problem is that all the structures inside the network stack are only protected at splsoftnet. we could be in the middle of modifications to the pf state table or the pfsync queues when we get a hifn interrupt and then go stomp on the same structures. the solution is to defer the completions so they can do the right spl protections. this basically reverts r1.46 of src/sys/crypto/crypto.c. found by naddy@
Diffstat (limited to 'sys/crypto')
-rw-r--r--sys/crypto/crypto.c19
-rw-r--r--sys/crypto/cryptodev.h7
2 files changed, 18 insertions, 8 deletions
diff --git a/sys/crypto/crypto.c b/sys/crypto/crypto.c
index 5faf0f645b7..a6445b3e30a 100644
--- a/sys/crypto/crypto.c
+++ b/sys/crypto/crypto.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: crypto.c,v 1.52 2008/10/30 23:55:22 dlg Exp $ */
+/* $OpenBSD: crypto.c,v 1.53 2009/09/03 07:47:27 dlg Exp $ */
/*
* The author of this code is Angelos D. Keromytis (angelos@cis.upenn.edu)
*
@@ -25,7 +25,6 @@
#include <sys/malloc.h>
#include <sys/proc.h>
#include <sys/pool.h>
-#include <sys/workq.h>
#include <crypto/cryptodev.h>
@@ -420,7 +419,7 @@ crypto_dispatch(struct cryptop *crp)
splx(s);
if (crypto_workq) {
- workq_add_task(crypto_workq, 0,
+ workq_queue_task(crypto_workq, &crp->crp_wqt, 0,
(workq_fn)crypto_invoke, crp, NULL);
} else {
crypto_invoke(crp);
@@ -432,9 +431,8 @@ crypto_dispatch(struct cryptop *crp)
int
crypto_kdispatch(struct cryptkop *krp)
{
-
if (crypto_workq) {
- workq_add_task(crypto_workq, 0,
+ workq_queue_task(crypto_workq, &krp->krp_wqt, 0,
(workq_fn)crypto_kinvoke, krp, NULL);
} else {
crypto_kinvoke(krp);
@@ -640,7 +638,13 @@ void
crypto_done(struct cryptop *crp)
{
crp->crp_flags |= CRYPTO_F_DONE;
- crp->crp_callback(crp);
+ if (crp->crp_flags & CRYPTO_F_NOQUEUE) {
+ /* not from the crypto queue, wakeup the userland process */
+ crp->crp_callback(crp);
+ } else {
+ workq_queue_task(crypto_workq, &crp->crp_wqt, 0,
+ (workq_fn)crp->crp_callback, crp, NULL);
+ }
}
/*
@@ -649,7 +653,8 @@ crypto_done(struct cryptop *crp)
void
crypto_kdone(struct cryptkop *krp)
{
- krp->krp_callback(krp);
+ workq_queue_task(crypto_workq, &krp->krp_wqt, 0,
+ (workq_fn)krp->krp_callback, krp, NULL);
}
int
diff --git a/sys/crypto/cryptodev.h b/sys/crypto/cryptodev.h
index 1a0e7d4a51c..1a736c985cc 100644
--- a/sys/crypto/cryptodev.h
+++ b/sys/crypto/cryptodev.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: cryptodev.h,v 1.47 2008/06/09 16:07:00 djm Exp $ */
+/* $OpenBSD: cryptodev.h,v 1.48 2009/09/03 07:47:27 dlg Exp $ */
/*
* The author of this code is Angelos D. Keromytis (angelos@cis.upenn.edu)
@@ -53,6 +53,7 @@
#define _CRYPTO_CRYPTO_H_
#include <sys/ioccom.h>
+#include <sys/workq.h>
/* Some initial values */
#define CRYPTO_DRIVERS_INITIAL 4
@@ -143,6 +144,8 @@ struct cryptodesc {
/* Structure describing complete operation */
struct cryptop {
+ struct workq_task crp_wqt;
+
u_int64_t crp_sid; /* Session ID */
int crp_ilen; /* Input data total length */
int crp_olen; /* Result total length */
@@ -211,6 +214,8 @@ struct crypt_kop {
#define CRF_DH_COMPUTE_KEY (1 << CRK_DH_COMPUTE_KEY)
struct cryptkop {
+ struct workq_task krp_wqt;
+
u_int krp_op; /* ie. CRK_MOD_EXP or other */
u_int krp_status; /* return status */
u_short krp_iparams; /* # of input parameters */