/* * RNG driver for VIA RNGs * * Copyright 2005 (c) MontaVista Software, Inc. * * with the majority of the code coming from: * * Hardware driver for the Intel/AMD/VIA Random Number Generators (RNG) * (c) Copyright 2003 Red Hat Inc <[email protected]> * * derived from * * Hardware driver for the AMD 768 Random Number Generator (RNG) * (c) Copyright 2001 Red Hat Inc * * derived from * * Hardware driver for Intel i810 Random Number Generator (RNG) * Copyright 2000,2001 Jeff Garzik <[email protected]> * Copyright 2000,2001 Philipp Rumpf <[email protected]> * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any * warranty of any kind, whether express or implied. */ #include <crypto/padlock.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/hw_random.h> #include <linux/delay.h> #include <asm/cpu_device_id.h> #include <asm/io.h> #include <asm/msr.h> #include <asm/cpufeature.h> #include <asm/fpu/api.h> enum { … }; /* * Investigate using the 'rep' prefix to obtain 32 bits of random data * in one insn. The upside is potentially better performance. The * downside is that the instruction becomes no longer atomic. Due to * this, just like familiar issues with /dev/random itself, the worst * case of a 'rep xstore' could potentially pause a cpu for an * unreasonably long time. In practice, this condition would likely * only occur when the hardware is failing. (or so we hope :)) * * Another possible performance boost may come from simply buffering * until we have 4 bytes, thus returning a u32 at a time, * instead of the current u8-at-a-time. * * Padlock instructions can generate a spurious DNA fault, but the * kernel doesn't use CR0.TS, so this doesn't matter. */ static inline u32 xstore(u32 *addr, u32 edx_in) { … } static int via_rng_data_present(struct hwrng *rng, int wait) { … } static int via_rng_data_read(struct hwrng *rng, u32 *data) { … } static int via_rng_init(struct hwrng *rng) { … } static struct hwrng via_rng = …; static int __init via_rng_mod_init(void) { … } module_init(…) …; static void __exit via_rng_mod_exit(void) { … } module_exit(via_rng_mod_exit); static struct x86_cpu_id __maybe_unused via_rng_cpu_id[] = …; MODULE_DEVICE_TABLE(x86cpu, via_rng_cpu_id); MODULE_DESCRIPTION(…) …; MODULE_LICENSE(…) …;