Module Name:    src
Committed By:   riastradh
Date:           Wed Mar 16 23:56:33 UTC 2022

Modified Files:
        src/share/man/man9: cprng.9
        src/sys/kern: subr_cprng.c

Log Message:
cprng(9): Forbid use in hard interrupt context.

May need access to the global entropy pool (infrequently).  This way
the global entropy pool lock can be lowered to IPL_SOFTSERIAL too,
with a little additional work.


To generate a diff of this commit:
cvs rdiff -u -r1.14 -r1.15 src/share/man/man9/cprng.9
cvs rdiff -u -r1.41 -r1.42 src/sys/kern/subr_cprng.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/share/man/man9/cprng.9
diff -u src/share/man/man9/cprng.9:1.14 src/share/man/man9/cprng.9:1.15
--- src/share/man/man9/cprng.9:1.14	Mon Aug 17 06:07:53 2020
+++ src/share/man/man9/cprng.9	Wed Mar 16 23:56:33 2022
@@ -1,4 +1,4 @@
-.\"	$NetBSD: cprng.9,v 1.14 2020/08/17 06:07:53 wiz Exp $
+.\"	$NetBSD: cprng.9,v 1.15 2022/03/16 23:56:33 riastradh Exp $
 .\"
 .\" Copyright (c) 2011-2015 The NetBSD Foundation, Inc.
 .\" All rights reserved.
@@ -93,16 +93,14 @@ the strong generator can also be created
 .Pp
 The
 .Nm
-functions may be used at interrupt priority level
-.Dv IPL_VM
-or below,
+functions may be used in soft interrupt context,
 except for
 .Fn cprng_strong_create
 and
 .Fn cprng_strong_destroy
 which are allowed only at
-.Dv IPL_NONE ;
-see
+.Dv IPL_NONE
+in thread context; see
 .Xr spl 9 .
 .Pp
 The

Index: src/sys/kern/subr_cprng.c
diff -u src/sys/kern/subr_cprng.c:1.41 src/sys/kern/subr_cprng.c:1.42
--- src/sys/kern/subr_cprng.c:1.41	Wed Jul 21 06:35:45 2021
+++ src/sys/kern/subr_cprng.c	Wed Mar 16 23:56:33 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: subr_cprng.c,v 1.41 2021/07/21 06:35:45 skrll Exp $	*/
+/*	$NetBSD: subr_cprng.c,v 1.42 2022/03/16 23:56:33 riastradh Exp $	*/
 
 /*-
  * Copyright (c) 2019 The NetBSD Foundation, Inc.
@@ -44,7 +44,7 @@
  *	This code serves the first two categories without having extra
  *	logic for /dev/random.
  *
- *	kern_cprng - available at IPL_VM or lower
+ *	kern_cprng - available at IPL_SOFTSERIAL or lower
  *	user_cprng - available only at IPL_NONE in thread context
  *
  *	The name kern_cprng is for hysterical raisins.  The name
@@ -52,7 +52,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: subr_cprng.c,v 1.41 2021/07/21 06:35:45 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: subr_cprng.c,v 1.42 2022/03/16 23:56:33 riastradh Exp $");
 
 #include <sys/param.h>
 #include <sys/types.h>
@@ -88,7 +88,6 @@ struct cprng_cpu {
 	struct nist_hash_drbg	*cc_drbg;
 	struct {
 		struct evcnt	reseed;
-		struct evcnt	intr;
 	}			*cc_evcnt;
 	unsigned		cc_epoch;
 };
@@ -99,7 +98,7 @@ static void	cprng_init_cpu(void *, void 
 static void	cprng_fini_cpu(void *, void *, struct cpu_info *);
 
 /* Well-known CPRNG instances */
-struct cprng_strong *kern_cprng __read_mostly; /* IPL_VM */
+struct cprng_strong *kern_cprng __read_mostly; /* IPL_SOFTSERIAL */
 struct cprng_strong *user_cprng __read_mostly; /* IPL_NONE */
 
 static struct sysctllog *cprng_sysctllog __read_mostly;
@@ -112,12 +111,12 @@ cprng_init(void)
 		panic("NIST Hash_DRBG failed self-test");
 
 	/*
-	 * Create CPRNG instances at two IPLs: IPL_VM for kernel use
-	 * that may occur inside IPL_VM interrupt handlers (!!??!?!?),
+	 * Create CPRNG instances at two IPLs: IPL_SOFTSERIAL for
+	 * kernel use that may occur inside soft interrupt handlers,
 	 * and IPL_NONE for userland use which need not block
 	 * interrupts.
 	 */
-	kern_cprng = cprng_strong_create("kern", IPL_VM, 0);
+	kern_cprng = cprng_strong_create("kern", IPL_SOFTSERIAL, 0);
 	user_cprng = cprng_strong_create("user", IPL_NONE, 0);
 
 	/* Create kern.urandom and kern.arandom sysctl nodes.  */
@@ -246,8 +245,6 @@ cprng_init_cpu(void *ptr, void *cookie, 
 	/* Attach the event counters.  */
 	/* XXX ci_cpuname may not be initialized early enough.  */
 	cpuname = ci->ci_cpuname[0] == '\0' ? "cpu0" : ci->ci_cpuname;
-	evcnt_attach_dynamic(&cc->cc_evcnt->intr, EVCNT_TYPE_MISC, NULL,
-	    cpuname, "cprng_strong intr");
 	evcnt_attach_dynamic(&cc->cc_evcnt->reseed, EVCNT_TYPE_MISC, NULL,
 	    cpuname, "cprng_strong reseed");
 
@@ -261,7 +258,6 @@ cprng_fini_cpu(void *ptr, void *cookie, 
 	struct cprng_cpu *cc = ptr;
 
 	evcnt_detach(&cc->cc_evcnt->reseed);
-	evcnt_detach(&cc->cc_evcnt->intr);
 	if (__predict_false(nist_hash_drbg_destroy(cc->cc_drbg)))
 		panic("nist_hash_drbg_destroy");
 
@@ -277,6 +273,9 @@ cprng_strong(struct cprng_strong *cprng,
 	unsigned epoch;
 	int s;
 
+	/* Not allowed in hard interrupt context.  */
+	KASSERT(!cpu_intr_p());
+
 	/*
 	 * Verify maximum request length.  Caller should really limit
 	 * their requests to 32 bytes to avoid spending much time with
@@ -292,9 +291,6 @@ cprng_strong(struct cprng_strong *cprng,
 	cc = percpu_getref(cprng->cs_percpu);
 	s = splraiseipl(cprng->cs_iplcookie);
 
-	if (cpu_intr_p())
-		cc->cc_evcnt->intr.ev_count++;
-
 	/* If the entropy epoch has changed, (re)seed.  */
 	epoch = entropy_epoch();
 	if (__predict_false(epoch != cc->cc_epoch)) {

Reply via email to