Re: [PATCH v6 1/3] KVM: selftests: implement random number generation for guest code

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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.



[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux