Module Name: src
Committed By: snj
Date: Wed Jul 5 20:19:22 UTC 2017
Modified Files:
src/sys/opencrypto [netbsd-8]: crypto.c cryptodev.c cryptodev.h
cryptosoft.c
src/sys/rump/dev/lib/libopencrypto [netbsd-8]: opencrypto_component.c
Log Message:
Pull up following revision(s) (requested by knakahara in ticket #97):
sys/opencrypto/crypto.c: 1.87-1.91
sys/opencrypto/cryptodev.c: 1.93-1.95
sys/opencrypto/cryptodev.h: 1.37
sys/opencrypto/cryptosoft.c: 1.52
sys/rump/dev/lib/libopencrypto/opencrypto_component.c: 1.5
sanitize count used for kmem_alloc size.
Hmm, who uses CIOCNGSESSION, CIOCNFSESSION, CIOCNCRYPTM or CIOCNFKEYM?
--
sanitize in CIOCNCRYPTM and initialize comp_alg in CIOCNGSESSION
--
must release cap->cc_lock before calling cap->cc_newsession() because of
spinlock.
--
refactor crypto_newsession() like FreeBSD.
--
support multiple encryption drivers (port from FreeBSD).
--
Divide crp_devflags from crp_flags to write exclusively.
CRYPTO_F_DQRETQ(new name is CRYPTODEV_F_RET) is used by cryptodev.c only.
It should be divided to other member.
--
Reduce crypto_ret_q_mtx lock regions.
crypto.c does not access the members of crp when the crp is in crp_q or
crp_ret_q. Furthermore, crp_q and crp_ret_q are protected by each mutex,
so the members of crp is not shared. That means crp_flags is not required
mutex in crypto.c.
--
fix cryptosoft.c:r1.51 mistake. swcrypto_attach() must not be called from
module_init_class().
swcrypto_attach() will call softint_establish(), it must be called after cpus
attached. module_init_class() is too early to call softint_establish().
--
simplify mutex_enter/exit(crypto_q_mtx), and fix missing exit.
--
reduce rump waring message. pointed out by [email protected], thanks.
To generate a diff of this commit:
cvs rdiff -u -r1.78.2.1 -r1.78.2.2 src/sys/opencrypto/crypto.c
cvs rdiff -u -r1.92 -r1.92.2.1 src/sys/opencrypto/cryptodev.c
cvs rdiff -u -r1.34.2.1 -r1.34.2.2 src/sys/opencrypto/cryptodev.h
cvs rdiff -u -r1.51 -r1.51.2.1 src/sys/opencrypto/cryptosoft.c
cvs rdiff -u -r1.4 -r1.4.10.1 \
src/sys/rump/dev/lib/libopencrypto/opencrypto_component.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/opencrypto/crypto.c
diff -u src/sys/opencrypto/crypto.c:1.78.2.1 src/sys/opencrypto/crypto.c:1.78.2.2
--- src/sys/opencrypto/crypto.c:1.78.2.1 Thu Jun 22 05:36:41 2017
+++ src/sys/opencrypto/crypto.c Wed Jul 5 20:19:21 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: crypto.c,v 1.78.2.1 2017/06/22 05:36:41 snj Exp $ */
+/* $NetBSD: crypto.c,v 1.78.2.2 2017/07/05 20:19:21 snj Exp $ */
/* $FreeBSD: src/sys/opencrypto/crypto.c,v 1.4.2.5 2003/02/26 00:14:05 sam Exp $ */
/* $OpenBSD: crypto.c,v 1.41 2002/07/17 23:52:38 art Exp $ */
@@ -53,7 +53,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: crypto.c,v 1.78.2.1 2017/06/22 05:36:41 snj Exp $");
+__KERNEL_RCSID(0, "$NetBSD: crypto.c,v 1.78.2.2 2017/07/05 20:19:21 snj Exp $");
#include <sys/param.h>
#include <sys/reboot.h>
@@ -501,27 +501,50 @@ crypto_destroy(bool exit_kthread)
return 0;
}
-/*
- * Create a new session.
- */
-int
-crypto_newsession(u_int64_t *sid, struct cryptoini *cri, int hard)
+static bool
+crypto_driver_suitable(struct cryptocap *cap, struct cryptoini *cri)
{
struct cryptoini *cr;
- struct cryptocap *cap;
- u_int32_t hid, lid;
- int err = EINVAL;
- mutex_enter(&crypto_drv_mtx);
+ for (cr = cri; cr; cr = cr->cri_next)
+ if (cap->cc_alg[cr->cri_alg] == 0) {
+ DPRINTF("alg %d not supported\n", cr->cri_alg);
+ return false;
+ }
+ return true;
+}
+
+#define CRYPTO_ACCEPT_HARDWARE 0x1
+#define CRYPTO_ACCEPT_SOFTWARE 0x2
+/*
+ * The algorithm we use here is pretty stupid; just use the
+ * first driver that supports all the algorithms we need.
+ * If there are multiple drivers we choose the driver with
+ * the fewest active sessions. We prefer hardware-backed
+ * drivers to software ones.
+ *
+ * XXX We need more smarts here (in real life too, but that's
+ * XXX another story altogether).
+ */
+static struct cryptocap *
+crypto_select_driver_lock(struct cryptoini *cri, int hard)
+{
+ u_int32_t hid;
+ int accept;
+ struct cryptocap *cap, *best;
+
+ best = NULL;
/*
- * The algorithm we use here is pretty stupid; just use the
- * first driver that supports all the algorithms we need.
- *
- * XXX We need more smarts here (in real life too, but that's
- * XXX another story altogether).
+ * hard == 0 can use both hardware and software drivers.
+ * We use hardware drivers prior to software drivers, so search
+ * hardware drivers at first time.
*/
-
+ if (hard >= 0)
+ accept = CRYPTO_ACCEPT_HARDWARE;
+ else
+ accept = CRYPTO_ACCEPT_SOFTWARE;
+again:
for (hid = 0; hid < crypto_drivers_num; hid++) {
cap = crypto_checkdriver(hid);
if (cap == NULL)
@@ -540,54 +563,85 @@ crypto_newsession(u_int64_t *sid, struct
}
/* Hardware required -- ignore software drivers. */
- if (hard > 0 && (cap->cc_flags & CRYPTOCAP_F_SOFTWARE)) {
+ if ((accept & CRYPTO_ACCEPT_SOFTWARE) == 0
+ && (cap->cc_flags & CRYPTOCAP_F_SOFTWARE)) {
crypto_driver_unlock(cap);
continue;
}
/* Software required -- ignore hardware drivers. */
- if (hard < 0 && (cap->cc_flags & CRYPTOCAP_F_SOFTWARE) == 0) {
+ if ((accept & CRYPTO_ACCEPT_HARDWARE) == 0
+ && (cap->cc_flags & CRYPTOCAP_F_SOFTWARE) == 0) {
crypto_driver_unlock(cap);
continue;
}
/* See if all the algorithms are supported. */
- for (cr = cri; cr; cr = cr->cri_next)
- if (cap->cc_alg[cr->cri_alg] == 0) {
- DPRINTF("alg %d not supported\n", cr->cri_alg);
- break;
+ if (crypto_driver_suitable(cap, cri)) {
+ if (best == NULL) {
+ /* keep holding crypto_driver_lock(cap) */
+ best = cap;
+ continue;
+ } else if (cap->cc_sessions < best->cc_sessions) {
+ crypto_driver_unlock(best);
+ /* keep holding crypto_driver_lock(cap) */
+ best = cap;
+ continue;
}
+ }
- if (cr == NULL) {
- /* Ok, all algorithms are supported. */
+ crypto_driver_unlock(cap);
+ }
+ if (best == NULL && hard == 0
+ && (accept & CRYPTO_ACCEPT_SOFTWARE) == 0) {
+ accept = CRYPTO_ACCEPT_SOFTWARE;
+ goto again;
+ }
- /*
- * Can't do everything in one session.
- *
- * XXX Fix this. We need to inject a "virtual" session layer right
- * XXX about here.
- */
+ return best;
+}
- /* Call the driver initialization routine. */
- lid = hid; /* Pass the driver ID. */
- err = cap->cc_newsession(cap->cc_arg, &lid, cri);
- if (err == 0) {
- (*sid) = hid;
- (*sid) <<= 32;
- (*sid) |= (lid & 0xffffffff);
- (cap->cc_sessions)++;
- } else {
- DPRINTF("crypto_drivers[%d].cc_newsession() failed. error=%d\n",
- hid, err);
- }
- crypto_driver_unlock(cap);
- goto done;
- /*break;*/
- }
+/*
+ * Create a new session.
+ */
+int
+crypto_newsession(u_int64_t *sid, struct cryptoini *cri, int hard)
+{
+ struct cryptocap *cap;
+ int err = EINVAL;
+
+ mutex_enter(&crypto_drv_mtx);
+
+ cap = crypto_select_driver_lock(cri, hard);
+ if (cap != NULL) {
+ u_int32_t hid, lid;
+ hid = cap - crypto_drivers;
+ /*
+ * Can't do everything in one session.
+ *
+ * XXX Fix this. We need to inject a "virtual" session layer right
+ * XXX about here.
+ */
+
+ /* Call the driver initialization routine. */
+ lid = hid; /* Pass the driver ID. */
+ crypto_driver_unlock(cap);
+ err = cap->cc_newsession(cap->cc_arg, &lid, cri);
+ crypto_driver_lock(cap);
+ if (err == 0) {
+ (*sid) = hid;
+ (*sid) <<= 32;
+ (*sid) |= (lid & 0xffffffff);
+ (cap->cc_sessions)++;
+ } else {
+ DPRINTF("crypto_drivers[%d].cc_newsession() failed. error=%d\n",
+ hid, err);
+ }
crypto_driver_unlock(cap);
}
-done:
+
mutex_exit(&crypto_drv_mtx);
+
return err;
}
@@ -1063,8 +1117,8 @@ crypto_dispatch(struct cryptop *crp)
* to other drivers in cryptointr() later.
*/
TAILQ_INSERT_TAIL(&crp_q, crp, crp_next);
- mutex_exit(&crypto_q_mtx);
- return 0;
+ result = 0;
+ goto out;
}
if (cap->cc_qblocked != 0) {
@@ -1074,8 +1128,8 @@ crypto_dispatch(struct cryptop *crp)
* it unblocks and the swi thread gets kicked.
*/
TAILQ_INSERT_TAIL(&crp_q, crp, crp_next);
- mutex_exit(&crypto_q_mtx);
- return 0;
+ result = 0;
+ goto out;
}
/*
@@ -1105,6 +1159,7 @@ crypto_dispatch(struct cryptop *crp)
result = 0;
}
+out:
mutex_exit(&crypto_q_mtx);
return result;
}
@@ -1132,8 +1187,8 @@ crypto_kdispatch(struct cryptkop *krp)
*/
if (cap == NULL) {
TAILQ_INSERT_TAIL(&crp_kq, krp, krp_next);
- mutex_exit(&crypto_q_mtx);
- return 0;
+ result = 0;
+ goto out;
}
if (cap->cc_kqblocked != 0) {
@@ -1143,8 +1198,8 @@ crypto_kdispatch(struct cryptkop *krp)
* it unblocks and the swi thread gets kicked.
*/
TAILQ_INSERT_TAIL(&crp_kq, krp, krp_next);
- mutex_exit(&crypto_q_mtx);
- return 0;
+ result = 0;
+ goto out;
}
crypto_driver_unlock(cap);
@@ -1160,7 +1215,6 @@ crypto_kdispatch(struct cryptkop *krp)
crypto_driver_unlock(cap);
TAILQ_INSERT_HEAD(&crp_kq, krp, krp_next);
cryptostats.cs_kblocks++;
- mutex_exit(&crypto_q_mtx);
/*
* The krp is enqueued to crp_kq, that is,
@@ -1170,6 +1224,8 @@ crypto_kdispatch(struct cryptkop *krp)
result = 0;
}
+out:
+ mutex_exit(&crypto_q_mtx);
return result;
}
@@ -1440,7 +1496,6 @@ crypto_kgetreq(int num __unused, int prf
void
crypto_done(struct cryptop *crp)
{
- int wasempty;
KASSERT(crp != NULL);
@@ -1466,9 +1521,7 @@ crypto_done(struct cryptop *crp)
* callback routine does very little (e.g. the
* /dev/crypto callback method just does a wakeup).
*/
- mutex_spin_enter(&crypto_ret_q_mtx);
crp->crp_flags |= CRYPTO_F_DONE;
- mutex_spin_exit(&crypto_ret_q_mtx);
#ifdef CRYPTO_TIMING
if (crypto_timing) {
@@ -1485,7 +1538,6 @@ crypto_done(struct cryptop *crp)
#endif
crp->crp_callback(crp);
} else {
- mutex_spin_enter(&crypto_ret_q_mtx);
crp->crp_flags |= CRYPTO_F_DONE;
#if 0
if (crp->crp_flags & CRYPTO_F_USER) {
@@ -1501,6 +1553,9 @@ crypto_done(struct cryptop *crp)
} else
#endif
{
+ int wasempty;
+
+ mutex_spin_enter(&crypto_ret_q_mtx);
wasempty = TAILQ_EMPTY(&crp_ret_q);
DPRINTF("lid[%u]: queueing %p\n",
CRYPTO_SESID2LID(crp->crp_sid), crp);
@@ -1513,8 +1568,8 @@ crypto_done(struct cryptop *crp)
CRYPTO_SESID2LID(crp->crp_sid), crp);
cv_signal(&cryptoret_cv);
}
+ mutex_spin_exit(&crypto_ret_q_mtx);
}
- mutex_spin_exit(&crypto_ret_q_mtx);
}
}
@@ -1524,7 +1579,6 @@ crypto_done(struct cryptop *crp)
void
crypto_kdone(struct cryptkop *krp)
{
- int wasempty;
KASSERT(krp != NULL);
@@ -1542,6 +1596,8 @@ crypto_kdone(struct cryptkop *krp)
if (krp->krp_flags & CRYPTO_F_CBIMM) {
krp->krp_callback(krp);
} else {
+ int wasempty;
+
mutex_spin_enter(&crypto_ret_q_mtx);
wasempty = TAILQ_EMPTY(&crp_ret_kq);
krp->krp_flags |= CRYPTO_F_ONRETQ;
Index: src/sys/opencrypto/cryptodev.c
diff -u src/sys/opencrypto/cryptodev.c:1.92 src/sys/opencrypto/cryptodev.c:1.92.2.1
--- src/sys/opencrypto/cryptodev.c:1.92 Fri Jun 2 09:46:57 2017
+++ src/sys/opencrypto/cryptodev.c Wed Jul 5 20:19:21 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: cryptodev.c,v 1.92 2017/06/02 09:46:57 knakahara Exp $ */
+/* $NetBSD: cryptodev.c,v 1.92.2.1 2017/07/05 20:19:21 snj Exp $ */
/* $FreeBSD: src/sys/opencrypto/cryptodev.c,v 1.4.2.4 2003/06/03 00:09:02 sam Exp $ */
/* $OpenBSD: cryptodev.c,v 1.53 2002/07/10 22:21:30 mickey Exp $ */
@@ -64,7 +64,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cryptodev.c,v 1.92 2017/06/02 09:46:57 knakahara Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cryptodev.c,v 1.92.2.1 2017/07/05 20:19:21 snj Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -281,6 +281,11 @@ cryptof_ioctl(struct file *fp, u_long cm
break;
case CIOCNGSESSION:
sgop = (struct crypt_sgop *)data;
+ if (sgop->count <= 0
+ || SIZE_MAX / sizeof(struct session_n_op) <= sgop->count) {
+ error = EINVAL;
+ break;
+ }
snop = kmem_alloc((sgop->count *
sizeof(struct session_n_op)), KM_SLEEP);
error = copyin(sgop->sessions, snop, sgop->count *
@@ -320,6 +325,11 @@ mbail:
fcr->mtime = fcr->atime;
mutex_exit(&cryptodev_mtx);
sfop = (struct crypt_sfop *)data;
+ if (sfop->count <= 0
+ || SIZE_MAX / sizeof(u_int32_t) <= sfop->count) {
+ error = EINVAL;
+ break;
+ }
sesid = kmem_alloc((sfop->count * sizeof(u_int32_t)),
KM_SLEEP);
error = copyin(sfop->sesid, sesid,
@@ -347,6 +357,11 @@ mbail:
fcr->mtime = fcr->atime;
mutex_exit(&cryptodev_mtx);
mop = (struct crypt_mop *)data;
+ if (mop->count <= 0
+ || SIZE_MAX / sizeof(struct crypt_n_op) <= mop->count) {
+ error = EINVAL;
+ break;
+ }
cnop = kmem_alloc((mop->count * sizeof(struct crypt_n_op)),
KM_SLEEP);
error = copyin(mop->reqs, cnop,
@@ -369,6 +384,11 @@ mbail:
fcr->mtime = fcr->atime;
mutex_exit(&cryptodev_mtx);
mkop = (struct crypt_mkop *)data;
+ if (mkop->count <= 0
+ || SIZE_MAX / sizeof(struct crypt_n_kop) <= mkop->count) {
+ error = EINVAL;
+ break;
+ }
knop = kmem_alloc((mkop->count * sizeof(struct crypt_n_kop)),
KM_SLEEP);
error = copyin(mkop->reqs, knop,
@@ -390,6 +410,11 @@ mbail:
mutex_exit(&cryptodev_mtx);
crypt_ret = (struct cryptret *)data;
count = crypt_ret->count;
+ if (count <= 0
+ || SIZE_MAX / sizeof(struct crypt_result) <= count) {
+ error = EINVAL;
+ break;
+ }
crypt_res = kmem_alloc((count * sizeof(struct crypt_result)),
KM_SLEEP);
error = copyin(crypt_ret->results, crypt_res,
@@ -664,7 +689,7 @@ eagain:
goto bail;
}
- while (!(crp->crp_flags & CRYPTO_F_DQRETQ)) {
+ while (!(crp->crp_devflags & CRYPTODEV_F_RET)) {
DPRINTF("cse->sid[%d]: sleeping on cv %p for crp %p\n",
(uint32_t)cse->sid, &crp->crp_cv, crp);
cv_wait(&crp->crp_cv, &cryptodev_mtx); /* XXX cv_wait_sig? */
@@ -738,7 +763,7 @@ cryptodev_cb(void *op)
mutex_enter(&cryptodev_mtx);
}
if (error != 0 || (crp->crp_flags & CRYPTO_F_DONE)) {
- crp->crp_flags |= CRYPTO_F_DQRETQ;
+ crp->crp_devflags |= CRYPTODEV_F_RET;
cv_signal(&crp->crp_cv);
}
mutex_exit(&cryptodev_mtx);
@@ -775,7 +800,7 @@ cryptodevkey_cb(void *op)
struct cryptkop *krp = op;
mutex_enter(&cryptodev_mtx);
- krp->krp_flags |= CRYPTO_F_DQRETQ;
+ krp->krp_devflags |= CRYPTODEV_F_RET;
cv_signal(&krp->krp_cv);
mutex_exit(&cryptodev_mtx);
return 0;
@@ -890,7 +915,7 @@ cryptodev_key(struct crypt_kop *kop)
}
mutex_enter(&cryptodev_mtx);
- while (!(krp->krp_flags & CRYPTO_F_DQRETQ)) {
+ while (!(krp->krp_devflags & CRYPTODEV_F_RET)) {
cv_wait(&krp->krp_cv, &cryptodev_mtx); /* XXX cv_wait_sig? */
}
mutex_exit(&cryptodev_mtx);
@@ -1156,6 +1181,12 @@ cryptodev_mop(struct fcrypt *fcr,
}
}
+ /* sanitize */
+ if (cnop[req].len <= 0) {
+ cnop[req].status = ENOMEM;
+ goto bail;
+ }
+
crp = crypto_getreq((cse->txform != NULL) +
(cse->thash != NULL) +
(cse->tcomp != NULL));
@@ -1745,12 +1776,14 @@ cryptodev_msession(struct fcrypt *fcr, s
struct session_op s_op;
s_op.cipher = sn_ops->cipher;
s_op.mac = sn_ops->mac;
+ s_op.comp_alg = sn_ops->comp_alg;
s_op.keylen = sn_ops->keylen;
s_op.key = sn_ops->key;
s_op.mackeylen = sn_ops->mackeylen;
s_op.mackey = sn_ops->mackey;
sn_ops->status = cryptodev_session(fcr, &s_op);
+
sn_ops->ses = s_op.ses;
}
Index: src/sys/opencrypto/cryptodev.h
diff -u src/sys/opencrypto/cryptodev.h:1.34.2.1 src/sys/opencrypto/cryptodev.h:1.34.2.2
--- src/sys/opencrypto/cryptodev.h:1.34.2.1 Thu Jun 22 05:36:41 2017
+++ src/sys/opencrypto/cryptodev.h Wed Jul 5 20:19:21 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: cryptodev.h,v 1.34.2.1 2017/06/22 05:36:41 snj Exp $ */
+/* $NetBSD: cryptodev.h,v 1.34.2.2 2017/07/05 20:19:21 snj Exp $ */
/* $FreeBSD: src/sys/opencrypto/cryptodev.h,v 1.2.2.6 2003/07/02 17:04:50 sam Exp $ */
/* $OpenBSD: cryptodev.h,v 1.33 2002/07/17 23:52:39 art Exp $ */
@@ -461,8 +461,10 @@ struct cryptop {
* should always check and use the new
* value on future requests.
*/
- int crp_flags; /* Note: must hold mutext to modify */
-
+ int crp_flags; /*
+ * other than crypto.c must not write
+ * after crypto_dispatch().
+ */
#define CRYPTO_F_IMBUF 0x0001 /* Input/output are mbuf chains */
#define CRYPTO_F_IOV 0x0002 /* Input/output are uio */
#define CRYPTO_F_REL 0x0004 /* Must return data in same place */
@@ -473,7 +475,9 @@ struct cryptop {
#define CRYPTO_F_ONRETQ 0x0080 /* Request is on return queue */
#define CRYPTO_F_USER 0x0100 /* Request is in user context */
#define CRYPTO_F_MORE 0x0200 /* more data to follow */
-#define CRYPTO_F_DQRETQ 0x0400 /* Dequeued from crp_ret_{,k}q */
+
+ int crp_devflags; /* other than cryptodev.c must not use. */
+#define CRYPTODEV_F_RET 0x0001 /* return from crypto.c to cryptodev.c */
void * crp_buf; /* Data to be processed */
void * crp_opaque; /* Opaque pointer, passed along */
@@ -528,6 +532,7 @@ struct cryptkop {
struct crparam krp_param[CRK_MAXPARAM]; /* kvm */
int (*krp_callback)(struct cryptkop *);
int krp_flags; /* same values as crp_flags */
+ int krp_devflags; /* same values as crp_devflags */
kcondvar_t krp_cv;
struct fcrypt *fcrp;
struct crparam crk_param[CRK_MAXPARAM];
Index: src/sys/opencrypto/cryptosoft.c
diff -u src/sys/opencrypto/cryptosoft.c:1.51 src/sys/opencrypto/cryptosoft.c:1.51.2.1
--- src/sys/opencrypto/cryptosoft.c:1.51 Thu Jun 1 08:49:35 2017
+++ src/sys/opencrypto/cryptosoft.c Wed Jul 5 20:19:21 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: cryptosoft.c,v 1.51 2017/06/01 08:49:35 knakahara Exp $ */
+/* $NetBSD: cryptosoft.c,v 1.51.2.1 2017/07/05 20:19:21 snj Exp $ */
/* $FreeBSD: src/sys/opencrypto/cryptosoft.c,v 1.2.2.1 2002/11/21 23:34:23 sam Exp $ */
/* $OpenBSD: cryptosoft.c,v 1.35 2002/04/26 08:43:50 deraadt Exp $ */
@@ -24,7 +24,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.51 2017/06/01 08:49:35 knakahara Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.51.2.1 2017/07/05 20:19:21 snj Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -77,6 +77,8 @@ static int swcr_process(void *, struct c
static int swcr_newsession(void *, u_int32_t *, struct cryptoini *);
static int swcr_freesession(void *, u_int64_t);
+static int swcryptoattach_internal(void);
+
/*
* Apply a symmetric encryption/decryption algorithm.
*/
@@ -1326,9 +1328,17 @@ void
swcryptoattach(int num)
{
/*
- * Nothing to do here, initialization is handled by the
- * module initialization code in swcrypto_attach() below).
+ * swcrypto_attach() must be called after attached cpus, because
+ * it calls softint_establish() through below call path.
+ * swcr_init() => crypto_get_driverid() => crypto_init()
+ * => crypto_init0()
+ * If softint_establish() is called before attached cpus that ncpu == 0,
+ * the softint handler is established to CPU#0 only.
+ *
+ * So, swcrypto_attach() must be called from not module_init_class()
+ * but config_finalize() when it is built as builtin module.
*/
+ swcryptoattach_internal();
}
void swcrypto_attach(device_t, device_t, void *);
@@ -1386,42 +1396,56 @@ static struct cfdata swcrypto_cfdata[] =
{ NULL, NULL, 0, 0, NULL, 0, NULL }
};
+/*
+ * Internal attach routine.
+ * Don't call before attached cpus.
+ */
static int
-swcrypto_modcmd(modcmd_t cmd, void *arg)
+swcryptoattach_internal(void)
{
int error;
- switch (cmd) {
- case MODULE_CMD_INIT:
- error = config_cfdriver_attach(&swcrypto_cd);
- if (error) {
- return error;
- }
+ error = config_cfdriver_attach(&swcrypto_cd);
+ if (error) {
+ return error;
+ }
+
+ error = config_cfattach_attach(swcrypto_cd.cd_name, &swcrypto_ca);
+ if (error) {
+ config_cfdriver_detach(&swcrypto_cd);
+ aprint_error("%s: unable to register cfattach\n",
+ swcrypto_cd.cd_name);
- error = config_cfattach_attach(swcrypto_cd.cd_name,
+ return error;
+ }
+
+ error = config_cfdata_attach(swcrypto_cfdata, 1);
+ if (error) {
+ config_cfattach_detach(swcrypto_cd.cd_name,
&swcrypto_ca);
- if (error) {
- config_cfdriver_detach(&swcrypto_cd);
- aprint_error("%s: unable to register cfattach\n",
- swcrypto_cd.cd_name);
+ config_cfdriver_detach(&swcrypto_cd);
+ aprint_error("%s: unable to register cfdata\n",
+ swcrypto_cd.cd_name);
- return error;
- }
+ return error;
+ }
- error = config_cfdata_attach(swcrypto_cfdata, 1);
- if (error) {
- config_cfattach_detach(swcrypto_cd.cd_name,
- &swcrypto_ca);
- config_cfdriver_detach(&swcrypto_cd);
- aprint_error("%s: unable to register cfdata\n",
- swcrypto_cd.cd_name);
+ (void)config_attach_pseudo(swcrypto_cfdata);
- return error;
- }
+ return 0;
+}
- (void)config_attach_pseudo(swcrypto_cfdata);
+static int
+swcrypto_modcmd(modcmd_t cmd, void *arg)
+{
+ int error = 0;
- return 0;
+ switch (cmd) {
+ case MODULE_CMD_INIT:
+#ifdef _MODULE
+ error = swcryptoattach_internal();
+#endif
+ return error;
case MODULE_CMD_FINI:
error = config_cfdata_detach(swcrypto_cfdata);
if (error) {
Index: src/sys/rump/dev/lib/libopencrypto/opencrypto_component.c
diff -u src/sys/rump/dev/lib/libopencrypto/opencrypto_component.c:1.4 src/sys/rump/dev/lib/libopencrypto/opencrypto_component.c:1.4.10.1
--- src/sys/rump/dev/lib/libopencrypto/opencrypto_component.c:1.4 Tue Jan 26 23:12:15 2016
+++ src/sys/rump/dev/lib/libopencrypto/opencrypto_component.c Wed Jul 5 20:19:22 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: opencrypto_component.c,v 1.4 2016/01/26 23:12:15 pooka Exp $ */
+/* $NetBSD: opencrypto_component.c,v 1.4.10.1 2017/07/05 20:19:22 snj Exp $ */
/*
* Copyright (c) 2009 Antti Kantee. All Rights Reserved.
@@ -26,7 +26,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: opencrypto_component.c,v 1.4 2016/01/26 23:12:15 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: opencrypto_component.c,v 1.4.10.1 2017/07/05 20:19:22 snj Exp $");
#include <sys/param.h>
#include <sys/conf.h>
@@ -64,5 +64,20 @@ RUMP_COMPONENT(RUMP_COMPONENT_DEV)
*/
crypto_init();
rump_pdev_add(cryptoattach, 1);
+#if 0
+ /*
+ * rump defines "_MODULE" in spite of using built-in module
+ * initialization(module_init_class()). So, swcryptoattach_internal()
+ * is called by two functions, one is swcryptoattach() and the other is
+ * swcrypto_modcmd().
+ * That causes "builtin module `swcrypto' failed to init" WARNING message.
+ * To suppress this warning, we let rump use swcrypto_modcmd() call-path
+ * only.
+ *
+ * TODO:
+ * There is still "crypto: unable to register devsw" message. it should
+ * be suppressed.
+ */
rump_pdev_add(swcryptoattach, 0);
+#endif
}