diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2016-09-03 11:40:55 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2016-09-03 11:40:55 +0000 |
commit | 9b018bffcf13061640bb50b4a51d7882776081a5 (patch) | |
tree | 7b7149f27932deaac9c99651d10609a97b80dcc5 | |
parent | ab7b2803be9990366443429fc6136a0768f59afc (diff) |
Since the initial entropy pool is 8192 bytes, we need three pages to create
the alias mapping when clearing it, since there is no guarantee the pool is
page aligned.
ok deraadt@
-rw-r--r-- | sys/dev/rnd.c | 31 |
1 files changed, 18 insertions, 13 deletions
diff --git a/sys/dev/rnd.c b/sys/dev/rnd.c index 54f050a0553..f18c9c5ae65 100644 --- a/sys/dev/rnd.c +++ b/sys/dev/rnd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rnd.c,v 1.183 2016/09/01 09:05:52 deraadt Exp $ */ +/* $OpenBSD: rnd.c,v 1.184 2016/09/03 11:40:54 kettenis Exp $ */ /* * Copyright (c) 2011 Theo de Raadt. @@ -616,28 +616,33 @@ _rs_clearseed(const void *p, size_t s) { struct kmem_dyn_mode kd_avoidalias; vaddr_t va = trunc_page((vaddr_t)p); - vaddr_t rwa; - paddr_t pa1, pa2; + vsize_t off = (vaddr_t)p - va; + vaddr_t rwva; + paddr_t pa[3]; + int i; + + KASSERT(s <= (nitems(pa) - 1) * PAGE_SIZE); - pmap_extract(pmap_kernel(), va, &pa1); - pmap_extract(pmap_kernel(), va + PAGE_SIZE, &pa2); + for (i = 0; i < nitems(pa); i++, va += PAGE_SIZE) + pmap_extract(pmap_kernel(), va, &pa[i]); memset(&kd_avoidalias, 0, sizeof kd_avoidalias); - kd_avoidalias.kd_prefer = pa1; + kd_avoidalias.kd_prefer = pa[0]; kd_avoidalias.kd_waitok = 1; - rwa = (vaddr_t)km_alloc(2 * PAGE_SIZE, &kv_any, &kp_none, + rwva = (vaddr_t)km_alloc(nitems(pa) * PAGE_SIZE, &kv_any, &kp_none, &kd_avoidalias); - if (!rwa) + if (!rwva) panic("_rs_clearseed"); - pmap_kenter_pa(rwa, pa1, PROT_READ | PROT_WRITE); - pmap_kenter_pa(rwa + PAGE_SIZE, pa2, PROT_READ | PROT_WRITE); + va = rwva; + for (i = 0; i < nitems(pa); i++, va += PAGE_SIZE) + pmap_kenter_pa(va, pa[i], PROT_READ | PROT_WRITE); pmap_update(pmap_kernel()); - explicit_bzero(rwa + ((char *)p - va), s); + explicit_bzero((void *)(rwva + off), s); - pmap_kremove(rwa, 2 * PAGE_SIZE); - km_free((void *)rwa, 2 * PAGE_SIZE, &kv_any, &kp_none); + pmap_kremove(rwva, nitems(pa) * PAGE_SIZE); + km_free((void *)rwva, nitems(pa) * PAGE_SIZE, &kv_any, &kp_none); } static inline void |