On 10/28/19 9:32 PM, richard.henderson@xxxxxxxxxx wrote: > +bool arch_get_random_long(unsigned long *v) > +{ > + bool ok; > + > + preempt_disable_notrace(); > + > + ok = this_cpu_has_cap(ARM64_HAS_RNG); > + if (ok) { > + /* > + * Reads of RNDR set PSTATE.NZCV to 0b0000 on success, > + * and set PSTATE.NZCV to 0b0100 otherwise. > + */ > + asm volatile( > + __mrs_s("%0", SYS_RNDR_EL0) "\n" > + " cset %w1, ne\n" > + : "=r"(*v), "=r"(ok) > + : > + : "cc"); > + > + if (unlikely(!ok)) { > + pr_warn_ratelimited("cpu%d: sys_rndr failed\n", > + read_cpuid_id()); > + } > + } > + > + preempt_enable_notrace(); > + return ok; > +} ... > +bool arch_get_random_seed_long(unsigned long *v) > +{ > + preempt_disable_notrace(); > + > + if (this_cpu_has_cap(ARM64_HAS_RNG)) { > + unsigned long ok, val; > + > + /* > + * Reads of RNDRRS set PSTATE.NZCV to 0b0000 on success, > + * and set PSTATE.NZCV to 0b0100 otherwise. > + */ > + asm volatile( > + __mrs_s("%0", SYS_RNDRRS_EL0) "\n" > + " cset %1, ne\n" > + : "=r"(val), "=r"(ok) > + : > + : "cc"); > + > + if (likely(ok)) { > + *v = val; > + preempt_enable_notrace(); > + return true; > + } > + > + pr_warn_ratelimited("cpu%d: sys_rndrrs failed\n", > + read_cpuid_id()); > + } > + > + preempt_enable_notrace(); > + return false; > +} Ho hum. The difference in form between these two functions is unintentional. I had peeked at the assembly for arch_get_random_long, tweaked the structure a bit, and meant to copy the result to arch_get_random_seed_long, but forgot. The first form above produces fewer register spills from gcc8. I'll use that for both for v3, supposing there are further comments to be addressed in review. r~