5.17.12-rc1 review
Greg Kroah-Hartman
maintainerPATCH 97/111 random: handle latent entropy and command line from random_init()
In reply to Greg Kroah-HartmanFrom: "Jason A. Donenfeld" <[email protected]>
commit 2f14062bb14b0fcfcc21e6dc7d5b5c0d25966164 upstream.
Currently, start_kernel() adds latent entropy and the command line to the entropy bool *after* the RNG has been initialized, deferring when it's actually used by things like stack canaries until the next time the pool is seeded. This surely is not intended.
Rather than splitting up which entropy gets added where and when between start_kernel() and random_init(), just do everything in random_init(), which should eliminate these kinds of bugs in the future.
While we're at it, rename the awkwardly titled "rand_initialize()" to the more standard "random_init()" nomenclature.
--- drivers/char/random.c | 17 ++++++++++------- include/linux/random.h | 16 +++++++--------- init/main.c | 10 +++------- 3 files changed, 20 insertions(+), 23 deletions(-)
drivers/char/random.c +10 -7
@@ -886,12 +886,13 @@ early_param("random.trust_bootloader", p/* * The first collection of entropy occurs at system boot while interrupts -* are still turned off. Here we push in RDSEED, a timestamp, and utsname(). -* Depending on the above configuration knob, RDSEED may be considered -* sufficient for initialization. Note that much earlier setup may already -* have pushed entropy into the input pool by the time we get here. +* are still turned off. Here we push in latent entropy, RDSEED, a timestamp, +* utsname(), and the command line. Depending on the above configuration knob, +* RDSEED may be considered sufficient for initialization. Note that much +* earlier setup may already have pushed entropy into the input pool by the +* time we get here. */ -int __init rand_initialize (void ) +int __init random_init (const char *command_line) {size_t i;ktime_t now =ktime_get_real ();
@@ -913,6 +914,8 @@ int __init rand_initialize(void) }_mix_pool_bytes (&now,sizeof (now));_mix_pool_bytes (utsname (),sizeof (*(utsname ()))); +_mix_pool_bytes (command_line,strlen (command_line)); +add_latent_entropy ();if (crng_ready ())crng_reseed ();
@@ -1591,8 +1594,8 @@ static struct ctl_table random_table[] = };/* -* rand_initialize() is called before sysctl_init(), -* so we cannot call register_sysctl_init() in rand_initialize() +* random_init() is called before sysctl_init(), +* so we cannot call register_sysctl_init() in random_init() */ static int __init random_sysctls_init (void ) {
include/linux/random.h +7 -9
@@ -14,26 +14,24 @@ struct notifier_block;extern void add_device_randomness (const void *,size_t );extern void add_bootloader_randomness (const void *,size_t ); +extern void add_input_randomness(unsigned int type, unsigned int code, + unsigned int value) __latent_entropy; +extern void add_interrupt_randomness(int irq) __latent_entropy; +extern void add_hwgenerator_randomness (const void *buffer,size_t count, +size_t entropy);#if defined(LATENT_ENTROPY_PLUGIN ) && !defined(__CHECKER__)static inline void add_latent_entropy (void ) { -add_device_randomness ((const void *)&latent_entropy, -sizeof (latent_entropy)); +add_device_randomness ((const void *)&latent_entropy,sizeof (latent_entropy)); }#else static inline void add_latent_entropy (void ) {}#endif -extern void add_input_randomness(unsigned int type, unsigned int code, - unsigned int value) __latent_entropy; -extern void add_interrupt_randomness(int irq) __latent_entropy; -extern void add_hwgenerator_randomness (const void *buffer,size_t count, -size_t entropy); -extern void get_random_bytes (void *buf,size_t nbytes);extern int wait_for_random_bytes (void ); -extern int __init rand_initialize (void ); +extern int __init random_init (const char *command_line);extern bool rng_is_initialized (void );extern int register_random_ready_notifier (struct notifier_block *nb);extern int unregister_random_ready_notifier (struct notifier_block *nb);
init/main.c +3 -7
@@ -1040,15 +1040,11 @@ asmlinkage __visible void __init __no_sa/* * For best initial stack canary entropy, prepare it after: * - setup_arch() for any UEFI RNG entropy and boot cmdline access -* - timekeeping_init() for ktime entropy used in rand_initialize() +* - timekeeping_init() for ktime entropy used in random_init() * - time_init() for making random_get_entropy() work on some platforms -* - rand_initialize() to get any arch-specific entropy like RDRAND -* - add_latent_entropy() to get any latent entropy -* - adding command line entropy +* - random_init() to initialize the RNG from from early entropy sources */ -rand_initialize (); -add_latent_entropy (); -add_device_randomness (command_line,strlen (command_line)); +random_init (command_line);boot_init_stack_canary ();perf_event_init ();
Greg Kroah-Hartman
maintainerPATCH 98/111 random: credit architectural init the exact amount
In reply to Greg Kroah-HartmanFrom: "Jason A. Donenfeld" <[email protected]>
commit 12e45a2a6308105469968951e6d563e8f4fea187 upstream.
RDRAND and RDSEED can fail sometimes, which is fine. We currently initialize the RNG with 512 bits of RDRAND/RDSEED. We only need 256 bits of those to succeed in order to initialize the RNG. Instead of the current "all or nothing" approach, actually credit these contributions the amount that is actually contributed.
--- drivers/char/random.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
drivers/char/random.c +6 -6
@@ -894,9 +894,8 @@ early_param("random.trust_bootloader", p*/ int __init random_init (const char *command_line) { -size_t i;ktime_t now =ktime_get_real (); -bool arch_init = true; +unsigned int i, arch_bytes;unsigned long rv;#if defined(LATENT_ENTROPY_PLUGIN )
@@ -904,11 +903,12 @@ int __init random_init(const char *comma_mix_pool_bytes (compiletime_seed,sizeof (compiletime_seed));#endif -for (i =0 ; i <BLAKE2S_BLOCK_SIZE ; i +=sizeof (rv)) { +for (i =0 , arch_bytes =BLAKE2S_BLOCK_SIZE ; + i <BLAKE2S_BLOCK_SIZE ; i +=sizeof (rv)) {if (!arch_get_random_seed_long_early (&rv) && !arch_get_random_long_early (&rv)) { rv =random_get_entropy (); - arch_init = false; + arch_bytes -=sizeof (rv); }_mix_pool_bytes (&rv,sizeof (rv)); }
@@ -919,8 +919,8 @@ int __init random_init(const char *commaif (crng_ready ())crng_reseed (); -else if (arch_init && trust_cpu) -credit_init_bits (BLAKE2S_BLOCK_SIZE *8 ); +else if (trust_cpu) +credit_init_bits (arch_bytes *8 );return 0 ; }
Greg Kroah-Hartman
maintainerPATCH 99/111 random: use static branch for crng_ready()
In reply to Greg Kroah-HartmanFrom: "Jason A. Donenfeld" <[email protected]>
commit f5bda35fba615ace70a656d4700423fa6c9bebee upstream.
Since crng_ready() is only false briefly during initialization and then forever after becomes true, we don't need to evaluate it after, making it a prime candidate for a static branch.
One complication, however, is that it changes state in a particular call to credit_init_bits(), which might be made from atomic context, which means we must kick off a workqueue to change the static key. Further complicating things, credit_init_bits() may be called sufficiently early on in system initialization such that system_wq is NULL.
Fortunately, there exists the nice function execute_in_process_context(), which will immediately execute the function if !in_interrupt(), and otherwise defer it to a workqueue. During early init, before workqueues are available, in_interrupt() is always false, because interrupts haven't even been enabled yet, which means the function in that case executes immediately. Later on, after workqueues are available, in_interrupt() might be true, but in that case, the work is queued in system_wq and all goes well.
--- drivers/char/random.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-)
drivers/char/random.c +12 -4
@@ -77,8 +77,9 @@ static enum {CRNG_EMPTY =0 ,/* Little to no entropy collected */ CRNG_EARLY =1 ,/* At least POOL_EARLY_BITS collected */ CRNG_READY = 2 /* Fully initialized with POOL_READY_BITS collected */ -} crng_init =CRNG_EMPTY ; -#define crng_ready () (likely(crng_init >= CRNG_READY)) +} crng_init__read_mostly =CRNG_EMPTY ; +static DEFINE_STATIC_KEY_FALSE (crng_is_ready); +#define crng_ready () (static_branch_likely(&crng_is_ready) || crng_init >= CRNG_READY)/* Various types of waiters for crng_init->CRNG_READY transition. */ static DECLARE_WAIT_QUEUE_HEAD (crng_init_wait);static struct fasync_struct *fasync;
@@ -108,6 +109,11 @@ bool rng_is_initialized(void) }EXPORT_SYMBOL (rng_is_initialized); +static void crng_set_ready (struct work_struct *work) +{ +static_branch_enable (&crng_is_ready); +} +/* Used by wait_for_random_bytes(), and considered an entropy collector, below. */ static void try_to_generate_entropy (void );
@@ -267,7 +273,7 @@ static void crng_reseed(void) ++next_gen;WRITE_ONCE (base_crng.generation, next_gen);WRITE_ONCE (base_crng.birth, jiffies); -if (!crng_ready ()) +if (!static_branch_likely (&crng_is_ready)) crng_init =CRNG_READY ;spin_unlock_irqrestore (&base_crng.lock, flags);memzero_explicit (key,sizeof (key));
@@ -785,6 +791,7 @@ static void extract_entropy(void *buf, sstatic void credit_init_bits (size_t nbits) { +static struct execute_work set_ready;unsigned int new, orig, add;unsigned long flags;
@@ -800,6 +807,7 @@ static void credit_init_bits(size_t nbitif (orig <POOL_READY_BITS && new >=POOL_READY_BITS ) {crng_reseed ();/* Sets crng_init to CRNG_READY under base_crng.lock. */ +execute_in_process_context (crng_set_ready, &set_ready);process_random_ready_list ();wake_up_interruptible (&crng_init_wait);kill_fasync (&fasync,SIGIO ,POLL_IN );
@@ -1309,7 +1317,7 @@ SYSCALL_DEFINE3(getrandom, char __user *if (count >INT_MAX ) count =INT_MAX ; -if (!(flags &GRND_INSECURE ) && !crng_ready ()) { +if (!crng_ready () && !(flags &GRND_INSECURE )) {int ret;if (flags &GRND_NONBLOCK )
Greg Kroah-Hartman
maintainerPATCH 100/111 random: remove extern from functions in header
In reply to Greg Kroah-HartmanFrom: "Jason A. Donenfeld" <[email protected]>
commit 7782cfeca7d420e8bb707613d4cfb0f7ff29bb3a upstream.
Accoriding to the kernel style guide, having extern on functions in headers is old school and deprecated, and doesn't add anything. So remove them from random.h, and tidy up the file a little bit too.
--- include/linux/random.h | 71 +++++++++++++++++++------------------------------ 1 file changed, 28 insertions(+), 43 deletions(-)
include/linux/random.h +28 -43
@@ -12,13 +12,12 @@struct notifier_block ; -extern void add_device_randomness (const void *,size_t ); -extern void add_bootloader_randomness (const void *,size_t ); -extern void add_input_randomness(unsigned int type, unsigned int code, - unsigned int value) __latent_entropy; -extern void add_interrupt_randomness(int irq) __latent_entropy; -extern void add_hwgenerator_randomness (const void *buffer,size_t count, -size_t entropy); +void add_device_randomness (const void *,size_t ); +void add_bootloader_randomness (const void *,size_t ); +void add_input_randomness(unsigned int type, unsigned int code, + unsigned int value) __latent_entropy; +void add_interrupt_randomness(int irq) __latent_entropy; +void add_hwgenerator_randomness (const void *buffer,size_t count,size_t entropy);#if defined(LATENT_ENTROPY_PLUGIN ) && !defined(__CHECKER__)static inline void add_latent_entropy (void )
@@ -26,21 +25,11 @@ static inline void add_latent_entropy(vo add_device_randomness((const void *)&latent_entropy, sizeof(latent_entropy)); }#else -static inline void add_latent_entropy (void ) {} -#endif - -extern void get_random_bytes (void *buf,size_t nbytes); -extern int wait_for_random_bytes (void ); -extern int __init random_init (const char *command_line); -extern bool rng_is_initialized (void ); -extern int register_random_ready_notifier (struct notifier_block *nb); -extern int unregister_random_ready_notifier (struct notifier_block *nb); -extern size_t __must_check get_random_bytes_arch (void *buf,size_t nbytes); - -#ifndef MODULE -extern const struct file_operations random_fops, urandom_fops; +static inline void add_latent_entropy (void ) { }#endif +void get_random_bytes (void *buf,size_t nbytes); +size_t __must_check get_random_bytes_arch (void *buf,size_t nbytes);u32 get_random_u32 (void );u64 get_random_u64 (void );static inline unsigned int get_random_int (void )
@@ -72,11 +61,17 @@ static inline unsigned long get_random_lstatic inline unsigned long get_random_canary (void ) { -unsigned long val =get_random_long (); - -return val &CANARY_MASK ; +return get_random_long () &CANARY_MASK ; } +unsigned long randomize_page (unsigned long start,unsigned long range); + +int __init random_init (const char *command_line); +bool rng_is_initialized (void ); +int wait_for_random_bytes (void ); +int register_random_ready_notifier (struct notifier_block *nb); +int unregister_random_ready_notifier (struct notifier_block *nb); +/* Calls wait_for_random_bytes() and then calls get_random_bytes(buf, nbytes). * Returns the result of the call to wait_for_random_bytes. */ static inline int get_random_bytes_wait (void *buf,size_t nbytes)
@@ -100,8 +95,6 @@ declare_get_random_var_wait(int)declare_get_random_var_wait (long ) #undef declare_get_random_var -unsigned long randomize_page (unsigned long start,unsigned long range); -/* * This is designed to be standalone for just prandom * users, but for now we include it from <linux/random.h>
@@ -112,22 +105,10 @@ unsigned long randomize_page(unsigned lo#ifdef CONFIG_ARCH_RANDOM # include <asm/archrandom.h> #else -static inline bool __must_check arch_get_random_long (unsigned long *v) -{ -return false; -} -static inline bool __must_check arch_get_random_int (unsigned int *v) -{ -return false; -} -static inline bool __must_check arch_get_random_seed_long (unsigned long *v) -{ -return false; -} -static inline bool __must_check arch_get_random_seed_int (unsigned int *v) -{ -return false; -} +static inline bool __must_check arch_get_random_long (unsigned long *v) {return false; } +static inline bool __must_check arch_get_random_int (unsigned int *v) {return false; } +static inline bool __must_check arch_get_random_seed_long (unsigned long *v) {return false; } +static inline bool __must_check arch_get_random_seed_int (unsigned int *v) {return false; }#endif /*
@@ -151,8 +132,12 @@ static inline bool __init arch_get_rando#endif #ifdef CONFIG_SMP -extern int random_prepare_cpu (unsigned int cpu); -extern int random_online_cpu (unsigned int cpu); +int random_prepare_cpu (unsigned int cpu); +int random_online_cpu (unsigned int cpu); +#endif + +#ifndef MODULE +extern const struct file_operations random_fops, urandom_fops;#endif #endif /* _LINUX_RANDOM_H */
Greg Kroah-Hartman
maintainerPATCH 101/111 random: use proper return types on get_random_{int,long}_wait()
In reply to Greg Kroah-HartmanFrom: "Jason A. Donenfeld" <[email protected]>
commit 7c3a8a1db5e03d02cc0abb3357a84b8b326dfac3 upstream.
Before these were returning signed values, but the API is intended to be used with unsigned values.
--- include/linux/random.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-)
include/linux/random.h +7 -7
@@ -81,18 +81,18 @@ static inline int get_random_bytes_wait(return ret; } -#define declare_get_random_var_wait (var) \ - static inline int get_random_ ## var ## _wait(var *out) { \ +#define declare_get_random_var_wait (name, ret_type) \ + static inline int get_random_ ## name ## _wait(ret_type *out) { \ int ret = wait_for_random_bytes(); \ if (unlikely(ret)) \ return ret; \ - *out = get_random_ ## var(); \ + *out = get_random_ ## name(); \ return 0; \ } -declare_get_random_var_wait(u32) -declare_get_random_var_wait(u64) -declare_get_random_var_wait(int) -declare_get_random_var_wait(long) +declare_get_random_var_wait(u32, u32) +declare_get_random_var_wait(u64, u32) +declare_get_random_var_wait(int, unsigned int) +declare_get_random_var_wait(long, unsigned long)#undef declare_get_random_var/*
Greg Kroah-Hartman
maintainerPATCH 102/111 random: make consistent use of buf and len
In reply to Greg Kroah-HartmanFrom: "Jason A. Donenfeld" <[email protected]>
commit a19402634c435a4eae226df53c141cdbb9922e7b upstream.
The current code was a mix of "nbytes", "count", "size", "buffer", "in", and so forth. Instead, let's clean this up by naming input parameters "buf" (or "ubuf") and "len", so that you always understand that you're reading this variety of function argument.
--- drivers/char/random.c | 193 +++++++++++++++++++++++-------------------------- include/linux/random.h | 10 +- 2 files changed, 99 insertions(+), 104 deletions(-)
drivers/char/random.c +94 -99
@@ -208,7 +208,7 @@ static void _warn_unseeded_randomness(co* * There are a few exported interfaces for use by other drivers: * -* void get_random_bytes(void *buf, size_t nbytes) +* void get_random_bytes(void *buf, size_t len) * u32 get_random_u32() * u64 get_random_u64() * unsigned int get_random_int()
@@ -249,7 +249,7 @@ static DEFINE_PER_CPU(struct crng, crngs };/* Used by crng_reseed() and crng_make_state() to extract a new seed from the input pool. */ -static void extract_entropy (void *buf,size_t nbytes); +static void extract_entropy (void *buf,size_t len);/* This extracts a new crng key from the input pool. */ static void crng_reseed (void )
@@ -403,24 +403,24 @@ static void crng_make_state(u32 chacha_slocal_unlock_irqrestore (&crngs.lock, flags); } -static void _get_random_bytes (void *buf,size_t nbytes) +static void _get_random_bytes (void *buf,size_t len) {u32 chacha_state[CHACHA_STATE_WORDS ];u8 tmp[CHACHA_BLOCK_SIZE ]; -size_t len; +size_t first_block_len; -if (!nbytes) +if (!len)return ; - len =min_t (size_t,32 , nbytes); -crng_make_state (chacha_state, buf, len); - nbytes -= len; - buf += len; + first_block_len =min_t (size_t,32 , len); +crng_make_state (chacha_state, buf, first_block_len); + len -= first_block_len; + buf += first_block_len; -while (nbytes) { -if (nbytes <CHACHA_BLOCK_SIZE ) { +while (len) { +if (len <CHACHA_BLOCK_SIZE ) {chacha20_block (chacha_state, tmp); -memcpy (buf, tmp, nbytes); +memcpy (buf, tmp, len);memzero_explicit (tmp,sizeof (tmp));break ; }
@@ -428,7 +428,7 @@ static void _get_random_bytes(void *buf,chacha20_block (chacha_state, buf);if (unlikely (chacha_state[12 ] ==0 )) ++chacha_state[13 ]; - nbytes -=CHACHA_BLOCK_SIZE ; + len -=CHACHA_BLOCK_SIZE ; buf +=CHACHA_BLOCK_SIZE ; }
@@ -445,20 +445,20 @@ static void _get_random_bytes(void *buf,* wait_for_random_bytes() should be called and return 0 at least once * at any point prior. */ -void get_random_bytes (void *buf,size_t nbytes) +void get_random_bytes (void *buf,size_t len) {warn_unseeded_randomness (); -_get_random_bytes (buf, nbytes); +_get_random_bytes (buf, len); }EXPORT_SYMBOL (get_random_bytes); -static ssize_t get_random_bytes_user (void __user *buf,size_t nbytes) +static ssize_t get_random_bytes_user (void __user *ubuf,size_t len) { -size_t len, left, ret =0 ; +size_t block_len, left, ret =0 ;u32 chacha_state[CHACHA_STATE_WORDS ];u8 output[CHACHA_BLOCK_SIZE ]; -if (!nbytes) +if (!len)return 0 ;/*
@@ -472,8 +472,8 @@ static ssize_t get_random_bytes_user(voi* use chacha_state after, so we can simply return those bytes to * the user directly. */ -if (nbytes <=CHACHA_KEY_SIZE ) { - ret = nbytes -copy_to_user (buf, &chacha_state[4 ], nbytes); +if (len <=CHACHA_KEY_SIZE ) { + ret = len -copy_to_user (ubuf, &chacha_state[4 ], len); goto out_zero_chacha; }
@@ -482,17 +482,17 @@ static ssize_t get_random_bytes_user(voiif (unlikely (chacha_state[12 ] ==0 )) ++chacha_state[13 ]; - len =min_t (size_t, nbytes,CHACHA_BLOCK_SIZE ); - left =copy_to_user (buf, output, len); + block_len =min_t (size_t, len,CHACHA_BLOCK_SIZE ); + left =copy_to_user (ubuf, output, block_len);if (left) { - ret += len - left; + ret += block_len - left;break ; } - buf += len; - ret += len; - nbytes -= len; -if (!nbytes) + ubuf += block_len; + ret += block_len; + len -= block_len; +if (!len)break ;BUILD_BUG_ON (PAGE_SIZE %CHACHA_BLOCK_SIZE !=0 );
@@ -666,24 +666,24 @@ unsigned long randomize_page(unsigned lo* use. Use get_random_bytes() instead. It returns the number of * bytes filled in. */ -size_t __must_check get_random_bytes_arch (void *buf,size_t nbytes) +size_t __must_check get_random_bytes_arch (void *buf,size_t len) { -size_t left = nbytes; +size_t left = len;u8 *p = buf;while (left) {unsigned long v; -size_t chunk =min_t (size_t, left,sizeof (unsigned long )); +size_t block_len =min_t (size_t, left,sizeof (unsigned long ));if (!arch_get_random_long (&v))break ; -memcpy (p, &v, chunk); - p += chunk; - left -= chunk; +memcpy (p, &v, block_len); + p += block_len; + left -= block_len; } -return nbytes - left; +return len - left; }EXPORT_SYMBOL (get_random_bytes_arch);
@@ -694,15 +694,15 @@ EXPORT_SYMBOL(get_random_bytes_arch);* * Callers may add entropy via: * -* static void mix_pool_bytes(const void *in, size_t nbytes) +* static void mix_pool_bytes(const void *buf, size_t len) * * After which, if added entropy should be credited: * -* static void credit_init_bits(size_t nbits) +* static void credit_init_bits(size_t bits) * * Finally, extract entropy via: * -* static void extract_entropy(void *buf, size_t nbytes) +* static void extract_entropy(void *buf, size_t len) * **********************************************************************/
@@ -724,9 +724,9 @@ static struct { .lock = __SPIN_LOCK_UNLOCKED(input_pool.lock), }; -static void _mix_pool_bytes (const void *in,size_t nbytes) +static void _mix_pool_bytes (const void *buf,size_t len) { -blake2s_update (&input_pool.hash, in, nbytes); +blake2s_update (&input_pool.hash, buf, len); }/*
@@ -734,12 +734,12 @@ static void _mix_pool_bytes(const void ** update the initialization bit counter; the caller should call * credit_init_bits if this is appropriate. */ -static void mix_pool_bytes (const void *in,size_t nbytes) +static void mix_pool_bytes (const void *buf,size_t len) {unsigned long flags;spin_lock_irqsave (&input_pool.lock, flags); -_mix_pool_bytes (in, nbytes); +_mix_pool_bytes (buf, len);spin_unlock_irqrestore (&input_pool.lock, flags); }
@@ -747,7 +747,7 @@ static void mix_pool_bytes(const void *i* This is an HKDF-like construction for using the hashed collected entropy * as a PRF key, that's then expanded block-by-block. */ -static void extract_entropy (void *buf,size_t nbytes) +static void extract_entropy (void *buf,size_t len) {unsigned long flags;u8 seed[BLAKE2S_HASH_SIZE ], next_key[BLAKE2S_HASH_SIZE ];
@@ -776,12 +776,12 @@ static void extract_entropy(void *buf, sspin_unlock_irqrestore (&input_pool.lock, flags);memzero_explicit (next_key,sizeof (next_key)); -while (nbytes) { - i =min_t (size_t, nbytes,BLAKE2S_HASH_SIZE ); +while (len) { + i =min_t (size_t, len,BLAKE2S_HASH_SIZE );/* output = HASHPRF(seed, RDSEED || ++counter) */ ++block.counter;blake2s (buf, (u8 *)&block, seed, i,sizeof (block),sizeof (seed)); - nbytes -= i; + len -= i; buf += i; }
@@ -789,16 +789,16 @@ static void extract_entropy(void *buf, smemzero_explicit (&block,sizeof (block)); } -static void credit_init_bits (size_t nbits) +static void credit_init_bits (size_t bits) {static struct execute_work set_ready;unsigned int new, orig, add;unsigned long flags; -if (crng_ready () || !nbits) +if (crng_ready () || !bits)return ; - add =min_t (size_t, nbits,POOL_BITS ); + add =min_t (size_t, bits,POOL_BITS ); do { orig = READ_ONCE(input_pool.init_bits);
@@ -834,13 +834,11 @@ static void credit_init_bits(size_t nbit* The following exported functions are used for pushing entropy into * the above entropy accumulation routines: * -* void add_device_randomness(const void *buf, size_t size); -* void add_hwgenerator_randomness(const void *buffer, size_t count, -* size_t entropy); -* void add_bootloader_randomness(const void *buf, size_t size); +* void add_device_randomness(const void *buf, size_t len); +* void add_hwgenerator_randomness(const void *buf, size_t len, size_t entropy); +* void add_bootloader_randomness(const void *buf, size_t len); * void add_interrupt_randomness(int irq); -* void add_input_randomness(unsigned int type, unsigned int code, -* unsigned int value); +* void add_input_randomness(unsigned int type, unsigned int code, unsigned int value); * void add_disk_randomness(struct gendisk *disk); * * add_device_randomness() adds data to the input pool that
@@ -904,7 +902,7 @@ int __init random_init(const char *comma {ktime_t now =ktime_get_real ();unsigned int i, arch_bytes; -unsigned long rv; +unsigned long entropy;#if defined(LATENT_ENTROPY_PLUGIN ) static const u8 compiletime_seed[BLAKE2S_BLOCK_SIZE] __initconst __latent_entropy;
@@ -912,13 +910,13 @@ int __init random_init(const char *comma#endif for (i =0 , arch_bytes =BLAKE2S_BLOCK_SIZE ; - i <BLAKE2S_BLOCK_SIZE ; i +=sizeof (rv)) { -if (!arch_get_random_seed_long_early (&rv) && - !arch_get_random_long_early (&rv)) { - rv =random_get_entropy (); - arch_bytes -=sizeof (rv); + i <BLAKE2S_BLOCK_SIZE ; i +=sizeof (entropy)) { +if (!arch_get_random_seed_long_early (&entropy) && + !arch_get_random_long_early (&entropy)) { + entropy =random_get_entropy (); + arch_bytes -=sizeof (entropy); } -_mix_pool_bytes (&rv,sizeof (rv)); +_mix_pool_bytes (&entropy,sizeof (entropy)); }_mix_pool_bytes (&now,sizeof (now));_mix_pool_bytes (utsname (),sizeof (*(utsname ())));
@@ -941,14 +939,14 @@ int __init random_init(const char *comma* the entropy pool having similar initial state across largely * identical devices. */ -void add_device_randomness (const void *buf,size_t size) +void add_device_randomness (const void *buf,size_t len) {unsigned long entropy =random_get_entropy ();unsigned long flags;spin_lock_irqsave (&input_pool.lock, flags);_mix_pool_bytes (&entropy,sizeof (entropy)); -_mix_pool_bytes (buf, size); +_mix_pool_bytes (buf, len);spin_unlock_irqrestore (&input_pool.lock, flags); }EXPORT_SYMBOL (add_device_randomness);
@@ -958,10 +956,9 @@ EXPORT_SYMBOL(add_device_randomness);* Those devices may produce endless random bits and will be throttled * when our pool is full. */ -void add_hwgenerator_randomness (const void *buffer,size_t count, -size_t entropy) +void add_hwgenerator_randomness (const void *buf,size_t len,size_t entropy) { -mix_pool_bytes (buffer, count); +mix_pool_bytes (buf, len);credit_init_bits (entropy);/*
@@ -977,11 +974,11 @@ EXPORT_SYMBOL_GPL(add_hwgenerator_random* Handle random seed passed by bootloader, and credit it if * CONFIG_RANDOM_TRUST_BOOTLOADER is set. */ -void add_bootloader_randomness (const void *buf,size_t size) +void add_bootloader_randomness (const void *buf,size_t len) { -mix_pool_bytes (buf, size); +mix_pool_bytes (buf, len);if (trust_bootloader) -credit_init_bits (size *8 ); +credit_init_bits (len *8 ); }EXPORT_SYMBOL_GPL (add_bootloader_randomness);
@@ -1181,8 +1178,7 @@ static void add_timer_randomness(structcredit_init_bits (bits); } -void add_input_randomness (unsigned int type,unsigned int code, -unsigned int value) +void add_input_randomness (unsigned int type,unsigned int code,unsigned int value) {static unsigned char last_value;static struct timer_rand_state input_timer_state = {INITIAL_JIFFIES };
@@ -1301,8 +1297,7 @@ static void try_to_generate_entropy(void* **********************************************************************/ -SYSCALL_DEFINE3(getrandom, char __user *, buf, size_t, count, unsigned int, - flags) +SYSCALL_DEFINE3(getrandom, char __user *, ubuf, size_t, len, unsigned int, flags) {if (flags & ~(GRND_NONBLOCK |GRND_RANDOM |GRND_INSECURE ))return -EINVAL ;
@@ -1314,8 +1309,8 @@ SYSCALL_DEFINE3(getrandom, char __user *if ((flags & (GRND_INSECURE |GRND_RANDOM )) == (GRND_INSECURE |GRND_RANDOM ))return -EINVAL ; -if (count >INT_MAX ) - count =INT_MAX ; +if (len >INT_MAX ) + len =INT_MAX ;if (!crng_ready () && !(flags &GRND_INSECURE )) {int ret;
@@ -1326,7 +1321,7 @@ SYSCALL_DEFINE3(getrandom, char __user *if (unlikely (ret))return ret; } -return get_random_bytes_user (buf, count); +return get_random_bytes_user (ubuf, len); }static __poll_t random_poll (struct file *file,poll_table *wait)
@@ -1335,21 +1330,21 @@ static __poll_t random_poll(struct filereturn crng_ready () ?EPOLLIN |EPOLLRDNORM :EPOLLOUT |EPOLLWRNORM ; } -static int write_pool (const char __user *ubuf,size_t count) +static int write_pool (const char __user *ubuf,size_t len) { -size_t len; +size_t block_len;int ret =0 ;u8 block[BLAKE2S_BLOCK_SIZE ]; -while (count) { - len =min (count,sizeof (block)); -if (copy_from_user (block, ubuf, len)) { +while (len) { + block_len =min (len,sizeof (block)); +if (copy_from_user (block, ubuf, block_len)) { ret = -EFAULT ; goto out; } - count -= len; - ubuf += len; -mix_pool_bytes (block, len); + len -= block_len; + ubuf += block_len; +mix_pool_bytes (block, block_len);cond_resched (); }
@@ -1358,20 +1353,20 @@ out:return ret; } -static ssize_t random_write (struct file *file,const char __user *buffer, -size_t count,loff_t *ppos) +static ssize_t random_write (struct file *file,const char __user *ubuf, +size_t len,loff_t *ppos) {int ret; - ret =write_pool (buffer, count); + ret =write_pool (ubuf, len);if (ret)return ret; -return (ssize_t )count; +return (ssize_t )len; } -static ssize_t urandom_read (struct file *file,char __user *buf,size_t nbytes, -loff_t *ppos) +static ssize_t urandom_read (struct file *file,char __user *ubuf, +size_t len,loff_t *ppos) {static int maxwarn =10 ;
@@ -1381,22 +1376,22 @@ static ssize_t urandom_read(struct fileelse if (ratelimit_disable ||__ratelimit (&urandom_warning)) { --maxwarn;pr_notice ("%s: uninitialized urandom read (%zd bytes read)\n" , - current->comm, nbytes); + current->comm, len); } } -return get_random_bytes_user (buf, nbytes); +return get_random_bytes_user (ubuf, len); } -static ssize_t random_read (struct file *file,char __user *buf,size_t nbytes, -loff_t *ppos) +static ssize_t random_read (struct file *file,char __user *ubuf, +size_t len,loff_t *ppos) {int ret; ret =wait_for_random_bytes ();if (ret !=0 )return ret; -return get_random_bytes_user (buf, nbytes); +return get_random_bytes_user (ubuf, len); }static long random_ioctl (struct file *f,unsigned int cmd,unsigned long arg)
@@ -1521,7 +1516,7 @@ static u8 sysctl_bootid[UUID_SIZE];* UUID. The difference is in whether table->data is NULL; if it is, * then a new UUID is generated and returned to the user. */ -static int proc_do_uuid (struct ctl_table *table,int write,void *buffer, +static int proc_do_uuid (struct ctl_table *table,int write,void *buf,size_t *lenp,loff_t *ppos) {u8 tmp_uuid[UUID_SIZE ], *uuid;
@@ -1548,14 +1543,14 @@ static int proc_do_uuid(struct ctl_table }snprintf (uuid_string,sizeof (uuid_string),"%pU" , uuid); -return proc_dostring (&fake_table,0 , buffer, lenp, ppos); +return proc_dostring (&fake_table,0 , buf, lenp, ppos); }/* The same as proc_dointvec, but writes don't change anything. */ -static int proc_do_rointvec (struct ctl_table *table,int write,void *buffer, +static int proc_do_rointvec (struct ctl_table *table,int write,void *buf,size_t *lenp,loff_t *ppos) { -return write ?0 :proc_dointvec (table,0 , buffer, lenp, ppos); +return write ?0 :proc_dointvec (table,0 , buf, lenp, ppos); }static struct ctl_table random_table[] = {
include/linux/random.h +5 -5
@@ -12,12 +12,12 @@struct notifier_block ; -void add_device_randomness (const void *,size_t ); -void add_bootloader_randomness (const void *,size_t ); +void add_device_randomness (const void *buf,size_t len); +void add_bootloader_randomness (const void *buf,size_t len); void add_input_randomness(unsigned int type, unsigned int code, unsigned int value) __latent_entropy; void add_interrupt_randomness(int irq) __latent_entropy; -void add_hwgenerator_randomness (const void *buffer,size_t count,size_t entropy); +void add_hwgenerator_randomness (const void *buf,size_t len,size_t entropy);#if defined(LATENT_ENTROPY_PLUGIN ) && !defined(__CHECKER__)static inline void add_latent_entropy (void )
@@ -28,8 +28,8 @@ static inline void add_latent_entropy(vostatic inline void add_latent_entropy (void ) { }#endif -void get_random_bytes (void *buf,size_t nbytes); -size_t __must_check get_random_bytes_arch (void *buf,size_t nbytes); +void get_random_bytes (void *buf,size_t len); +size_t __must_check get_random_bytes_arch (void *buf,size_t len);u32 get_random_u32 (void );u64 get_random_u64 (void );static inline unsigned int get_random_int (void )
Greg Kroah-Hartman
maintainerPATCH 103/111 random: move initialization functions out of hot pages
In reply to Greg Kroah-HartmanFrom: "Jason A. Donenfeld" <[email protected]>
commit 560181c27b582557d633ecb608110075433383af upstream.
Much of random.c is devoted to initializing the rng and accounting for when a sufficient amount of entropy has been added. In a perfect world, this would all happen during init, and so we could mark these functions as __init. But in reality, this isn't the case: sometimes the rng only finishes initializing some seconds after system init is finished.
For this reason, at the moment, a whole host of functions that are only used relatively close to system init and then never again are intermixed with functions that are used in hot code all the time. This creates more cache misses than necessary.
In order to pack the hot code closer together, this commit moves the initialization functions that can't be marked as __init into .text.unlikely by way of the __cold attribute.
Of particular note is moving credit_init_bits() into a macro wrapper that inlines the crng_ready() static branch check. This avoids a function call to a nop+ret, and most notably prevents extra entropy arithmetic from being computed in mix_interrupt_randomness().
--- drivers/char/random.c | 40 ++++++++++++++++++---------------------- 1 file changed, 18 insertions(+), 22 deletions(-)
drivers/char/random.c +18 -22
@@ -109,7 +109,7 @@ bool rng_is_initialized(void) }EXPORT_SYMBOL (rng_is_initialized); -static void crng_set_ready (struct work_struct *work) +static void __cold crng_set_ready (struct work_struct *work) {static_branch_enable (&crng_is_ready); }
@@ -148,7 +148,7 @@ EXPORT_SYMBOL(wait_for_random_bytes);* returns: 0 if callback is successfully added * -EALREADY if pool is already initialised (callback not called) */ -int register_random_ready_notifier (struct notifier_block *nb) +int __cold register_random_ready_notifier (struct notifier_block *nb) {unsigned long flags;int ret = -EALREADY ;
@@ -166,7 +166,7 @@ int register_random_ready_notifier(struc/* * Delete a previously registered readiness callback function. */ -int unregister_random_ready_notifier (struct notifier_block *nb) +int __cold unregister_random_ready_notifier (struct notifier_block *nb) {unsigned long flags;int ret;
@@ -177,7 +177,7 @@ int unregister_random_ready_notifier(strreturn ret; } -static void process_random_ready_list (void ) +static void __cold process_random_ready_list (void ) {unsigned long flags;
@@ -187,15 +187,9 @@ static void process_random_ready_list(vo }#define warn_unseeded_randomness () \ - _warn_unseeded_randomness(__func__, (void *)_RET_IP_) - -static void _warn_unseeded_randomness (const char *func_name,void *caller) -{ -if (!IS_ENABLED (CONFIG_WARN_ALL_UNSEEDED_RANDOM ) ||crng_ready ()) -return ; -printk_deferred (KERN_NOTICE "random: %s called from %pS with crng_init=%d\n" , - func_name, caller, crng_init); -} + if (IS_ENABLED(CONFIG_WARN_ALL_UNSEEDED_RANDOM) && !crng_ready()) \ + printk_deferred(KERN_NOTICE "random: %s called from %pS with crng_init=%d\n", \ + __func__, (void *)_RET_IP_, crng_init)/*********************************************************************
@@ -614,7 +608,7 @@ EXPORT_SYMBOL(get_random_u32);* This function is called when the CPU is coming up, with entry * CPUHP_RANDOM_PREPARE, which comes before CPUHP_WORKQUEUE_PREP. */ -int random_prepare_cpu (unsigned int cpu) +int __cold random_prepare_cpu (unsigned int cpu) {/* * When the cpu comes back online, immediately invalidate both
@@ -789,13 +783,15 @@ static void extract_entropy(void *buf, smemzero_explicit (&block,sizeof (block)); } -static void credit_init_bits (size_t bits) +#define credit_init_bits (bits) if (!crng_ready()) _credit_init_bits(bits) + +static void __cold _credit_init_bits (size_t bits) {static struct execute_work set_ready;unsigned int new, orig, add;unsigned long flags; -if (crng_ready () || !bits) +if (!bits)return ; add =min_t (size_t, bits,POOL_BITS );
@@ -974,7 +970,7 @@ EXPORT_SYMBOL_GPL(add_hwgenerator_random* Handle random seed passed by bootloader, and credit it if * CONFIG_RANDOM_TRUST_BOOTLOADER is set. */ -void add_bootloader_randomness (const void *buf,size_t len) +void __cold add_bootloader_randomness (const void *buf,size_t len) {mix_pool_bytes (buf, len);if (trust_bootloader)
@@ -1020,7 +1016,7 @@ static void fast_mix(unsigned long s[4],* This function is called when the CPU has just come online, with * entry CPUHP_AP_RANDOM_ONLINE, just after CPUHP_AP_WORKQUEUE_ONLINE. */ -int random_online_cpu (unsigned int cpu) +int __cold random_online_cpu (unsigned int cpu) {/* * During CPU shutdown and before CPU onlining, add_interrupt_
@@ -1175,7 +1171,7 @@ static void add_timer_randomness(structif (in_hardirq ())this_cpu_ptr (&irq_randomness)->count +=max (1u , bits *64 ) -1 ;else -credit_init_bits (bits); +_credit_init_bits (bits); }void add_input_randomness (unsigned int type,unsigned int code,unsigned int value)
@@ -1203,7 +1199,7 @@ void add_disk_randomness(struct gendisk }EXPORT_SYMBOL_GPL (add_disk_randomness); -void rand_initialize_disk (struct gendisk *disk) +void __cold rand_initialize_disk (struct gendisk *disk) {struct timer_rand_state *state;
@@ -1232,7 +1228,7 @@ void rand_initialize_disk(struct gendisk* * So the re-arming always happens in the entropy loop itself. */ -static void entropy_timer (struct timer_list *t) +static void __cold entropy_timer (struct timer_list *t) {credit_init_bits (1 ); }
@@ -1241,7 +1237,7 @@ static void entropy_timer(struct timer_l* If we have an actual cycle counter, see if we can * generate enough entropy with timing noise */ -static void try_to_generate_entropy (void ) +static void __cold try_to_generate_entropy (void ) {struct {unsigned long entropy;
Greg Kroah-Hartman
maintainerPATCH 104/111 random: move randomize_page() into mm where it belongs
In reply to Greg Kroah-HartmanFrom: "Jason A. Donenfeld" <[email protected]>
commit 5ad7dd882e45d7fe432c32e896e2aaa0b21746ea upstream.
randomize_page is an mm function. It is documented like one. It contains the history of one. It has the naming convention of one. It looks just like another very similar function in mm, randomize_stack_top(). And it has always been maintained and updated by mm people. There is no need for it to be in random.c. In the "which shape does not look like the other ones" test, pointing to randomize_page() is correct.
So move randomize_page() into mm/util.c, right next to the similar randomize_stack_top() function.
This commit contains no actual code changes.
--- drivers/char/random.c | 32 -------------------------------- include/linux/mm.h | 1 + include/linux/random.h | 2 -- mm/util.c | 32 ++++++++++++++++++++++++++++++++ 4 files changed, 33 insertions(+), 34 deletions(-)
drivers/char/random.c +0 -32
@@ -622,38 +622,6 @@ int __cold random_prepare_cpu(unsigned i }#endif -/** -* randomize_page - Generate a random, page aligned address -* @start: The smallest acceptable address the caller will take. -* @range: The size of the area, starting at @start, within which the -* random address must fall. -* -* If @start + @range would overflow, @range is capped. -* -* NOTE: Historical use of randomize_range, which this replaces, presumed that -* @start was already page aligned. We now align it regardless. -* -* Return: A page aligned address within [start, start + range). On error, -* @start is returned. -*/ -unsigned long randomize_page (unsigned long start,unsigned long range) -{ -if (!PAGE_ALIGNED (start)) { - range -=PAGE_ALIGN (start) - start; - start =PAGE_ALIGN (start); - } - -if (start >ULONG_MAX - range) - range =ULONG_MAX - start; - - range >>=PAGE_SHIFT ; - -if (range ==0 ) -return start; - -return start + (get_random_long () % range <<PAGE_SHIFT ); -} -/* * This function will use the architecture-specific hardware random * number generator if it is available. It is not recommended for
include/linux/mm.h +1 -0
@@ -2678,6 +2678,7 @@ extern int install_special_mapping(struc unsigned long flags, struct page **pages);unsigned long randomize_stack_top (unsigned long stack_top); +unsigned long randomize_page (unsigned long start,unsigned long range);extern unsigned long get_unmapped_area (struct file *,unsigned long ,unsigned long ,unsigned long ,unsigned long );
include/linux/random.h +0 -2
@@ -64,8 +64,6 @@ static inline unsigned long get_random_creturn get_random_long () &CANARY_MASK ; } -unsigned long randomize_page (unsigned long start,unsigned long range); -int __init random_init (const char *command_line);bool rng_is_initialized (void );int wait_for_random_bytes (void );
mm/util.c +32 -0
@@ -343,6 +343,38 @@ unsigned long randomize_stack_top(unsign#endif } +/** +* randomize_page - Generate a random, page aligned address +* @start: The smallest acceptable address the caller will take. +* @range: The size of the area, starting at @start, within which the +* random address must fall. +* +* If @start + @range would overflow, @range is capped. +* +* NOTE: Historical use of randomize_range, which this replaces, presumed that +* @start was already page aligned. We now align it regardless. +* +* Return: A page aligned address within [start, start + range). On error, +* @start is returned. +*/ +unsigned long randomize_page (unsigned long start,unsigned long range) +{ +if (!PAGE_ALIGNED (start)) { + range -=PAGE_ALIGN (start) - start; + start =PAGE_ALIGN (start); + } + +if (start >ULONG_MAX - range) + range =ULONG_MAX - start; + + range >>=PAGE_SHIFT ; + +if (range ==0 ) +return start; + +return start + (get_random_long () % range <<PAGE_SHIFT ); +} +#ifdef CONFIG_ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT unsigned long arch_randomize_brk (struct mm_struct *mm) {
Greg Kroah-Hartman
maintainerPATCH 105/111 random: unify batched entropy implementations
In reply to Greg Kroah-HartmanFrom: "Jason A. Donenfeld" <[email protected]>
commit 3092adcef3ffd2ef59634998297ca8358461ebce upstream.
There are currently two separate batched entropy implementations, for u32 and u64, with nearly identical code, with the goal of avoiding unaligned memory accesses and letting the buffers be used more efficiently. Having to maintain these two functions independently is a bit of a hassle though, considering that they always need to be kept in sync.
This commit factors them out into a type-generic macro, so that the expansion produces the same code as before, such that diffing the assembly shows no differences. This will also make it easier in the future to add u16 and u8 batches.
This was initially tested using an always_inline function and letting gcc constant fold the type size in, but the code gen was less efficient, and in general it was more verbose and harder to follow. So this patch goes with the boring macro solution, similar to what's already done for the _wait functions in random.h.
--- drivers/char/random.c | 145 ++++++++++++++++++-------------------------------- 1 file changed, 54 insertions(+), 91 deletions(-)
drivers/char/random.c +54 -91
@@ -509,99 +509,62 @@ out_zero_chacha:* provided by this function is okay, the function wait_for_random_bytes() * should be called and return 0 at least once at any point prior. */ -struct batched_entropy { -union { -/* -* We make this 1.5x a ChaCha block, so that we get the -* remaining 32 bytes from fast key erasure, plus one full -* block from the detached ChaCha state. We can increase -* the size of this later if needed so long as we keep the -* formula of (integer_blocks + 0.5) * CHACHA_BLOCK_SIZE. -*/ -u64 entropy_u64[CHACHA_BLOCK_SIZE *3 / (2 *sizeof (u64))]; -u32 entropy_u32[CHACHA_BLOCK_SIZE *3 / (2 *sizeof (u32))]; - }; -local_lock_t lock; -unsigned long generation; -unsigned int position; -}; +#define DEFINE_BATCHED_ENTROPY (type) \ +struct batch_ ##type { \ +/* \ +* We make this 1.5x a ChaCha block, so that we get the \ +* remaining 32 bytes from fast key erasure, plus one full \ +* block from the detached ChaCha state. We can increase \ +* the size of this later if needed so long as we keep the \ +* formula of (integer_blocks + 0.5) * CHACHA_BLOCK_SIZE. \ +*/ \ +type entropy[CHACHA_BLOCK_SIZE *3 / (2 *sizeof (type))]; \ +local_lock_t lock; \ +unsigned long generation; \ +unsigned int position; \ +}; \ + \ +static DEFINE_PER_CPU(struct batch_ ##type, batched_entropy_ ##type) = { \ + .lock = INIT_LOCAL_LOCK(batched_entropy_ ##type.lock), \ + .position = UINT_MAX \ +}; \ + \ +type get_random_ ##type(void) \ +{ \ + type ret; \ + unsigned long flags; \ + struct batch_ ##type *batch; \ + unsigned long next_gen; \ + \ + warn_unseeded_randomness(); \ + \ + if (!crng_ready()) { \ + _get_random_bytes(&ret, sizeof(ret)); \ + return ret; \ + } \ + \ + local_lock_irqsave(&batched_entropy_ ##type.lock, flags); \ + batch = raw_cpu_ptr(&batched_entropy_##type); \ + \ + next_gen = READ_ONCE(base_crng.generation); \ + if (batch->position >= ARRAY_SIZE(batch->entropy) || \ + next_gen != batch->generation) { \ + _get_random_bytes(batch->entropy, sizeof(batch->entropy)); \ + batch->position = 0; \ + batch->generation = next_gen; \ + } \ + \ + ret = batch->entropy[batch->position]; \ + batch->entropy[batch->position] = 0; \ + ++batch->position; \ + local_unlock_irqrestore(&batched_entropy_ ##type.lock, flags); \ + return ret; \ +} \ +EXPORT_SYMBOL(get_random_ ##type); -static DEFINE_PER_CPU(struct batched_entropy, batched_entropy_u64) = { - .lock =INIT_LOCAL_LOCK (batched_entropy_u64.lock), - .position =UINT_MAX -}; - -u64 get_random_u64 (void ) -{ -u64 ret; -unsigned long flags; -struct batched_entropy *batch; -unsigned long next_gen; - -warn_unseeded_randomness (); - -if (!crng_ready ()) { -_get_random_bytes (&ret,sizeof (ret)); -return ret; - } - -local_lock_irqsave (&batched_entropy_u64.lock, flags); - batch =raw_cpu_ptr (&batched_entropy_u64); - - next_gen =READ_ONCE (base_crng.generation); -if (batch->position >=ARRAY_SIZE (batch->entropy_u64) || - next_gen != batch->generation) { -_get_random_bytes (batch->entropy_u64,sizeof (batch->entropy_u64)); - batch->position =0 ; - batch->generation = next_gen; - } - - ret = batch->entropy_u64[batch->position]; - batch->entropy_u64[batch->position] =0 ; - ++batch->position; -local_unlock_irqrestore (&batched_entropy_u64.lock, flags); -return ret; -} -EXPORT_SYMBOL (get_random_u64); - -static DEFINE_PER_CPU(struct batched_entropy, batched_entropy_u32) = { - .lock =INIT_LOCAL_LOCK (batched_entropy_u32.lock), - .position =UINT_MAX -}; - -u32 get_random_u32 (void ) -{ -u32 ret; -unsigned long flags; -struct batched_entropy *batch; -unsigned long next_gen; - -warn_unseeded_randomness (); - -if (!crng_ready ()) { -_get_random_bytes (&ret,sizeof (ret)); -return ret; - } - -local_lock_irqsave (&batched_entropy_u32.lock, flags); - batch =raw_cpu_ptr (&batched_entropy_u32); - - next_gen =READ_ONCE (base_crng.generation); -if (batch->position >=ARRAY_SIZE (batch->entropy_u32) || - next_gen != batch->generation) { -_get_random_bytes (batch->entropy_u32,sizeof (batch->entropy_u32)); - batch->position =0 ; - batch->generation = next_gen; - } - - ret = batch->entropy_u32[batch->position]; - batch->entropy_u32[batch->position] =0 ; - ++batch->position; -local_unlock_irqrestore (&batched_entropy_u32.lock, flags); -return ret; -} -EXPORT_SYMBOL (get_random_u32); +DEFINE_BATCHED_ENTROPY(u64) +DEFINE_BATCHED_ENTROPY(u32)#ifdef CONFIG_SMP /*
Greg Kroah-Hartman
maintainerPATCH 106/111 random: convert to using fops->read_iter()
In reply to Greg Kroah-HartmanFrom: Jens Axboe <[email protected]>
commit 1b388e7765f2eaa137cf5d92b47ef5925ad83ced upstream.
This is a pre-requisite to wiring up splice() again for the random and urandom drivers. It also allows us to remove the INT_MAX check in getrandom(), because import_single_range() applies capping internally.
[Jason: rewrote get_random_bytes_user() to simplify and also incorporate
additional suggestions from Al.]
--- drivers/char/random.c | 66 ++++++++++++++++++++++---------------------------- 1 file changed, 30 insertions(+), 36 deletions(-)
drivers/char/random.c +30 -36
@@ -52,6 +52,7 @@#include <linux/uuid.h> #include <linux/uaccess.h> #include <linux/siphash.h> +#include <linux/uio.h> #include <crypto/chacha.h> #include <crypto/blake2s.h> #include <asm/processor.h>
@@ -446,13 +447,13 @@ void get_random_bytes(void *buf, size_t }EXPORT_SYMBOL (get_random_bytes); -static ssize_t get_random_bytes_user (void __user *ubuf,size_t len) +static ssize_t get_random_bytes_user (struct iov_iter *iter) { -size_t block_len, left, ret =0 ;u32 chacha_state[CHACHA_STATE_WORDS ]; -u8 output[CHACHA_BLOCK_SIZE ]; +u8 block[CHACHA_BLOCK_SIZE ]; +size_t ret =0 , copied; -if (!len) +if (unlikely (!iov_iter_count (iter)))return 0 ;/*
@@ -466,30 +467,22 @@ static ssize_t get_random_bytes_user(voi* use chacha_state after, so we can simply return those bytes to * the user directly. */ -if (len <=CHACHA_KEY_SIZE ) { - ret = len -copy_to_user (ubuf, &chacha_state[4 ], len); +if (iov_iter_count (iter) <=CHACHA_KEY_SIZE ) { + ret =copy_to_iter (&chacha_state[4 ],CHACHA_KEY_SIZE , iter); goto out_zero_chacha; }for (;;) { -chacha20_block (chacha_state, output); +chacha20_block (chacha_state, block);if (unlikely (chacha_state[12 ] ==0 )) ++chacha_state[13 ]; - block_len =min_t (size_t, len,CHACHA_BLOCK_SIZE ); - left =copy_to_user (ubuf, output, block_len); -if (left) { - ret += block_len - left; -break ; - } - - ubuf += block_len; - ret += block_len; - len -= block_len; -if (!len) + copied =copy_to_iter (block,sizeof (block), iter); + ret += copied; +if (!iov_iter_count (iter) || copied !=sizeof (block))break ; -BUILD_BUG_ON (PAGE_SIZE %CHACHA_BLOCK_SIZE !=0 ); +BUILD_BUG_ON (PAGE_SIZE %sizeof (block) !=0 );if (ret %PAGE_SIZE ==0 ) {if (signal_pending (current))break ;
@@ -497,7 +490,7 @@ static ssize_t get_random_bytes_user(voi } } -memzero_explicit (output,sizeof (output)); +memzero_explicit (block,sizeof (block)); out_zero_chacha:memzero_explicit (chacha_state,sizeof (chacha_state));return ret ? ret : -EFAULT ;
@@ -1226,6 +1219,10 @@ static void __cold try_to_generate_entro SYSCALL_DEFINE3(getrandom, char __user *, ubuf, size_t, len, unsigned int, flags) { +struct iov_iter iter; +struct iovec iov; +int ret; +if (flags & ~(GRND_NONBLOCK |GRND_RANDOM |GRND_INSECURE ))return -EINVAL ;
@@ -1236,19 +1233,18 @@ SYSCALL_DEFINE3(getrandom, char __user *if ((flags & (GRND_INSECURE |GRND_RANDOM )) == (GRND_INSECURE |GRND_RANDOM ))return -EINVAL ; -if (len >INT_MAX ) - len =INT_MAX ; -if (!crng_ready () && !(flags &GRND_INSECURE )) { -int ret; -if (flags &GRND_NONBLOCK )return -EAGAIN ; ret =wait_for_random_bytes ();if (unlikely (ret))return ret; } -return get_random_bytes_user (ubuf, len); + + ret =import_single_range (READ , ubuf, len, &iov, &iter); +if (unlikely (ret)) +return ret; +return get_random_bytes_user (&iter); }static __poll_t random_poll (struct file *file,poll_table *wait)
@@ -1292,8 +1288,7 @@ static ssize_t random_write(struct filereturn (ssize_t )len; } -static ssize_t urandom_read (struct file *file,char __user *ubuf, -size_t len,loff_t *ppos) +static ssize_t urandom_read_iter (struct kiocb *kiocb,struct iov_iter *iter) {static int maxwarn =10 ;
@@ -1302,23 +1297,22 @@ static ssize_t urandom_read(struct file ++urandom_warning.missed; else if (ratelimit_disable || __ratelimit(&urandom_warning)) { --maxwarn; -pr_notice ("%s: uninitialized urandom read (%zd bytes read)\n" , - current->comm, len); +pr_notice ("%s: uninitialized urandom read (%zu bytes read)\n" , + current->comm,iov_iter_count (iter)); } } -return get_random_bytes_user (ubuf, len); +return get_random_bytes_user (iter); } -static ssize_t random_read (struct file *file,char __user *ubuf, -size_t len,loff_t *ppos) +static ssize_t random_read_iter (struct kiocb *kiocb,struct iov_iter *iter) {int ret; ret =wait_for_random_bytes ();if (ret !=0 )return ret; -return get_random_bytes_user (ubuf, len); +return get_random_bytes_user (iter); }static long random_ioctl (struct file *f,unsigned int cmd,unsigned long arg)
@@ -1380,7 +1374,7 @@ static int random_fasync(int fd, struct }const struct file_operations random_fops = { - .read = random_read, + .read_iter = random_read_iter, .write = random_write, .poll = random_poll, .unlocked_ioctl = random_ioctl,
@@ -1390,7 +1384,7 @@ const struct file_operations random_fops };const struct file_operations urandom_fops = { - .read = urandom_read, + .read_iter = urandom_read_iter, .write = random_write, .unlocked_ioctl = random_ioctl, .compat_ioctl = compat_ptr_ioctl,
Greg Kroah-Hartman
maintainerPATCH 107/111 random: convert to using fops->write_iter()
In reply to Greg Kroah-HartmanFrom: Jens Axboe <[email protected]>
commit 22b0a222af4df8ee9bb8e07013ab44da9511b047 upstream.
Now that the read side has been converted to fix a regression with splice, convert the write side as well to have some symmetry in the interface used (and help deprecate ->write()).
[Jason: cleaned up random_ioctl a bit, require full writes in
RNDADDENTROPY since it's crediting entropy, simplify control flow of write_pool(), and incorporate suggestions from Al.]
--- drivers/char/random.c | 67 ++++++++++++++++++++++++++------------------------ 1 file changed, 35 insertions(+), 32 deletions(-)
drivers/char/random.c +35 -32
@@ -1253,39 +1253,31 @@ static __poll_t random_poll(struct filereturn crng_ready () ?EPOLLIN |EPOLLRDNORM :EPOLLOUT |EPOLLWRNORM ; } -static int write_pool (const char __user *ubuf,size_t len) +static ssize_t write_pool (struct iov_iter *iter) { -size_t block_len; -int ret =0 ;u8 block[BLAKE2S_BLOCK_SIZE ]; +ssize_t ret =0 ; +size_t copied; -while (len) { - block_len =min (len,sizeof (block)); -if (copy_from_user (block, ubuf, block_len)) { - ret = -EFAULT ; - goto out; - } - len -= block_len; - ubuf += block_len; -mix_pool_bytes (block, block_len); +if (unlikely (!iov_iter_count (iter))) +return 0 ; + +for (;;) { + copied =copy_from_iter (block,sizeof (block), iter); + ret += copied; +mix_pool_bytes (block, copied); +if (!iov_iter_count (iter) || copied !=sizeof (block)) +break ;cond_resched (); } -out:memzero_explicit (block,sizeof (block)); -return ret; +return ret ? ret : -EFAULT ; } -static ssize_t random_write (struct file *file,const char __user *ubuf, -size_t len,loff_t *ppos) +static ssize_t random_write_iter (struct kiocb *kiocb,struct iov_iter *iter) { -int ret; - - ret =write_pool (ubuf, len); -if (ret) -return ret; - -return (ssize_t )len; +return write_pool (iter); }static ssize_t urandom_read_iter (struct kiocb *kiocb,struct iov_iter *iter)
@@ -1317,9 +1309,8 @@ static ssize_t random_read_iter(struct kstatic long random_ioctl (struct file *f,unsigned int cmd,unsigned long arg) { -int size, ent_count;int __user *p = (int __user *)arg; -int retval; +int ent_count;switch (cmd) {case RNDGETENTCNT :
@@ -1336,20 +1327,32 @@ static long random_ioctl(struct file *f,return -EINVAL ;credit_init_bits (ent_count);return 0 ; -case RNDADDENTROPY : +case RNDADDENTROPY : { +struct iov_iter iter; +struct iovec iov; +ssize_t ret; +int len; +if (!capable (CAP_SYS_ADMIN ))return -EPERM ;if (get_user (ent_count, p++))return -EFAULT ;if (ent_count <0 )return -EINVAL ; -if (get_user (size, p++)) +if (get_user (len, p++)) +return -EFAULT ; + ret =import_single_range (WRITE , p, len, &iov, &iter); +if (unlikely (ret)) +return ret; + ret =write_pool (&iter); +if (unlikely (ret <0 )) +return ret; +/* Since we're crediting, enforce that it was all written into the pool. */ +if (unlikely (ret != len))return -EFAULT ; - retval =write_pool ((const char __user *)p, size); -if (retval <0 ) -return retval;credit_init_bits (ent_count);return 0 ; + }case RNDZAPENTCNT :case RNDCLEARPOOL :/* No longer has any effect. */
@@ -1375,7 +1378,7 @@ static int random_fasync(int fd, structconst struct file_operations random_fops = { .read_iter = random_read_iter, - .write = random_write, + .write_iter = random_write_iter, .poll = random_poll, .unlocked_ioctl = random_ioctl, .compat_ioctl = compat_ptr_ioctl,
@@ -1385,7 +1388,7 @@ const struct file_operations random_fopsconst struct file_operations urandom_fops = { .read_iter = urandom_read_iter, - .write = random_write, + .write_iter = random_write_iter, .unlocked_ioctl = random_ioctl, .compat_ioctl = compat_ptr_ioctl, .fasync = random_fasync,
Greg Kroah-Hartman
maintainerPATCH 108/111 random: wire up fops->splice_{read,write}_iter()
In reply to Greg Kroah-HartmanFrom: Jens Axboe <[email protected]>
commit 79025e727a846be6fd215ae9cdb654368ac3f9a6 upstream.
Now that random/urandom is using {read,write}_iter, we can wire it up to using the generic splice handlers.
[Jason: added the splice_write path. Note that sendfile() and such still
does not work for read, though it does for write, because of a file type restriction in splice_direct_to_actor(), which I'll address separately.]
--- drivers/char/random.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/char/random.c +4 -0
@@ -1384,6 +1384,8 @@ const struct file_operations random_fops .compat_ioctl = compat_ptr_ioctl, .fasync = random_fasync, .llseek = noop_llseek, + .splice_read = generic_file_splice_read, + .splice_write = iter_file_splice_write, };const struct file_operations urandom_fops = {
@@ -1393,6 +1395,8 @@ const struct file_operations urandom_fop .compat_ioctl = compat_ptr_ioctl, .fasync = random_fasync, .llseek = noop_llseek, + .splice_read = generic_file_splice_read, + .splice_write = iter_file_splice_write, };
Greg Kroah-Hartman
maintainerPATCH 109/111 random: check for signals after page of pool writes
In reply to Greg Kroah-HartmanFrom: "Jason A. Donenfeld" <[email protected]>
commit 1ce6c8d68f8ac587f54d0a271ac594d3d51f3efb upstream.
get_random_bytes_user() checks for signals after producing a PAGE_SIZE worth of output, just like /dev/zero does. write_pool() is doing basically the same work (actually, slightly more expensive), and so should stop to check for signals in the same way. Let's also name it write_pool_user() to match get_random_bytes_user(), so this won't be misused in the future.
Before this patch, massive writes to /dev/urandom would tie up the process for an extremely long time and make it unterminatable. After, it can be successfully interrupted. The following test program can be used to see this works as intended:
#include <unistd.h> #include <fcntl.h> #include <signal.h> #include <stdio.h> static unsigned char x[~0U];
static void handle(int) { }
int main(int argc, char *argv[])
{
pid_t pid = getpid(), child;
int fd;
signal(SIGUSR1, handle);
if (!(child = fork())) {
for (;;)
kill(pid, SIGUSR1);
}
fd = open("/dev/urandom", O_WRONLY);
pause();
printf("interrupted after writing %zd bytes\n", write(fd, x, sizeof(x)));
close(fd);
kill(child, SIGTERM);
return 0;
}Result before: "interrupted after writing 2147479552 bytes" Result after: "interrupted after writing 4096 bytes"
--- drivers/char/random.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-)
drivers/char/random.c +10 -4
@@ -1253,7 +1253,7 @@ static __poll_t random_poll(struct filereturn crng_ready () ?EPOLLIN |EPOLLRDNORM :EPOLLOUT |EPOLLWRNORM ; } -static ssize_t write_pool (struct iov_iter *iter) +static ssize_t write_pool_user (struct iov_iter *iter) {u8 block[BLAKE2S_BLOCK_SIZE ];ssize_t ret =0 ;
@@ -1268,7 +1268,13 @@ static ssize_t write_pool(struct iov_itemix_pool_bytes (block, copied);if (!iov_iter_count (iter) || copied !=sizeof (block))break ; -cond_resched (); + +BUILD_BUG_ON (PAGE_SIZE %sizeof (block) !=0 ); +if (ret %PAGE_SIZE ==0 ) { +if (signal_pending (current)) +break ; +cond_resched (); + } }memzero_explicit (block,sizeof (block));
@@ -1277,7 +1283,7 @@ static ssize_t write_pool(struct iov_itestatic ssize_t random_write_iter (struct kiocb *kiocb,struct iov_iter *iter) { -return write_pool (iter); +return write_pool_user (iter); }static ssize_t urandom_read_iter (struct kiocb *kiocb,struct iov_iter *iter)
@@ -1344,7 +1350,7 @@ static long random_ioctl(struct file *f, ret =import_single_range (WRITE , p, len, &iov, &iter);if (unlikely (ret))return ret; - ret =write_pool (&iter); + ret =write_pool_user (&iter);if (unlikely (ret <0 ))return ret;/* Since we're crediting, enforce that it was all written into the pool. */
Greg Kroah-Hartman
maintainerPATCH 110/111 ACPI: sysfs: Fix BERT error region memory mapping
In reply to Greg Kroah-HartmanFrom: Lorenzo Pieralisi <[email protected]>
commit 1bbc21785b7336619fb6a67f1fff5afdaf229acc upstream.
Currently the sysfs interface maps the BERT error region as "memory" (through acpi_os_map_memory()) in order to copy the error records into memory buffers through memory operations (eg memory_read_from_buffer()).
The OS system cannot detect whether the BERT error region is part of system RAM or it is "device memory" (eg BMC memory) and therefore it cannot detect which memory attributes the bus to memory support (and corresponding kernel mapping, unless firmware provides the required information).
The acpi_os_map_memory() arch backend implementation determines the mapping attributes. On arm64, if the BERT error region is not present in the EFI memory map, the error region is mapped as device-nGnRnE; this triggers alignment faults since memcpy unaligned accesses are not allowed in device-nGnRnE regions.
The ACPI sysfs code cannot therefore map by default the BERT error region with memory semantics but should use a safer default.
Change the sysfs code to map the BERT error region as MMIO (through acpi_os_map_iomem()) and use the memcpy_fromio() interface to read the error region into the kernel buffer.
--- drivers/acpi/sysfs.c | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-)
drivers/acpi/sysfs.c +18 -7
@@ -415,19 +415,30 @@ static ssize_t acpi_data_show(struct fil loff_t offset, size_t count) {struct acpi_data_attr *data_attr; -void *base; -ssize_t rc; +void __iomem *base; +ssize_t size; data_attr = container_of(bin_attr, struct acpi_data_attr, attr); + size = data_attr->attr.size; - base =acpi_os_map_memory (data_attr->addr, data_attr->attr.size); +if (offset <0 ) +return -EINVAL ; + +if (offset >= size) +return 0 ; + +if (count > size - offset) + count = size - offset; + + base =acpi_os_map_iomem (data_attr->addr, size);if (!base)return -ENOMEM ; - rc =memory_read_from_buffer (buf, count, &offset, base, - data_attr->attr.size); -acpi_os_unmap_memory (base, data_attr->attr.size); -return rc; +memcpy_fromio (buf, base + offset, count); + +acpi_os_unmap_iomem (base, size); + +return count; }static int acpi_bert_data_init (void *th,struct acpi_data_attr *data_attr)
Greg Kroah-Hartman
maintainerPATCH 111/111 ALSA: ctxfi: Add SB046x PCI ID
In reply to Greg Kroah-HartmanFrom: Edward Matijevic <[email protected]>
commit 1b073ebb174d0c7109b438e0a5eb4495137803ec upstream.
Adds the PCI ID for X-Fi cards sold under the Platnum and XtremeMusic names
Before: snd_ctxfi 0000:05:05.0: chip 20K1 model Unknown (1102:0021) is found
After: snd_ctxfi 0000:05:05.0: chip 20K1 model SB046x (1102:0021) is found
[ This is only about defining the model name string, and the rest is
handled just like before, as a default unknown device. Edward confirmed that the stuff has been working fine -- tiwai ]
--- sound/pci/ctxfi/ctatc.c | 2 ++ sound/pci/ctxfi/cthardware.h | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-)
sound/pci/ctxfi/ctatc.c +2 -0
@@ -36,6 +36,7 @@ | ((IEC958_AES3_CON_FS_48000) << 24))static const struct snd_pci_quirk subsys_20k1_list[] = { +SND_PCI_QUIRK (PCI_VENDOR_ID_CREATIVE ,0x0021 ,"SB046x" ,CTSB046X ),SND_PCI_QUIRK (PCI_VENDOR_ID_CREATIVE ,0x0022 ,"SB055x" ,CTSB055X ),SND_PCI_QUIRK (PCI_VENDOR_ID_CREATIVE ,0x002f ,"SB055x" ,CTSB055X ),SND_PCI_QUIRK (PCI_VENDOR_ID_CREATIVE ,0x0029 ,"SB073x" ,CTSB073X ),
@@ -64,6 +65,7 @@ static const struct snd_pci_quirk subsysstatic const char *ct_subsys_name[NUM_CTCARDS ] = {/* 20k1 models */ + [CTSB046X ] ="SB046x" , [CTSB055X ] ="SB055x" , [CTSB073X ] ="SB073x" , [CTUAA ] ="UAA" ,
sound/pci/ctxfi/cthardware.h +2 -1
@@ -26,8 +26,9 @@ enum CHIPTYP {enum CTCARDS {/* 20k1 models */ +CTSB046X , +CT20K1_MODEL_FIRST =CTSB046X ,CTSB055X , -CT20K1_MODEL_FIRST =CTSB055X ,CTSB073X ,CTUAA ,CT20K1_UNKNOWN ,
Quoted 8 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.17.12 release. There are 111 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Sun, 29 May 2022 08:46:36 +0000. Anything received after that time might be too late.
Build results:
total: 155 pass: 155 fail: 0 Qemu test results: total: 489 pass: 489 fail: 0
Guenter
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.17.12 release. There are 111 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Sun, 29 May 2022 08:46:36 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.17.12-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-5.17.y
and the diffstat can be found below.thanks,
greg k-h
Tested rc1 against the Fedora build system (aarch64, armv7, ppc64le, s390x, x86_64), and boot tested x86_64. No regressions noted.
Quoted 10 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.17.12 release. There are 111 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Sun, 29 May 2022 08:46:36 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.17.12-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-5.17.y
and the diffstat can be found below.thanks,
greg k-h
Results from Linaro’s test farm.
No regressions on arm64, arm, x86_64, and i386.
## Build
* kernel: 5.17.12-rc1
* git: https://gitlab.com/Linaro/lkft/mirrors/stable/linux-stable-rc
* git branch: linux-5.17.y
* git commit: 118948632858649db5531086bb74e586db579fbf
* git describe: v5.17.11-112-g118948632858
* test details:
https://qa-reports.linaro.org/lkft/linux-stable-rc-linux-5.17.y/build/v5.17.11-112-g118948632858/
## Test Regressions (compared to v5.17.11)
No test regressions found.
## Metric Regressions (compared to v5.17.11)
No metric regressions found.
## Test Fixes (compared to v5.17.11)
No test fixes found.
## Metric Fixes (compared to v5.17.11)
No metric fixes found.
## Test result summary
total: 97605, pass: 84424, fail: 334, skip: 12047, xfail: 800
## Build Summary
* arc: 10 total, 10 passed, 0 failed
* arm: 296 total, 293 passed, 3 failed
* arm64: 47 total, 47 passed, 0 failed
* i386: 44 total, 40 passed, 4 failed
* mips: 41 total, 38 passed, 3 failed
* parisc: 14 total, 14 passed, 0 failed
* powerpc: 59 total, 56 passed, 3 failed
* riscv: 27 total, 27 passed, 0 failed
* s390: 26 total, 23 passed, 3 failed
* sh: 26 total, 24 passed, 2 failed
* sparc: 14 total, 14 passed, 0 failed
* x86_64: 47 total, 46 passed, 1 failed
## Test suites summary
* fwts
* igt-gpu-tools
* kselftest-android
* kselftest-arm64
* kselftest-breakpoints
* kselftest-capabilities
* kselftest-cgroup
* kselftest-clone3
* kselftest-core
* kselftest-cpu-hotplug
* kselftest-cpufreq
* kselftest-drivers
* kselftest-efivarfs
* kselftest-filesystems
* kselftest-firmware
* kselftest-fpu
* kselftest-futex
* kselftest-gpio
* kselftest-intel_pstate
* kselftest-ipc
* kselftest-ir
* kselftest-kcmp
* kselftest-kexec
* kselftest-kvm
* kselftest-lib
* kselftest-livepatch
* kselftest-membarrier
* kselftest-memfd
* kselftest-memory-hotplug
* kselftest-mincore
* kselftest-mount
* kselftest-mqueue
* kselftest-net
* kselftest-openat2
* kselftest-pid_namespace
* kselftest-pidfd
* kselftest-proc
* kselftest-pstore
* kselftest-ptrace
* kselftest-rseq
* kselftest-rtc
* kselftest-seccomp
* kselftest-sigaltstack
* kselftest-size
* kselftest-splice
* kselftest-static_keys
* kselftest-sync
* kselftest-sysctl
* kselftest-timens
* kselftest-timers
* kselftest-tmpfs
* kselftest-tpm2
* kselftest-user
* kselftest-vm
* kselftest-x86
* kselftest-zram
* kunit
* kvm-unit-tests
* libgpiod
* libhugetlbfs
* linux-log-parser
* ltp-cap_bounds-tests
* ltp-commands-tests
* ltp-containers-tests
* ltp-controllers-tests
* ltp-cpuhotplug-tests
* ltp-crypto-tests
* ltp-cve-tests
* ltp-cve-tests
* ltp-dio-tests
* ltp-fcntl-locktests-tests
* ltp-filecaps-tests
* ltp-fs-tests
* ltp-fs_bind-tests
* ltp-fs_perms_simple-tests
* ltp-fsx-tests
* ltp-hugetlb-tests
* ltp-io-tests
* ltp-ipc-tests
* ltp-math-tests
* ltp-mm-tests
* ltp-nptl-tests
* ltp-open-posix-tests
* ltp-pty-tests
* ltp-sched-tests
* ltp-securebits-tests
* ltp-syscalls-tests
* ltp-tracing-tests
* network-basic-tests
* packetdrill
* perf
* perf/Zstd-perf.data-compression
* prep-inline
* rcutorture
* ssuite
* v4l2-compliance
* vdso
--
Linaro LKFT
https://lkft.linaro.org
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.17.12 release. There are 111 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Sun, 29 May 2022 08:46:36 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.17.12-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-5.17.y
and the diffstat can be found below.thanks,
greg k-h
Built and booted successfully on RISC-V RV64 (HiFive Unmatched).
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.17.12 release. There are 111 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Sun, 29 May 2022 08:46:36 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 9 lines
https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.17.12-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-5.17.y
and the diffstat can be found below.thanks,
greg k-h
5.17.12-rc1 Successfully Compiled and booted on my Raspberry PI 4b (8g) (bcm2711)
Hi Greg,
Quoted 7 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.17.12 release. There are 111 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Sun, 29 May 2022 08:46:36 +0000. Anything received after that time might be too late.
Build test:
mips (gcc version 11.3.1 20220517): 60 configs -> no failure arm (gcc version 11.3.1 20220517): 100 configs -> no new failure arm64 (gcc version 11.3.1 20220517): 3 configs -> no failure x86_64 (gcc version 11.3.1 20220517): 4 configs -> no failure
Boot test:x86_64: Booted on my test laptop. No regression.
arm64: Booted on rpi4b (4GB model). No regression. [1]
mips: Booted on ci20 board. No regression. [2]
[1]. https://openqa.qa.codethink.co.uk/tests/1223
[2]. https://openqa.qa.codethink.co.uk/tests/1224
--
Regards
Sudip