This is not the first RNG bug on Zen 2, I recall after I first got mine that some application or other would quit immediately at startup because rdrand always returned -1, i.e. all 1s. It was fixed with a microcode update.
Do we now learn that they fixed "always generate all 1s" with "never generate all 0s"??
EDIT: I've been unable to reproduce the problem on my CPU, FWIW. It's a Ryzen 5 3600.
EDIT2: OK, update, I can reproduce it with rdrand16, rdrand32 is fine but rdrand16 can never generate all 0s. So my CPU does have this problem!
Zen 4 reporting in. I'm unable to reproduce it (7840U).
$ ./a.out | rg '\b\-?\d\b' | sort -n | uniq -c
15281 -2
15192 -1
15273 0
15243 1
15269 2
I used the GCC intrinsic ( _rdrand16_step ), #include <immintrin.h>
short rdrand16() { // gcc -mrdrnd
short ret;
while (1 != _rdrand16_step(&ret)) { }
return ret;
}If I remember correctly, we had a setting in every Linux server we owned to remove CPU as a RNG seeder for the kernel because of those bugs with AMD CPUs.
I.e., we had `random.trust_cpu=off nordrand` in `GRUB_CMDLINE_LINUX`.
Does rdrand32 and then taking the lowest 16 bits of its result yield any zeroes?
Basically I'm wondering if it's a bug in the version of the instruction that writes to a 16-bit reg, or a bug in the underlying RNG
You probably recall https://news.ycombinator.com/item?id=19848953 .
Even if you reproduce the issue, it is not a proof it can't generate a zero - just that it's very unlikely.
To prove it, we'd need to examine the chip and its microcode.
I can reproduce it too with rdrand16 on Zen2.
But it looks like the rdrand16 instruction can produce zeros just fine, it just sets CF=0 erroneously (indicating an error and that the user program should retry).
So keep that in mind when you try to reproduce it too and use some abstraction that could implement retries internally.