Here is a cpu_rnd_messybits() implementation for arm64.
It reads the virtual counter and xors it with a bit-reversed copy
of itself.
The virtual counter is used by the only timecounter implementation
used on arm64, so I assume it is generally available.
It's a 64-bit counter, which we reduce to 32 bits. Since there is
progressively less entropy in the higher bits of a counter than in
the lower bits, it intuitively makes sense not just to do hi^lo,
but to bit-reverse one half in order to extract maximal entropy,
and on aarch64 bit reversal is a simple instruction.
This patch I have tested!
ok?
Index: arch/arm64/arm64/machdep.c
===================================================================
RCS file: /cvs/src/sys/arch/arm64/arm64/machdep.c,v
retrieving revision 1.52
diff -u -p -r1.52 machdep.c
--- arch/arm64/arm64/machdep.c 31 May 2020 06:23:57 -0000 1.52
+++ arch/arm64/arm64/machdep.c 5 Jun 2020 20:00:20 -0000
@@ -1247,12 +1247,3 @@ dumpregs(struct trapframe *frame)
printf("pc: 0x%016lx\n", frame->tf_elr);
printf("spsr: 0x%016lx\n", frame->tf_spsr);
}
-
-unsigned int
-cpu_rnd_messybits(void)
-{
- struct timespec ts;
-
- nanotime(&ts);
- return (ts.tv_nsec ^ (ts.tv_sec << 20));
-}
Index: arch/arm64/include/cpu.h
===================================================================
RCS file: /cvs/src/sys/arch/arm64/include/cpu.h,v
retrieving revision 1.17
diff -u -p -r1.17 cpu.h
--- arch/arm64/include/cpu.h 31 May 2020 06:23:57 -0000 1.17
+++ arch/arm64/include/cpu.h 5 Jun 2020 20:32:01 -0000
@@ -183,7 +183,16 @@ void cpu_boot_secondary_processors(void)
#define curpcb curcpu()->ci_curpcb
-unsigned int cpu_rnd_messybits(void);
+static inline unsigned int
+cpu_rnd_messybits(void)
+{
+ u_int64_t val, rval;
+
+ __asm volatile("mrs %x0, CNTVCT_EL0; rbit %x1, %x0;"
+ : "=r" (val), "=r" (rval));
+
+ return (val ^ rval);
+}
/*
* Scheduling glue
--
Christian "naddy" Weisgerber [email protected]