summaryrefslogtreecommitdiffstats
path: root/sys/dev/random
diff options
context:
space:
mode:
authorps <ps@FreeBSD.org>2005-12-20 21:41:52 +0000
committerps <ps@FreeBSD.org>2005-12-20 21:41:52 +0000
commit46c91127c85ed485d2195ee8fc2f88f6a23ec918 (patch)
treeb796b749704c3e811aff24db132665fd3285a303 /sys/dev/random
parent0d8b5918f54117f6b47bae8aa0cbbe736749ca9e (diff)
downloadFreeBSD-src-46c91127c85ed485d2195ee8fc2f88f6a23ec918.zip
FreeBSD-src-46c91127c85ed485d2195ee8fc2f88f6a23ec918.tar.gz
Remove GIANT from device random.
Submitted by: ups
Diffstat (limited to 'sys/dev/random')
-rw-r--r--sys/dev/random/nehemiah.c16
-rw-r--r--sys/dev/random/randomdev.c14
-rw-r--r--sys/dev/random/randomdev.h4
-rw-r--r--sys/dev/random/randomdev_soft.c42
-rw-r--r--sys/dev/random/randomdev_soft.h1
-rw-r--r--sys/dev/random/yarrow.c8
6 files changed, 69 insertions, 16 deletions
diff --git a/sys/dev/random/nehemiah.c b/sys/dev/random/nehemiah.c
index 9780dbd..3001b20 100644
--- a/sys/dev/random/nehemiah.c
+++ b/sys/dev/random/nehemiah.c
@@ -41,12 +41,13 @@ __FBSDID("$FreeBSD$");
#define CIPHER_BLOCK_SIZE 16
static void random_nehemiah_init(void);
+static void random_nehemiah_deinit(void);
static int random_nehemiah_read(void *, int);
struct random_systat random_nehemiah = {
.ident = "Hardware, VIA Nehemiah",
.init = random_nehemiah_init,
- .deinit = (random_deinit_func_t *)random_null_func,
+ .deinit = random_nehemiah_deinit,
.read = random_nehemiah_read,
.write = (random_write_func_t *)random_null_func,
.reseed = (random_reseed_func_t *)random_null_func,
@@ -81,6 +82,8 @@ static uint8_t out[RANDOM_BLOCK_SIZE+7] __aligned(16);
static union VIA_ACE_CW acw __aligned(16);
+static struct mtx random_nehemiah_mtx;
+
/* ARGSUSED */
static __inline size_t
VIA_RNG_store(void *buf)
@@ -126,6 +129,14 @@ random_nehemiah_init(void)
{
acw.raw = 0ULL;
acw.field.round_count = 12;
+
+ mtx_init(&random_nehemiah_mtx, "random nehemiah", NULL, MTX_DEF);
+}
+
+void
+random_nehemiah_deinit(void)
+{
+ mtx_destroy(&random_nehemiah_mtx);
}
static int
@@ -135,6 +146,8 @@ random_nehemiah_read(void *buf, int c)
size_t count, ret;
uint8_t *p;
+ mtx_lock(&random_nehemiah_mtx);
+
/* Get a random AES key */
count = 0;
p = key;
@@ -174,5 +187,6 @@ random_nehemiah_read(void *buf, int c)
c = MIN(RANDOM_BLOCK_SIZE, c);
memcpy(buf, out, (size_t)c);
+ mtx_unlock(&random_nehemiah_mtx);
return (c);
}
diff --git a/sys/dev/random/randomdev.c b/sys/dev/random/randomdev.c
index e18be5a..4d2b1bb 100644
--- a/sys/dev/random/randomdev.c
+++ b/sys/dev/random/randomdev.c
@@ -61,7 +61,6 @@ static d_poll_t random_poll;
static struct cdevsw random_cdevsw = {
.d_version = D_VERSION,
- .d_flags = D_NEEDGIANT,
.d_close = random_close,
.d_read = random_read,
.d_write = random_write,
@@ -103,15 +102,8 @@ random_read(struct cdev *dev __unused, struct uio *uio, int flag)
void *random_buf;
/* Blocking logic */
- while (!random_systat.seeded && !error) {
- if (flag & O_NONBLOCK)
- error = EWOULDBLOCK;
- else {
- printf("Entropy device is blocking.\n");
- error = tsleep(&random_systat,
- PUSER | PCATCH, "block", 0);
- }
- }
+ if (!random_systat.seeded)
+ error = (*random_systat.block)(flag);
/* The actual read */
if (!error) {
@@ -181,7 +173,7 @@ random_poll(struct cdev *dev __unused, int events, struct thread *td)
if (random_systat.seeded)
revents = events & (POLLIN | POLLRDNORM);
else
- selrecord(td, &random_systat.rsel);
+ revents = (*random_systat.poll) (events,td);
}
return (revents);
}
diff --git a/sys/dev/random/randomdev.h b/sys/dev/random/randomdev.h
index bf13e1b..2529a82 100644
--- a/sys/dev/random/randomdev.h
+++ b/sys/dev/random/randomdev.h
@@ -32,8 +32,10 @@
typedef void random_init_func_t(void);
typedef void random_deinit_func_t(void);
+typedef int random_block_func_t(int);
typedef int random_read_func_t(void *, int);
typedef void random_write_func_t(void *, int);
+typedef int random_poll_func_t(int, struct thread *);
typedef void random_reseed_func_t(void);
struct random_systat {
@@ -42,8 +44,10 @@ struct random_systat {
int seeded;
random_init_func_t *init;
random_deinit_func_t *deinit;
+ random_block_func_t *block;
random_read_func_t *read;
random_write_func_t *write;
+ random_poll_func_t *poll;
random_reseed_func_t *reseed;
};
diff --git a/sys/dev/random/randomdev_soft.c b/sys/dev/random/randomdev_soft.c
index 4d109a7..cd5e2d9 100644
--- a/sys/dev/random/randomdev_soft.c
+++ b/sys/dev/random/randomdev_soft.c
@@ -59,13 +59,17 @@ static void random_kthread(void *);
static void
random_harvest_internal(u_int64_t, const void *, u_int,
u_int, u_int, enum esource);
+static int random_yarrow_poll(int event,struct thread *td);
+static int random_yarrow_block(int flag);
struct random_systat random_yarrow = {
.ident = "Software, Yarrow",
.init = random_yarrow_init,
.deinit = random_yarrow_deinit,
+ .block = random_yarrow_block,
.read = random_yarrow_read,
.write = random_yarrow_write,
+ .poll = random_yarrow_poll,
.reseed = random_yarrow_reseed,
.seeded = 1,
};
@@ -366,3 +370,41 @@ random_yarrow_unblock(void)
wakeup(&random_systat);
}
}
+
+static int
+random_yarrow_poll(int events, struct thread *td)
+{
+ int revents = 0;
+ mtx_lock(&random_reseed_mtx);
+
+ if (random_systat.seeded)
+ revents = events & (POLLIN | POLLRDNORM);
+ else
+ selrecord(td, &random_systat.rsel);
+
+ mtx_unlock(&random_reseed_mtx);
+ return revents;
+}
+
+static int
+random_yarrow_block(int flag)
+{
+ int error = 0;
+
+ mtx_lock(&random_reseed_mtx);
+
+ /* Blocking logic */
+ while (random_systat.seeded && !error) {
+ if (flag & O_NONBLOCK)
+ error = EWOULDBLOCK;
+ else {
+ printf("Entropy device is blocking.\n");
+ error = msleep(&random_systat,
+ &random_reseed_mtx,
+ PUSER | PCATCH, "block", 0);
+ }
+ }
+ mtx_unlock(&random_reseed_mtx);
+
+ return error;
+}
diff --git a/sys/dev/random/randomdev_soft.h b/sys/dev/random/randomdev_soft.h
index 46bb006..489d45a 100644
--- a/sys/dev/random/randomdev_soft.h
+++ b/sys/dev/random/randomdev_soft.h
@@ -76,6 +76,7 @@ void random_yarrow_init_alg(struct sysctl_ctx_list *, struct sysctl_oid *);
void random_yarrow_deinit_alg(void);
extern struct random_systat random_yarrow;
+extern struct mtx random_reseed_mtx;
/* If this was c++, this would be a template */
#define RANDOM_CHECK_UINT(name, min, max) \
diff --git a/sys/dev/random/yarrow.c b/sys/dev/random/yarrow.c
index 3c5f831..ab10b21 100644
--- a/sys/dev/random/yarrow.c
+++ b/sys/dev/random/yarrow.c
@@ -57,7 +57,7 @@ static void generator_gate(void);
static void reseed(u_int);
/* The reseed thread mutex */
-static struct mtx random_reseed_mtx;
+struct mtx random_reseed_mtx;
/* Process a single stochastic event off the harvest queue */
void
@@ -258,11 +258,11 @@ reseed(u_int fastslow)
/* 7. Dump to seed file */
/* XXX Not done here yet */
- /* Release the reseed mutex */
- mtx_unlock(&random_reseed_mtx);
-
/* Unblock the device if it was blocked due to being unseeded */
random_yarrow_unblock();
+
+ /* Release the reseed mutex */
+ mtx_unlock(&random_reseed_mtx);
}
/* Internal function to return processed entropy from the PRNG */
OpenPOWER on IntegriCloud