From 46c91127c85ed485d2195ee8fc2f88f6a23ec918 Mon Sep 17 00:00:00 2001 From: ps Date: Tue, 20 Dec 2005 21:41:52 +0000 Subject: Remove GIANT from device random. Submitted by: ups --- sys/dev/random/nehemiah.c | 16 +++++++++++++++- sys/dev/random/randomdev.c | 14 +++----------- sys/dev/random/randomdev.h | 4 ++++ sys/dev/random/randomdev_soft.c | 42 +++++++++++++++++++++++++++++++++++++++++ sys/dev/random/randomdev_soft.h | 1 + sys/dev/random/yarrow.c | 8 ++++---- 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 */ -- cgit v1.1