sys/cpu: Add retry limit to rdrand/rdseed macros
diff --git a/common/lib/rand.c b/common/lib/rand.c
index 8a443277..e17b0cab 100644
--- a/common/lib/rand.c
+++ b/common/lib/rand.c
@@ -26,9 +26,11 @@ static uint32_t hw_entropy(void) {
uint32_t eax, ebx, ecx, edx;
if (cpuid(0x07, 0, &eax, &ebx, &ecx, &edx) && (ebx & (1 << 18))) {
- return rdseed(uint32_t);
+ uint32_t val = rdseed(uint32_t);
+ if (val != 0) return val;
} else if (cpuid(0x01, 0, &eax, &ebx, &ecx, &edx) && (ecx & (1 << 30))) {
- return rdrand(uint32_t);
+ uint32_t val = rdrand(uint32_t);
+ if (val != 0) return val;
}
#elif defined (__aarch64__)
// ARMv8.5-RNG: check ID_AA64ISAR0_EL1 RNDR field (bits [63:60])
diff --git a/common/sys/cpu.h b/common/sys/cpu.h
index 461f35f6..60cc72bd 100644
--- a/common/sys/cpu.h
+++ b/common/sys/cpu.h
@@ -170,24 +170,28 @@ static inline uint64_t tsc_freq_arch(void) {
}
#define rdrand(type) ({ \
- type rdrand__ret; \
- asm volatile ( \
- "1: " \
- "rdrand %0;" \
- "jnc 1b;" \
- : "=r" (rdrand__ret) \
- ); \
+ type rdrand__ret = 0; \
+ for (int rdrand__i = 0; rdrand__i < 10; rdrand__i++) { \
+ bool rdrand__ok; \
+ asm volatile ( \
+ "rdrand %0; setc %1" \
+ : "=r" (rdrand__ret), "=qm" (rdrand__ok) \
+ ); \
+ if (rdrand__ok) break; \
+ } \
rdrand__ret; \
})
#define rdseed(type) ({ \
- type rdseed__ret; \
- asm volatile ( \
- "1: " \
- "rdseed %0;" \
- "jnc 1b;" \
- : "=r" (rdseed__ret) \
- ); \
+ type rdseed__ret = 0; \
+ for (int rdseed__i = 0; rdseed__i < 10; rdseed__i++) { \
+ bool rdseed__ok; \
+ asm volatile ( \
+ "rdseed %0; setc %1" \
+ : "=r" (rdseed__ret), "=qm" (rdseed__ok) \
+ ); \
+ if (rdseed__ok) break; \
+ } \
rdseed__ret; \
})
