APPLIED/CMNT: [SRU][B][PATCH 1/1] UBUNTU: SAUCE: Revert "s390/archrandom: simplify back to earlier design and initialize earlier"

Frank Heimes frank.heimes at canonical.com
Fri Oct 28 06:32:17 UTC 2022


Okay, understood - thank you Luke!


On Fri, Oct 28, 2022 at 12:38 AM Luke Nowakowski-Krijger <
luke.nowakowskikrijger at canonical.com> wrote:

> Follow up to this just so we are all aware,
>
> Not going to do the second revert because obviously the first one getting
> reverted means the second apply+revert doesn't make sense. Just going to
> drop "s390/archrandom: prevent CPACF trng invocations in interrupt context"
> from the current cycle stable updates and going to leave breadcrumbs on
> stable updates LP bug that this was dropped.
>
> - Luke
>
> On Thu, Oct 27, 2022 at 2:27 PM Luke Nowakowski-Krijger <
> luke.nowakowskikrijger at canonical.com> wrote:
>
>> I applied this patch but decided to split it up into two reverts that
>> revert both this patch and the "s390/archrandom: prevent CPACF trng
>> invocations in interrupt context" that was a part of the stable updates
>> this cycle. This extra patch was why you needed to do context adjustments.
>> I decided to just go ahead with it so we can get things moving.
>>
>> The source diff is exactly the same, I just decided to split it up into
>> two reverts because one affects the last cycle and what we have in updates,
>> while the other one is in the current cycle. So when respinning I will
>> apply the reverts in the appropriate cycle/place for clarity.
>>
>> Thanks,
>> - Luke
>>
>> On Thu, Oct 27, 2022 at 8:30 AM <frank.heimes at canonical.com> wrote:
>>
>>> BugLink: https://bugs.launchpad.net/bugs/1994601
>>>
>>> From: Frank Heimes <frank.heimes at canonical.com>
>>>
>>> This reverts commit 6edb63a7b6cd57825e47cf6a8600b694a19f0d90.
>>>
>>> In LP#1994601 it's reported that 6edb63a7b6cd breaks IPL (boot) on IBM
>>> zSystems
>>> generation z14 and newer (however, z13 is fine).
>>> Hence reverting this patch to unbreak and re-enable IPL.
>>> Due to slightly changed context over time, the revert needed minor
>>> adjustments.
>>>
>>> Signed-off-by: Frank Heimes <frank.heimes at canonical.com>
>>> ---
>>>  arch/s390/crypto/arch_random.c     | 111 ++++++++++++++++++++++++++++-
>>>  arch/s390/include/asm/archrandom.h |  27 +++----
>>>  arch/s390/kernel/setup.c           |   5 --
>>>  3 files changed, 121 insertions(+), 22 deletions(-)
>>>
>>> diff --git a/arch/s390/crypto/arch_random.c
>>> b/arch/s390/crypto/arch_random.c
>>> index 1f2d40993c4d..4cbb4b6d85a8 100644
>>> --- a/arch/s390/crypto/arch_random.c
>>> +++ b/arch/s390/crypto/arch_random.c
>>> @@ -2,17 +2,126 @@
>>>  /*
>>>   * s390 arch random implementation.
>>>   *
>>> - * Copyright IBM Corp. 2017, 2020
>>> + * Copyright IBM Corp. 2017, 2018
>>>   * Author(s): Harald Freudenberger
>>> + *
>>> + * The s390_arch_random_generate() function may be called from random.c
>>> + * in interrupt context. So this implementation does the best to be very
>>> + * fast. There is a buffer of random data which is asynchronously
>>> checked
>>> + * and filled by a workqueue thread.
>>> + * If there are enough bytes in the buffer the
>>> s390_arch_random_generate()
>>> + * just delivers these bytes. Otherwise false is returned until the
>>> + * worker thread refills the buffer.
>>> + * The worker fills the rng buffer by pulling fresh entropy from the
>>> + * high quality (but slow) true hardware random generator. This entropy
>>> + * is then spread over the buffer with an pseudo random generator PRNG.
>>> + * As the arch_get_random_seed_long() fetches 8 bytes and the calling
>>> + * function add_interrupt_randomness() counts this as 1 bit entropy the
>>> + * distribution needs to make sure there is in fact 1 bit entropy
>>> contained
>>> + * in 8 bytes of the buffer. The current values pull 32 byte entropy
>>> + * and scatter this into a 2048 byte buffer. So 8 byte in the buffer
>>> + * will contain 1 bit of entropy.
>>> + * The worker thread is rescheduled based on the charge level of the
>>> + * buffer but at least with 500 ms delay to avoid too much CPU
>>> consumption.
>>> + * So the max. amount of rng data delivered via arch_get_random_seed is
>>> + * limited to 4k bytes per second.
>>>   */
>>>
>>>  #include <linux/kernel.h>
>>>  #include <linux/atomic.h>
>>>  #include <linux/random.h>
>>> +#include <linux/slab.h>
>>>  #include <linux/static_key.h>
>>> +#include <linux/workqueue.h>
>>>  #include <asm/cpacf.h>
>>>
>>>  DEFINE_STATIC_KEY_FALSE(s390_arch_random_available);
>>>
>>>  atomic64_t s390_arch_random_counter = ATOMIC64_INIT(0);
>>>  EXPORT_SYMBOL(s390_arch_random_counter);
>>> +
>>> +#define ARCH_REFILL_TICKS (HZ/2)
>>> +#define ARCH_PRNG_SEED_SIZE 32
>>> +#define ARCH_RNG_BUF_SIZE 2048
>>> +
>>> +static DEFINE_SPINLOCK(arch_rng_lock);
>>> +static u8 *arch_rng_buf;
>>> +static unsigned int arch_rng_buf_idx;
>>> +
>>> +static void arch_rng_refill_buffer(struct work_struct *);
>>> +static DECLARE_DELAYED_WORK(arch_rng_work, arch_rng_refill_buffer);
>>> +
>>> +bool s390_arch_random_generate(u8 *buf, unsigned int nbytes)
>>> +{
>>> +       /* max hunk is ARCH_RNG_BUF_SIZE */
>>> +       if (nbytes > ARCH_RNG_BUF_SIZE)
>>> +               return false;
>>> +
>>> +       /* lock rng buffer */
>>> +       if (!spin_trylock(&arch_rng_lock))
>>> +               return false;
>>> +
>>> +       /* try to resolve the requested amount of bytes from the buffer
>>> */
>>> +       arch_rng_buf_idx -= nbytes;
>>> +       if (arch_rng_buf_idx < ARCH_RNG_BUF_SIZE) {
>>> +               memcpy(buf, arch_rng_buf + arch_rng_buf_idx, nbytes);
>>> +               atomic64_add(nbytes, &s390_arch_random_counter);
>>> +               spin_unlock(&arch_rng_lock);
>>> +               return true;
>>> +       }
>>> +
>>> +       /* not enough bytes in rng buffer, refill is done asynchronously
>>> */
>>> +       spin_unlock(&arch_rng_lock);
>>> +
>>> +       return false;
>>> +}
>>> +EXPORT_SYMBOL(s390_arch_random_generate);
>>> +
>>> +static void arch_rng_refill_buffer(struct work_struct *unused)
>>> +{
>>> +       unsigned int delay = ARCH_REFILL_TICKS;
>>> +
>>> +       spin_lock(&arch_rng_lock);
>>> +       if (arch_rng_buf_idx > ARCH_RNG_BUF_SIZE) {
>>> +               /* buffer is exhausted and needs refill */
>>> +               u8 seed[ARCH_PRNG_SEED_SIZE];
>>> +               u8 prng_wa[240];
>>> +               /* fetch ARCH_PRNG_SEED_SIZE bytes of entropy */
>>> +               cpacf_trng(NULL, 0, seed, sizeof(seed));
>>> +               /* blow this entropy up to ARCH_RNG_BUF_SIZE with PRNG */
>>> +               memset(prng_wa, 0, sizeof(prng_wa));
>>> +               cpacf_prno(CPACF_PRNO_SHA512_DRNG_SEED,
>>> +                          &prng_wa, NULL, 0, seed, sizeof(seed));
>>> +               cpacf_prno(CPACF_PRNO_SHA512_DRNG_GEN,
>>> +                          &prng_wa, arch_rng_buf, ARCH_RNG_BUF_SIZE,
>>> NULL, 0);
>>> +               arch_rng_buf_idx = ARCH_RNG_BUF_SIZE;
>>> +       }
>>> +       delay += (ARCH_REFILL_TICKS * arch_rng_buf_idx) /
>>> ARCH_RNG_BUF_SIZE;
>>> +       spin_unlock(&arch_rng_lock);
>>> +
>>> +       /* kick next check */
>>> +       queue_delayed_work(system_long_wq, &arch_rng_work, delay);
>>> +}
>>> +
>>> +static int __init s390_arch_random_init(void)
>>> +{
>>> +       /* all the needed PRNO subfunctions available ? */
>>> +       if (cpacf_query_func(CPACF_PRNO, CPACF_PRNO_TRNG) &&
>>> +           cpacf_query_func(CPACF_PRNO, CPACF_PRNO_SHA512_DRNG_GEN)) {
>>> +
>>> +               /* alloc arch random working buffer */
>>> +               arch_rng_buf = kmalloc(ARCH_RNG_BUF_SIZE, GFP_KERNEL);
>>> +               if (!arch_rng_buf)
>>> +                       return -ENOMEM;
>>> +
>>> +               /* kick worker queue job to fill the random buffer */
>>> +               queue_delayed_work(system_long_wq,
>>> +                                  &arch_rng_work, ARCH_REFILL_TICKS);
>>> +
>>> +               /* enable arch random to the outside world */
>>> +               static_branch_enable(&s390_arch_random_available);
>>> +       }
>>> +
>>> +       return 0;
>>> +}
>>> +arch_initcall(s390_arch_random_init);
>>> diff --git a/arch/s390/include/asm/archrandom.h
>>> b/arch/s390/include/asm/archrandom.h
>>> index 4120c428dc37..6ef8857f648f 100644
>>> --- 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, 2022
>>> + * Copyright IBM Corp. 2017
>>>   *
>>>   * Author: Harald Freudenberger <freude at de.ibm.com>
>>>   *
>>> @@ -16,39 +16,34 @@
>>>  #include <linux/static_key.h>
>>>  #include <linux/preempt.h>
>>>  #include <linux/atomic.h>
>>> -#include <asm/cpacf.h>
>>>
>>>  DECLARE_STATIC_KEY_FALSE(s390_arch_random_available);
>>>  extern atomic64_t s390_arch_random_counter;
>>>
>>> -static inline bool __must_check arch_get_random_long(unsigned long *v)
>>> +bool s390_arch_random_generate(u8 *buf, unsigned int nbytes);
>>> +
>>> +static inline bool arch_get_random_long(unsigned long *v)
>>>  {
>>>         return false;
>>>  }
>>>
>>> -static inline bool __must_check arch_get_random_int(unsigned int *v)
>>> +static inline bool arch_get_random_int(unsigned int *v)
>>>  {
>>>         return false;
>>>  }
>>>
>>> -static inline bool __must_check arch_get_random_seed_long(unsigned long
>>> *v)
>>> +static inline bool arch_get_random_seed_long(unsigned long *v)
>>>  {
>>> -       if (static_branch_likely(&s390_arch_random_available) &&
>>> -           in_task()) {
>>> -               cpacf_trng(NULL, 0, (u8 *)v, sizeof(*v));
>>> -               atomic64_add(sizeof(*v), &s390_arch_random_counter);
>>> -               return true;
>>> +       if (static_branch_likely(&s390_arch_random_available)) {
>>> +               return s390_arch_random_generate((u8 *)v, sizeof(*v));
>>>         }
>>>         return false;
>>>  }
>>>
>>> -static inline bool __must_check arch_get_random_seed_int(unsigned int
>>> *v)
>>> +static inline bool arch_get_random_seed_int(unsigned int *v)
>>>  {
>>> -       if (static_branch_likely(&s390_arch_random_available) &&
>>> -           in_task()) {
>>> -               cpacf_trng(NULL, 0, (u8 *)v, sizeof(*v));
>>> -               atomic64_add(sizeof(*v), &s390_arch_random_counter);
>>> -               return true;
>>> +       if (static_branch_likely(&s390_arch_random_available)) {
>>> +               return s390_arch_random_generate((u8 *)v, sizeof(*v));
>>>         }
>>>         return false;
>>>  }
>>> diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
>>> index 933300e2ad38..a59a730c3f11 100644
>>> --- a/arch/s390/kernel/setup.c
>>> +++ b/arch/s390/kernel/setup.c
>>> @@ -861,11 +861,6 @@ 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
>>>  }
>>>
>>>  /*
>>> --
>>> 2.25.1
>>>
>>>
>>> --
>>> kernel-team mailing list
>>> kernel-team at lists.ubuntu.com
>>> https://lists.ubuntu.com/mailman/listinfo/kernel-team
>>>
>>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.ubuntu.com/archives/kernel-team/attachments/20221028/f71dbf4f/attachment-0001.html>


More information about the kernel-team mailing list