summaryrefslogtreecommitdiff
path: root/sys/dev/sysmon
diff options
context:
space:
mode:
authorpgoyette <pgoyette@NetBSD.org>2012-07-15 18:33:07 +0000
committerpgoyette <pgoyette@NetBSD.org>2012-07-15 18:33:07 +0000
commit8f5b32f4c316ade7df5e8f41d5f9fa8ca910c00e (patch)
tree7ff6bc027958a9911509ad9b0192052595aff620 /sys/dev/sysmon
parentfa8a1f450bd3e59952192fdd5830eb74d9fd4f04 (diff)
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.
Diffstat (limited to 'sys/dev/sysmon')
-rw-r--r--sys/dev/sysmon/sysmon_envsys.c56
-rw-r--r--sys/dev/sysmon/sysmon_envsys_events.c17
-rw-r--r--sys/dev/sysmon/sysmonvar.h8
3 files changed, 66 insertions, 15 deletions
diff --git a/sys/dev/sysmon/sysmon_envsys.c b/sys/dev/sysmon/sysmon_envsys.c
index 061f8d298c1..ceda7c56c19 100644
--- a/sys/dev/sysmon/sysmon_envsys.c
+++ b/sys/dev/sysmon/sysmon_envsys.c
@@ -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_envsys.c,v 1.119 2012/07/15 17:41:39 pgoyette
#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, void *data, int flag, struct lwp *l)
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 sysmon_envsys *sme, envsys_data_t *edata)
}
/*
- * 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_envsys *sme)
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_envsys *sme, prop_array_t array,
}
/*
- * 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 *sme,
*/
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_envsys *sme)
*/
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_envsys_callback_t func, void *arg,
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_envsys_callback_t func, void *arg,
}
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);
+}
diff --git a/sys/dev/sysmon/sysmon_envsys_events.c b/sys/dev/sysmon/sysmon_envsys_events.c
index d1ba97ab963..3c9ad71a648 100644
--- a/sys/dev/sysmon/sysmon_envsys_events.c
+++ b/sys/dev/sysmon/sysmon_envsys_events.c
@@ -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 sdict, envsys_data_t *edata,
}
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 *arg)
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;
}
diff --git a/sys/dev/sysmon/sysmonvar.h b/sys/dev/sysmon/sysmonvar.h
index a43e87c8de0..272afca8c38 100644
--- a/sys/dev/sysmon/sysmonvar.h
+++ b/sys/dev/sysmon/sysmonvar.h
@@ -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(bool (*)(const envsys_data_t*), bool);
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*);