diff options
author | Jason A. Donenfeld <Jason@zx2c4.com> | 2022-07-17 12:35:24 +0200 |
---|---|---|
committer | Jason A. Donenfeld <Jason@zx2c4.com> | 2022-07-25 13:26:14 +0200 |
commit | d349ab99eec7ab0f977fc4aac27aa476907acf90 (patch) | |
tree | b98736b45c4f0c00ea2e00e5cefe543bd2ce0759 /arch/um | |
parent | 0b9ba6135d7f18b82f3d8bebb55ded725ba88e0e (diff) | |
download | linux-d349ab99eec7ab0f977fc4aac27aa476907acf90.tar.gz linux-d349ab99eec7ab0f977fc4aac27aa476907acf90.tar.bz2 linux-d349ab99eec7ab0f977fc4aac27aa476907acf90.zip |
random: handle archrandom with multiple longs
The archrandom interface was originally designed for x86, which supplies
RDRAND/RDSEED for receiving random words into registers, resulting in
one function to generate an int and another to generate a long. However,
other architectures don't follow this.
On arm64, the SMCCC TRNG interface can return between one and three
longs. On s390, the CPACF TRNG interface can return arbitrary amounts,
with four longs having the same cost as one. On UML, the os_getrandom()
interface can return arbitrary amounts.
So change the api signature to take a "max_longs" parameter designating
the maximum number of longs requested, and then return the number of
longs generated.
Since callers need to check this return value and loop anyway, each arch
implementation does not bother implementing its own loop to try again to
fill the maximum number of longs. Additionally, all existing callers
pass in a constant max_longs parameter. Taken together, these two things
mean that the codegen doesn't really change much for one-word-at-a-time
platforms, while performance is greatly improved on platforms such as
s390.
Acked-by: Heiko Carstens <hca@linux.ibm.com>
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Acked-by: Mark Rutland <mark.rutland@arm.com>
Acked-by: Michael Ellerman <mpe@ellerman.id.au>
Acked-by: Borislav Petkov <bp@suse.de>
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
Diffstat (limited to 'arch/um')
-rw-r--r-- | arch/um/include/asm/archrandom.h | 21 |
1 files changed, 8 insertions, 13 deletions
diff --git a/arch/um/include/asm/archrandom.h b/arch/um/include/asm/archrandom.h index 2f24cb96391d..24e16c979c51 100644 --- a/arch/um/include/asm/archrandom.h +++ b/arch/um/include/asm/archrandom.h @@ -7,24 +7,19 @@ /* This is from <os.h>, but better not to #include that in a global header here. */ ssize_t os_getrandom(void *buf, size_t len, unsigned int flags); -static inline bool __must_check arch_get_random_long(unsigned long *v) +static inline size_t __must_check arch_get_random_longs(unsigned long *v, size_t max_longs) { - return os_getrandom(v, sizeof(*v), 0) == sizeof(*v); -} + ssize_t ret; -static inline bool __must_check arch_get_random_int(unsigned int *v) -{ - return os_getrandom(v, sizeof(*v), 0) == sizeof(*v); -} - -static inline bool __must_check arch_get_random_seed_long(unsigned long *v) -{ - return false; + ret = os_getrandom(v, max_longs * sizeof(*v), 0); + if (ret < 0) + return 0; + return ret / sizeof(*v); } -static inline bool __must_check arch_get_random_seed_int(unsigned int *v) +static inline size_t __must_check arch_get_random_seed_longs(unsigned long *v, size_t max_longs) { - return false; + return 0; } #endif |