:: commit dd2354bae9f32a4a5c45729b5801df74b4ea672a

Mintsuki <mintsuki@protonmail.com> — 2026-04-02 17:04

parents: eac7fd4c65

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; \
 })
 
tab: 248 wrap: offon