| From e4f74400308cb8abde5fdc9cad609c2aba32110c Mon Sep 17 00:00:00 2001 |
| From: "Jason A. Donenfeld" <Jason@zx2c4.com> |
| Date: Sat, 11 Jun 2022 00:20:23 +0200 |
| Subject: s390/archrandom: simplify back to earlier design and initialize earlier |
| |
| From: Jason A. Donenfeld <Jason@zx2c4.com> |
| |
| commit e4f74400308cb8abde5fdc9cad609c2aba32110c upstream. |
| |
| s390x appears to present two RNG interfaces: |
| - a "TRNG" that gathers entropy using some hardware function; and |
| - a "DRBG" that takes in a seed and expands it. |
| |
| Previously, the TRNG was wired up to arch_get_random_{long,int}(), but |
| it was observed that this was being called really frequently, resulting |
| in high overhead. So it was changed to be wired up to arch_get_random_ |
| seed_{long,int}(), which was a reasonable decision. Later on, the DRBG |
| was then wired up to arch_get_random_{long,int}(), with a complicated |
| buffer filling thread, to control overhead and rate. |
| |
| Fortunately, none of the performance issues matter much now. The RNG |
| always attempts to use arch_get_random_seed_{long,int}() first, which |
| means a complicated implementation of arch_get_random_{long,int}() isn't |
| really valuable or useful to have around. And it's only used when |
| reseeding, which means it won't hit the high throughput complications |
| that were faced before. |
| |
| So this commit returns to an earlier design of just calling the TRNG in |
| arch_get_random_seed_{long,int}(), and returning false in arch_get_ |
| random_{long,int}(). |
| |
| Part of what makes the simplification possible is that the RNG now seeds |
| itself using the TRNG at bootup. But this only works if the TRNG is |
| detected early in boot, before random_init() is called. So this commit |
| also causes that check to happen in setup_arch(). |
| |
| Cc: stable@vger.kernel.org |
| Cc: Harald Freudenberger <freude@linux.ibm.com> |
| Cc: Ingo Franzki <ifranzki@linux.ibm.com> |
| Cc: Juergen Christ <jchrist@linux.ibm.com> |
| Cc: Heiko Carstens <hca@linux.ibm.com> |
| Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com> |
| Link: https://lore.kernel.org/r/20220610222023.378448-1-Jason@zx2c4.com |
| Reviewed-by: Harald Freudenberger <freude@linux.ibm.com> |
| Acked-by: Heiko Carstens <hca@linux.ibm.com> |
| Signed-off-by: Alexander Gordeev <agordeev@linux.ibm.com> |
| Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| arch/s390/crypto/arch_random.c | 20 +++----------------- |
| arch/s390/include/asm/archrandom.h | 32 ++++++++++++++------------------ |
| arch/s390/kernel/setup.c | 5 +++++ |
| 3 files changed, 22 insertions(+), 35 deletions(-) |
| |
| --- a/arch/s390/crypto/arch_random.c |
| +++ b/arch/s390/crypto/arch_random.c |
| @@ -1,13 +1,9 @@ |
| +// SPDX-License-Identifier: GPL-2.0 |
| /* |
| * s390 arch random implementation. |
| * |
| - * Copyright IBM Corp. 2017 |
| - * Author(s): Harald Freudenberger <freude@de.ibm.com> |
| - * |
| - * This program is free software; you can redistribute it and/or modify |
| - * it under the terms of the GNU General Public License (version 2 only) |
| - * as published by the Free Software Foundation. |
| - * |
| + * Copyright IBM Corp. 2017, 2020 |
| + * Author(s): Harald Freudenberger |
| */ |
| |
| #include <linux/kernel.h> |
| @@ -20,13 +16,3 @@ DEFINE_STATIC_KEY_FALSE(s390_arch_random |
| |
| atomic64_t s390_arch_random_counter = ATOMIC64_INIT(0); |
| EXPORT_SYMBOL(s390_arch_random_counter); |
| - |
| -static int __init s390_arch_random_init(void) |
| -{ |
| - /* check if subfunction CPACF_PRNO_TRNG is available */ |
| - if (cpacf_query_func(CPACF_PRNO, CPACF_PRNO_TRNG)) |
| - static_branch_enable(&s390_arch_random_available); |
| - |
| - return 0; |
| -} |
| -arch_initcall(s390_arch_random_init); |
| --- a/arch/s390/include/asm/archrandom.h |
| +++ b/arch/s390/include/asm/archrandom.h |
| @@ -2,7 +2,7 @@ |
| /* |
| * Kernel interface for the s390 arch_random_* functions |
| * |
| - * Copyright IBM Corp. 2017 |
| + * Copyright IBM Corp. 2017, 2020 |
| * |
| * Author: Harald Freudenberger <freude@de.ibm.com> |
| * |
| @@ -20,38 +20,34 @@ |
| DECLARE_STATIC_KEY_FALSE(s390_arch_random_available); |
| extern atomic64_t s390_arch_random_counter; |
| |
| -static void s390_arch_random_generate(u8 *buf, unsigned int nbytes) |
| +static inline bool __must_check arch_get_random_long(unsigned long *v) |
| { |
| - cpacf_trng(NULL, 0, buf, nbytes); |
| - atomic64_add(nbytes, &s390_arch_random_counter); |
| + return false; |
| } |
| |
| -static inline bool arch_get_random_long(unsigned long *v) |
| +static inline bool __must_check arch_get_random_int(unsigned int *v) |
| { |
| - if (static_branch_likely(&s390_arch_random_available)) { |
| - s390_arch_random_generate((u8 *)v, sizeof(*v)); |
| - return true; |
| - } |
| return false; |
| } |
| |
| -static inline bool arch_get_random_int(unsigned int *v) |
| +static inline bool __must_check arch_get_random_seed_long(unsigned long *v) |
| { |
| if (static_branch_likely(&s390_arch_random_available)) { |
| - s390_arch_random_generate((u8 *)v, sizeof(*v)); |
| + cpacf_trng(NULL, 0, (u8 *)v, sizeof(*v)); |
| + atomic64_add(sizeof(*v), &s390_arch_random_counter); |
| return true; |
| } |
| return false; |
| } |
| |
| -static inline bool arch_get_random_seed_long(unsigned long *v) |
| +static inline bool __must_check arch_get_random_seed_int(unsigned int *v) |
| { |
| - return arch_get_random_long(v); |
| -} |
| - |
| -static inline bool arch_get_random_seed_int(unsigned int *v) |
| -{ |
| - return arch_get_random_int(v); |
| + if (static_branch_likely(&s390_arch_random_available)) { |
| + cpacf_trng(NULL, 0, (u8 *)v, sizeof(*v)); |
| + atomic64_add(sizeof(*v), &s390_arch_random_counter); |
| + return true; |
| + } |
| + return false; |
| } |
| |
| #endif /* CONFIG_ARCH_RANDOM */ |
| --- a/arch/s390/kernel/setup.c |
| +++ b/arch/s390/kernel/setup.c |
| @@ -853,6 +853,11 @@ static void __init setup_randomness(void |
| if (stsi(vmms, 3, 2, 2) == 0 && vmms->count) |
| add_device_randomness(&vmms->vm, sizeof(vmms->vm[0]) * vmms->count); |
| memblock_free((unsigned long) vmms, PAGE_SIZE); |
| + |
| +#ifdef CONFIG_ARCH_RANDOM |
| + if (cpacf_query_func(CPACF_PRNO, CPACF_PRNO_TRNG)) |
| + static_branch_enable(&s390_arch_random_available); |
| +#endif |
| } |
| |
| /* |