Module Name: src Committed By: pgoyette Date: Sun Jul 15 18:33:07 UTC 2012
Modified Files: src/sys/dev/sysmon: sysmon_envsys.c sysmon_envsys_events.c sysmonvar.h Log Message: If a sensor is flagged as capable of providing rnd(4) with entropy, hook the sensor into rnd subsystem, and make sure we periodically refresh the sensor whether or not it is being actively monitored. To generate a diff of this commit: cvs rdiff -u -r1.119 -r1.120 src/sys/dev/sysmon/sysmon_envsys.c cvs rdiff -u -r1.99 -r1.100 src/sys/dev/sysmon/sysmon_envsys_events.c cvs rdiff -u -r1.41 -r1.42 src/sys/dev/sysmon/sysmonvar.h 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/sysmon/sysmon_envsys.c diff -u src/sys/dev/sysmon/sysmon_envsys.c:1.119 src/sys/dev/sysmon/sysmon_envsys.c:1.120 --- src/sys/dev/sysmon/sysmon_envsys.c:1.119 Sun Jul 15 17:41:39 2012 +++ src/sys/dev/sysmon/sysmon_envsys.c Sun Jul 15 18:33:07 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: sysmon_envsys.c,v 1.119 2012/07/15 17:41:39 pgoyette Exp $ */ +/* $NetBSD: sysmon_envsys.c,v 1.120 2012/07/15 18:33:07 pgoyette Exp $ */ /*- * Copyright (c) 2007, 2008 Juan Romero Pardines. @@ -64,7 +64,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: sysmon_envsys.c,v 1.119 2012/07/15 17:41:39 pgoyette Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sysmon_envsys.c,v 1.120 2012/07/15 18:33:07 pgoyette Exp $"); #include <sys/param.h> #include <sys/types.h> @@ -76,6 +76,7 @@ __KERNEL_RCSID(0, "$NetBSD: sysmon_envsy #include <sys/proc.h> #include <sys/mutex.h> #include <sys/kmem.h> +#include <sys/rnd.h> /* #define ENVSYS_DEBUG */ #include <dev/sysmon/sysmonvar.h> @@ -360,7 +361,7 @@ sysmonioctl_envsys(dev_t dev, u_long cmd if ((sme->sme_flags & SME_DISABLE_REFRESH) == 0 && (sme->sme_flags & SME_POLL_ONLY) == 0) { mutex_enter(&sme->sme_mtx); - (*sme->sme_refresh)(sme, edata); + sysmon_envsys_refresh_sensor(sme, edata); mutex_exit(&sme->sme_mtx); } @@ -602,7 +603,7 @@ sysmon_envsys_sensor_detach(struct sysmo } /* - * remove it and decrement the sensors count. + * remove it, unhook from rnd(4), and decrement the sensors count. */ sme_event_unregister_sensor(sme, edata); TAILQ_REMOVE(&sme->sme_sensors_list, edata, sensors_head); @@ -636,6 +637,7 @@ sysmon_envsys_register(struct sysmon_env sme_event_drv_t *this_evdrv; int nevent; int error = 0; + char rnd_name[sizeof(edata->rnd_src.name)]; KASSERT(sme != NULL); KASSERT(sme->sme_name != NULL); @@ -773,6 +775,17 @@ out: sme_event_drvadd, evdv->evdrv); nevent++; } + /* + * Hook the sensor into rnd(4) entropy pool if requested + */ + TAILQ_FOREACH(edata, &sme->sme_sensors_list, sensors_head) { + if (edata->flags & ENVSYS_FHAS_ENTROPY) { + snprintf(rnd_name, sizeof(rnd_name), "%s-%s", + sme->sme_name, edata->desc); + rnd_attach_source(&edata->rnd_src, rnd_name, + RND_TYPE_ENV, 0); + } + } DPRINTF(("%s: driver '%s' registered (nsens=%d nevent=%d)\n", __func__, sme->sme_name, sme->sme_nsensors, nevent)); } @@ -1003,7 +1016,7 @@ sme_initial_refresh(void *arg) sysmon_envsys_acquire(sme, true); TAILQ_FOREACH(edata, &sme->sme_sensors_list, sensors_head) if ((sme->sme_flags & SME_DISABLE_REFRESH) == 0) - (*sme->sme_refresh)(sme, edata); + sysmon_envsys_refresh_sensor(sme, edata); sysmon_envsys_release(sme, true); mutex_exit(&sme->sme_mtx); } @@ -1356,9 +1369,10 @@ sme_add_sensor_dictionary(struct sysmon_ } /* - * Register new event(s) if any monitoring flag was set. + * Register new event(s) if any monitoring flag was set or if + * the sensor provides entropy for rnd(4). */ - if (edata->flags & ENVSYS_FMONANY) { + if (edata->flags & (ENVSYS_FMONANY | ENVSYS_FHAS_ENTROPY)) { sme_evdrv_t = kmem_zalloc(sizeof(*sme_evdrv_t), KM_SLEEP); sme_evdrv_t->sed_sdict = dict; sme_evdrv_t->sed_edata = edata; @@ -1427,7 +1441,7 @@ sme_get_max_value(struct sysmon_envsys * */ if (refresh && (sme->sme_flags & SME_DISABLE_REFRESH) == 0) { mutex_enter(&sme->sme_mtx); - (*sme->sme_refresh)(sme, edata); + sysmon_envsys_refresh_sensor(sme, edata); mutex_exit(&sme->sme_mtx); } @@ -1504,7 +1518,7 @@ sme_update_dictionary(struct sysmon_envs */ if ((sme->sme_flags & SME_DISABLE_REFRESH) == 0) { mutex_enter(&sme->sme_mtx); - (*sme->sme_refresh)(sme, edata); + sysmon_envsys_refresh_sensor(sme, edata); mutex_exit(&sme->sme_mtx); } @@ -1937,7 +1951,7 @@ sysmon_envsys_foreach_sensor(sysmon_envs if (refresh && (sme->sme_flags & SME_DISABLE_REFRESH) == 0) { mutex_enter(&sme->sme_mtx); - (*sme->sme_refresh)(sme, sensor); + sysmon_envsys_refresh_sensor(sme, sensor); mutex_exit(&sme->sme_mtx); } if (!(*func)(sme, sensor, arg)) @@ -1947,3 +1961,25 @@ sysmon_envsys_foreach_sensor(sysmon_envs } mutex_exit(&sme_global_mtx); } + +/* + * Call the sensor's refresh function, and collect/stir entropy + */ +void +sysmon_envsys_refresh_sensor(struct sysmon_envsys *sme, envsys_data_t *edata) +{ + int32_t old_state; + int32_t old_value; + + if (edata->flags & ENVSYS_FHAS_ENTROPY) { + old_state = edata->state; + old_value = edata->value_cur; + (*sme->sme_refresh)(sme, edata); + if (old_state != ENVSYS_SINVALID && + edata->state != ENVSYS_SINVALID && + old_value != edata->value_cur) + rnd_add_uint32(&edata->rnd_src, edata->value_cur); + } + else + (*sme->sme_refresh)(sme, edata); +} Index: src/sys/dev/sysmon/sysmon_envsys_events.c diff -u src/sys/dev/sysmon/sysmon_envsys_events.c:1.99 src/sys/dev/sysmon/sysmon_envsys_events.c:1.100 --- src/sys/dev/sysmon/sysmon_envsys_events.c:1.99 Sun Jul 15 17:41:39 2012 +++ src/sys/dev/sysmon/sysmon_envsys_events.c Sun Jul 15 18:33:07 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: sysmon_envsys_events.c,v 1.99 2012/07/15 17:41:39 pgoyette Exp $ */ +/* $NetBSD: sysmon_envsys_events.c,v 1.100 2012/07/15 18:33:07 pgoyette Exp $ */ /*- * Copyright (c) 2007, 2008 Juan Romero Pardines. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: sysmon_envsys_events.c,v 1.99 2012/07/15 17:41:39 pgoyette Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sysmon_envsys_events.c,v 1.100 2012/07/15 18:33:07 pgoyette Exp $"); #include <sys/param.h> #include <sys/types.h> @@ -186,6 +186,9 @@ sme_event_register(prop_dictionary_t sdi } break; } + if (crittype == PENVSYS_EVENT_NULL && see != NULL) + return EEXIST; + if (see == NULL) { /* * New event requested - allocate a sysmon_envsys event. @@ -526,6 +529,10 @@ do { \ PENVSYS_EVENT_LIMITS, "hw-range-limits"); + SEE_REGEVENT(ENVSYS_FHAS_ENTROPY, + PENVSYS_EVENT_NULL, + "refresh-event"); + /* * we are done, free memory now. */ @@ -732,7 +739,7 @@ sme_events_worker(struct work *wk, void if ((sme->sme_flags & SME_DISABLE_REFRESH) == 0) { if ((edata->flags & ENVSYS_FNEED_REFRESH) != 0) { /* refresh sensor in device */ - (*sme->sme_refresh)(sme, edata); + sysmon_envsys_refresh_sensor(sme, edata); edata->flags &= ~ENVSYS_FNEED_REFRESH; } } @@ -952,6 +959,8 @@ sme_deliver_event(sme_event_t *see) sysmon_penvsys_event(&pes, PENVSYS_EVENT_LOW_POWER); } break; + case PENVSYS_EVENT_NULL: + break; default: panic("%s: invalid event type %d", __func__, see->see_type); } @@ -1002,7 +1011,7 @@ sme_acadapter_check(void) sensor = true; /* refresh current sensor */ if ((sme->sme_flags & SME_DISABLE_REFRESH) == 0) - (*sme->sme_refresh)(sme, edata); + sysmon_envsys_refresh_sensor(sme, edata); if (edata->value_cur) return false; } Index: src/sys/dev/sysmon/sysmonvar.h diff -u src/sys/dev/sysmon/sysmonvar.h:1.41 src/sys/dev/sysmon/sysmonvar.h:1.42 --- src/sys/dev/sysmon/sysmonvar.h:1.41 Sat Jun 4 13:24:33 2011 +++ src/sys/dev/sysmon/sysmonvar.h Sun Jul 15 18:33:07 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: sysmonvar.h,v 1.41 2011/06/04 13:24:33 pgoyette Exp $ */ +/* $NetBSD: sysmonvar.h,v 1.42 2012/07/15 18:33:07 pgoyette Exp $ */ /*- * Copyright (c) 2000 Zembu Labs, Inc. @@ -44,6 +44,7 @@ #include <sys/callout.h> #include <sys/mutex.h> #include <sys/condvar.h> +#include <sys/rnd.h> struct lwp; struct proc; @@ -86,6 +87,7 @@ struct envsys_data { int32_t private; /* private data for drivers */ sysmon_envsys_lim_t limits; /* thresholds for monitoring */ int upropset; /* userland property set? */ + krndsource_t rnd_src; /* source element for rnd(4) */ char desc[ENVSYS_DESCLEN]; /* sensor description */ }; @@ -106,6 +108,8 @@ typedef struct envsys_data envsys_data_t (ENVSYS_FMONCRITICAL | ENVSYS_FMONLIMITS | ENVSYS_FMONSTCHANGED) #define ENVSYS_FMONNOTSUPP 0x00000800 /* monitoring not supported */ #define ENVSYS_FNEED_REFRESH 0x00001000 /* sensor needs refreshing */ +#define ENVSYS_FHAS_ENTROPY 0x00002000 /* sensor provides entropy + for rnd(4) */ /* * Properties that can be set in upropset (and in the event_limit's @@ -208,6 +212,8 @@ uint32_t sysmon_envsys_get_max_value(boo void sysmon_envsys_sensor_event(struct sysmon_envsys *, envsys_data_t *, int); +void sysmon_envsys_refresh_sensor(struct sysmon_envsys *, envsys_data_t *); + typedef bool (*sysmon_envsys_callback_t)(const struct sysmon_envsys *, const envsys_data_t *, void*);