Index: init_main.c =================================================================== RCS file: /cvs/src/sys/kern/init_main.c,v retrieving revision 1.237 diff -u -p -r1.237 init_main.c --- init_main.c 12 Apr 2015 11:12:09 -0000 1.237 +++ init_main.c 22 Apr 2015 13:27:23 -0000 @@ -176,6 +176,99 @@ struct emul emul_native = { EMUL_ENABLED | EMUL_NATIVE, }; +#include +#include +#include +#include + +struct kmthing { + TAILQ_ENTRY(kmthing) entry; + void *buf; +}; +TAILQ_HEAD(, kmthing) kmthings; + +struct pool kmpool; +struct timeout kmtick; +struct task kmtask; +chacha_ctx kmctx; + +void kmruntask(void *); +void kmthing(void *); + +void +kminit(void) +{ + u_int8_t key[32]; + + pool_init(&kmpool, sizeof(kmpool), 0, 0, PR_WAITOK, "kmpool", + &pool_allocator_nointr); + pool_setipl(&kmpool, IPL_NONE); + arc4random_buf(key, sizeof(key)); + chacha_keysetup(&kmctx, key, sizeof(key) * 8, 0); + TAILQ_INIT(&kmthings); + task_set(&kmtask, kmthing, NULL); + timeout_set(&kmtick, kmruntask, NULL); + timeout_add(&kmtick, 1); +} + +void +kmruntask(void *null) +{ + task_add(systqmp, &kmtask); + timeout_add(&kmtick, 1); +} + +#define KMSIZE (PAGE_SIZE * 4) + +void +kmthing(void *null) +{ + struct kmem_va_mode kv = kv_any; + struct kmem_dyn_mode kd = KMEM_DYN_INITIALIZER; + struct kmthing *t; + int slowdown; + void *v; + + if (kmpool.pr_nout > 32) { + u_int32_t *ip, *end; + + t = TAILQ_FIRST(&kmthings); + TAILQ_REMOVE(&kmthings, t, entry); + + v = t->buf; + chacha_ivsetup(&kmctx, (void *)&v); + chacha_encrypt_bytes(&kmctx, v, v, KMSIZE); + + end = (u_int32_t *)((u_int8_t *)v + KMSIZE); + for (ip = v; ip < end; ip++) { + if (*ip != 0) + panic("%s: %p", __func__, v); + } + + KERNEL_LOCK(); + km_free(v, KMSIZE, &kv, &kp_dirty); + KERNEL_UNLOCK(); + } else { + t = pool_get(&kmpool, PR_WAITOK); + } + + kd.kd_waitok = 1; + kd.kd_slowdown = &slowdown; + + KERNEL_LOCK(); + v = km_alloc(KMSIZE, &kv, &kp_dirty, &kd); + KERNEL_UNLOCK(); + if (v == NULL) { + pool_put(&kmpool, t); + return; + } + chacha_ivsetup(&kmctx, (void *)&v); + memset(v, 0, KMSIZE); + chacha_encrypt_bytes(&kmctx, v, v, KMSIZE); + + t->buf = v; + TAILQ_INSERT_TAIL(&kmthings, t, entry); +} /* * System startup; initialize the world, create process 0, mount root @@ -553,9 +646,9 @@ main(void *framep) /* * Start the idle pool page garbage collector */ -#if notyet pool_gc_pages(NULL); -#endif + + kminit(); /* * proc0: nothing to do, back to sleep