summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2020-08-04 11:48:58 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2020-08-04 11:48:58 +0000
commit2ad086ba2375bccdb4ca3f30a0b44b2c2c224ad9 (patch)
tree23bf9fb7def70fbedc1e2086cb4472ebd1acd223 /sys
parent27bbfbdc14249c84adf91a61c6e7f1beea3f8c8b (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.c29
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