diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2020-08-04 11:48:58 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2020-08-04 11:48:58 +0000 |
commit | 2ad086ba2375bccdb4ca3f30a0b44b2c2c224ad9 (patch) | |
tree | 23bf9fb7def70fbedc1e2086cb4472ebd1acd223 /sys | |
parent | 27bbfbdc14249c84adf91a61c6e7f1beea3f8c8b (diff) |
On POWER9 use the "darn" instruction and feed its output as entropy into
the random subsystem.
ok deraadt@
Diffstat (limited to 'sys')
-rw-r--r-- | sys/arch/powerpc64/powerpc64/cpu.c | 29 |
1 files changed, 28 insertions, 1 deletions
diff --git a/sys/arch/powerpc64/powerpc64/cpu.c b/sys/arch/powerpc64/powerpc64/cpu.c index a2333bc1609..d5efb0544a0 100644 --- a/sys/arch/powerpc64/powerpc64/cpu.c +++ b/sys/arch/powerpc64/powerpc64/cpu.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.c,v 1.14 2020/07/22 20:41:26 kettenis Exp $ */ +/* $OpenBSD: cpu.c,v 1.15 2020/08/04 11:48:57 kettenis Exp $ */ /* * Copyright (c) 2020 Mark Kettenis <kettenis@openbsd.org> @@ -20,6 +20,7 @@ #include <sys/atomic.h> #include <sys/device.h> #include <sys/systm.h> +#include <sys/timeout.h> #include <uvm/uvm_extern.h> @@ -60,6 +61,9 @@ uint64_t tb_freq = 512000000; /* POWER8, POWER9 */ struct cpu_info cpu_info[MAXCPUS]; struct cpu_info *cpu_info_primary = &cpu_info[0]; +struct timeout cpu_darn_to; +void cpu_darn(void *); + int cpu_match(struct device *, void *, void *); void cpu_attach(struct device *, struct device *, void *); @@ -171,6 +175,15 @@ cpu_attach(struct device *parent, struct device *dev, void *aux) level++; } + if (CPU_IS_PRIMARY(ci)) { + switch (CPU_VERSION(pvr)) { + case CPU_IBMPOWER9: + timeout_set(&cpu_darn_to, cpu_darn, NULL); + cpu_darn(NULL); + break; + } + } + #ifdef MULTIPROCESSOR if (dev->dv_unit != 0) { int timeout = 10000; @@ -202,6 +215,20 @@ cpu_attach(struct device *parent, struct device *dev, void *aux) tb_freq = OF_getpropint(faa->fa_node, "timebase-frequency", tb_freq); } +void +cpu_darn(void *arg) +{ + uint64_t value; + + __asm volatile ("darn %0, 1" : "=r"(value)); + if (value != UINT64_MAX) { + enqueue_randomness(value); + enqueue_randomness(value >> 32); + } + + timeout_add_msec(&cpu_darn_to, 10); +} + #ifdef MULTIPROCESSOR void |