On Mon, Sep 12, 2022, Colton Lewis wrote: > diff --git a/tools/testing/selftests/kvm/include/test_util.h b/tools/testing/selftests/kvm/include/test_util.h > index 99e0dcdc923f..2dd286bcf46f 100644 > --- a/tools/testing/selftests/kvm/include/test_util.h > +++ b/tools/testing/selftests/kvm/include/test_util.h > @@ -143,4 +143,6 @@ static inline void *align_ptr_up(void *x, size_t size) > return (void *)align_up((unsigned long)x, size); > } > > +void guest_random(uint32_t *seed); This is a weird and unintuitive API. The in/out param exposes the gory details of the pseudo-RNG to the caller, and makes it cumbersome to use, e.g. to create a 64-bit number or to consume the result in a conditional. It's also not inherently guest-specific, or even KVM specific. We should consider landing this in common selftests code so that others can use it and even expand on it. E.g. in a previous life, I worked with a tool that implemented all sorts of random number magic that provided APIs to get random bools with 1->99 probabilty, random numbers along Guassian curves, bounded numbers, etc. We definitely don't need that level of fanciness right way, but it doesn't require much effort to define the initial APIs such that they won't require modification if/when fancier usage comes along. E.g. to start: --- .c: /* * Random number generator that is usable in any context. Not thread-safe. * This is the Park-Miller LCG using standard constants. */ struct ksft_pseudo_rng { uint32_t state; } void ksft_pseudo_rng_init(struct ksft_pseudo_rng *rng, uint64_t seed) { rng->state = seed; } static uint32_t ksft_pseudo_rng_random(struct ksft_pseudo_rng *rng) { *rng->state = (uint64_t)*rng->state * 48271 % ((1u << 31) - 1); return *rng->state; } uint32_t random_u32(struct ksft_pseudo_rng *rng) { return ksft_pseudo_rng_random(rng); } uint64_t random_u64(struct ksft_pseudo_rng *rng) { return (uint64_t)random_u32(rng) << 32 | random_u32(rng); } .h struct ksft_pseudo_rng; void ksft_pseudo_rng_init(struct ksft_pseudo_rng *rng, uint64_t seed); uint32_t random_u32(struct ksft_pseudo_rng *rng); uint64_t random_u64(struct ksft_pseudo_rng *rng); --- And then if/when want to add fancier stuff, say bounded 32-bit values, we can do so without having to update existing users.