Module Name: src Committed By: tls Date: Sun Aug 25 21:12:56 UTC 2013
Modified Files: src/sys/dev: rnd_private.h src/sys/kern: init_main.c kern_rndq.c kern_rndsink.c Log Message: Attempt to resolve locking issues at kernel startup on platforms with hardware RNGs using the polling mode of operation: 1) Initialize the rng subsystem soft interrupts as early in kernel startup as seems safe (we have no MI guarantee that softints are working at all until configure2() returns, AFAICT). This should have the rnd subsystem able to process events via softint before the network subsystem (a notorious early user of entropy) starts. 2) Remove the shortcut calls to rnd_process_events() from rnd_schedule_process(), with the result that until the softint is installed rnd_process_events() is a NOP. 3) Directly call rnd_process_events() in rnd_extract_data(), rnd_maybe_extract(), and rnd_init_softint(). This should suck up any samples actually collected as early as possible. To generate a diff of this commit: cvs rdiff -u -r1.1 -r1.2 src/sys/dev/rnd_private.h cvs rdiff -u -r1.450 -r1.451 src/sys/kern/init_main.c cvs rdiff -u -r1.14 -r1.15 src/sys/kern/kern_rndq.c cvs rdiff -u -r1.2 -r1.3 src/sys/kern/kern_rndsink.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/dev/rnd_private.h diff -u src/sys/dev/rnd_private.h:1.1 src/sys/dev/rnd_private.h:1.2 --- src/sys/dev/rnd_private.h:1.1 Tue Nov 29 03:50:31 2011 +++ src/sys/dev/rnd_private.h Sun Aug 25 21:12:56 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: rnd_private.h,v 1.1 2011/11/29 03:50:31 tls Exp $ */ +/* $NetBSD: rnd_private.h,v 1.2 2013/08/25 21:12:56 tls Exp $ */ /*- * Copyright (c) 1997 The NetBSD Foundation, Inc. @@ -55,4 +55,6 @@ (short read ok) */ uint32_t rnd_extract_data(void *, uint32_t, uint32_t); +void rnd_process_events(void); /* XXX should be static */ + #endif Index: src/sys/kern/init_main.c diff -u src/sys/kern/init_main.c:1.450 src/sys/kern/init_main.c:1.451 --- src/sys/kern/init_main.c:1.450 Thu Jun 20 23:21:41 2013 +++ src/sys/kern/init_main.c Sun Aug 25 21:12:56 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: init_main.c,v 1.450 2013/06/20 23:21:41 christos Exp $ */ +/* $NetBSD: init_main.c,v 1.451 2013/08/25 21:12:56 tls Exp $ */ /*- * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc. @@ -97,7 +97,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: init_main.c,v 1.450 2013/06/20 23:21:41 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: init_main.c,v 1.451 2013/08/25 21:12:56 tls Exp $"); #include "opt_ddb.h" #include "opt_ipsec.h" @@ -519,6 +519,9 @@ main(void) /* Now timer is working. Enable preemption. */ kpreempt_enable(); + /* Enable deferred processing of RNG samples */ + rnd_init_softint(); + #ifdef SYSVSHM /* Initialize System V style shared memory. */ shminit(); @@ -565,8 +568,6 @@ main(void) if_attachdomain(); splx(s); - rnd_init_softint(); - #ifdef GPROF /* Initialize kernel profiling. */ kmstartup(); Index: src/sys/kern/kern_rndq.c diff -u src/sys/kern/kern_rndq.c:1.14 src/sys/kern/kern_rndq.c:1.15 --- src/sys/kern/kern_rndq.c:1.14 Sun Jun 23 02:35:24 2013 +++ src/sys/kern/kern_rndq.c Sun Aug 25 21:12:56 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: kern_rndq.c,v 1.14 2013/06/23 02:35:24 riastradh Exp $ */ +/* $NetBSD: kern_rndq.c,v 1.15 2013/08/25 21:12:56 tls Exp $ */ /*- * Copyright (c) 1997-2013 The NetBSD Foundation, Inc. @@ -32,7 +32,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: kern_rndq.c,v 1.14 2013/06/23 02:35:24 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kern_rndq.c,v 1.15 2013/08/25 21:12:56 tls Exp $"); #include <sys/param.h> #include <sys/ioctl.h> @@ -146,7 +146,6 @@ static inline u_int32_t rnd_estimate_ent static inline u_int32_t rnd_counter(void); static void rnd_intr(void *); static void rnd_wake(void *); -static void rnd_process_events(void); u_int32_t rnd_extract_data_locked(void *, u_int32_t, u_int32_t); /* XXX */ static void rnd_add_data_ts(krndsource_t *, const void *const, uint32_t, uint32_t, uint32_t); @@ -167,7 +166,10 @@ rndsave_t *boot_rsp; void rnd_init_softint(void) { rnd_process = softint_establish(SOFTINT_SERIAL|SOFTINT_MPSAFE, - rnd_intr, NULL); + rnd_intr, NULL); + rnd_wakeup = softint_establish(SOFTINT_CLOCK|SOFTINT_MPSAFE, + rnd_wake, NULL); + rnd_process_events(); } /* @@ -210,7 +212,6 @@ rnd_schedule_process(void) rnd_schedule_softint(rnd_process); return; } - rnd_process_events(); } static inline void @@ -220,11 +221,6 @@ rnd_schedule_wakeup(void) rnd_schedule_softint(rnd_wakeup); return; } - if (!cold) { - rnd_wakeup = softint_establish(SOFTINT_CLOCK|SOFTINT_MPSAFE, - rnd_wake, NULL); - } - rnd_wakeup_readers(); } /* @@ -821,7 +817,7 @@ rnd_hwrng_test(rnd_sample_t *sample) * is, if we are "cold" -- just booted). * */ -static void +void rnd_process_events(void) { rnd_sample_t *sample = NULL; @@ -1037,6 +1033,8 @@ rnd_extract_data(void *p, u_int32_t len, { uint32_t retval; + rnd_process_events(); /* XXX extra take/release rndpool_mtx */ + mutex_spin_enter(&rndpool_mtx); retval = rnd_extract_data_locked(p, len, flags); mutex_spin_exit(&rndpool_mtx); Index: src/sys/kern/kern_rndsink.c diff -u src/sys/kern/kern_rndsink.c:1.2 src/sys/kern/kern_rndsink.c:1.3 --- src/sys/kern/kern_rndsink.c:1.2 Mon Jun 24 04:21:20 2013 +++ src/sys/kern/kern_rndsink.c Sun Aug 25 21:12:56 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: kern_rndsink.c,v 1.2 2013/06/24 04:21:20 riastradh Exp $ */ +/* $NetBSD: kern_rndsink.c,v 1.3 2013/08/25 21:12:56 tls Exp $ */ /*- * Copyright (c) 2013 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: kern_rndsink.c,v 1.2 2013/06/24 04:21:20 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kern_rndsink.c,v 1.3 2013/08/25 21:12:56 tls Exp $"); #include <sys/param.h> #include <sys/types.h> @@ -131,6 +131,8 @@ rndpool_maybe_extract(void *buffer, size const uint32_t bits_needed = ((bytes + RND_ENTROPY_THRESHOLD) * NBBY); + rnd_process_events(); /* XXX extra take/release rndpool_mtx */ + mutex_spin_enter(&rndpool_mtx); if (bits_needed <= rndpool_get_entropy_count(&rnd_pool)) { const uint32_t extracted __unused =