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
 }

Reply via email to