public inbox for gentoo-commits@lists.gentoo.org
 help / color / mirror / Atom feed
From: "Mike Pagano" <mpagano@gentoo.org>
To: gentoo-commits@lists.gentoo.org
Subject: [gentoo-commits] proj/linux-patches:4.9 commit in: /
Date: Sat, 25 Jun 2022 10:24:15 +0000 (UTC)	[thread overview]
Message-ID: <1656152642.bc9a85789c4e42d0ea50133da958b1a29e193493.mpagano@gentoo> (raw)

commit:     bc9a85789c4e42d0ea50133da958b1a29e193493
Author:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Sat Jun 25 10:24:02 2022 +0000
Commit:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Sat Jun 25 10:24:02 2022 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=bc9a8578

Linux patch 4.9.320

Signed-off-by: Mike Pagano <mpagano <AT> gentoo.org>

 0000_README              |    4 +
 1319_linux-4.9.320.patch | 7856 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 7860 insertions(+)

diff --git a/0000_README b/0000_README
index d2a5bcdd..1aa08f52 100644
--- a/0000_README
+++ b/0000_README
@@ -1319,6 +1319,10 @@ Patch:  1318_linux-4.9.319.patch
 From:   http://www.kernel.org
 Desc:   Linux 4.9.319
 
+Patch:  1319_linux-4.9.320.patch
+From:   http://www.kernel.org
+Desc:   Linux 4.9.320
+
 Patch:  1500_XATTR_USER_PREFIX.patch
 From:   https://bugs.gentoo.org/show_bug.cgi?id=470644
 Desc:   Support for namespace user.pax.* on tmpfs.

diff --git a/1319_linux-4.9.320.patch b/1319_linux-4.9.320.patch
new file mode 100644
index 00000000..75e23994
--- /dev/null
+++ b/1319_linux-4.9.320.patch
@@ -0,0 +1,7856 @@
+diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
+index 97c0ff0787eaf..92a9a3282c5b6 100644
+--- a/Documentation/kernel-parameters.txt
++++ b/Documentation/kernel-parameters.txt
+@@ -3577,6 +3577,18 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
+ 	ramdisk_size=	[RAM] Sizes of RAM disks in kilobytes
+ 			See Documentation/blockdev/ramdisk.txt.
+ 
++	random.trust_cpu={on,off}
++			[KNL] Enable or disable trusting the use of the
++			CPU's random number generator (if available) to
++			fully seed the kernel's CRNG. Default is controlled
++			by CONFIG_RANDOM_TRUST_CPU.
++
++	random.trust_bootloader={on,off}
++			[KNL] Enable or disable trusting the use of a
++			seed passed by the bootloader (if available) to
++			fully seed the kernel's CRNG. Default is controlled
++			by CONFIG_RANDOM_TRUST_BOOTLOADER.
++
+ 	rcu_nocbs=	[KNL]
+ 			The argument is a cpu list, as described above.
+ 
+diff --git a/Documentation/sysctl/kernel.txt b/Documentation/sysctl/kernel.txt
+index 30ba179392d81..79608693ef0b0 100644
+--- a/Documentation/sysctl/kernel.txt
++++ b/Documentation/sysctl/kernel.txt
+@@ -777,9 +777,40 @@ The kernel command line parameter printk.devkmsg= overrides this and is
+ a one-time setting until next reboot: once set, it cannot be changed by
+ this sysctl interface anymore.
+ 
+-==============================================================
++pty
++===
++
++See Documentation/filesystems/devpts.rst.
++
++
++random
++======
++
++This is a directory, with the following entries:
++
++* ``boot_id``: a UUID generated the first time this is retrieved, and
++  unvarying after that;
++
++* ``uuid``: a UUID generated every time this is retrieved (this can
++  thus be used to generate UUIDs at will);
++
++* ``entropy_avail``: the pool's entropy count, in bits;
++
++* ``poolsize``: the entropy pool size, in bits;
++
++* ``urandom_min_reseed_secs``: obsolete (used to determine the minimum
++  number of seconds between urandom pool reseeding). This file is
++  writable for compatibility purposes, but writing to it has no effect
++  on any RNG behavior;
++
++* ``write_wakeup_threshold``: when the entropy count drops below this
++  (as a number of bits), processes waiting to write to ``/dev/random``
++  are woken up. This file is writable for compatibility purposes, but
++  writing to it has no effect on any RNG behavior.
++
+ 
+-randomize_va_space:
++randomize_va_space
++==================
+ 
+ This option can be used to select the type of process address
+ space randomization that is used in the system, for architectures
+diff --git a/MAINTAINERS b/MAINTAINERS
+index fcaab221553e0..afafd0fa18a9f 100644
+--- a/MAINTAINERS
++++ b/MAINTAINERS
+@@ -10068,6 +10068,7 @@ F:	drivers/block/brd.c
+ 
+ RANDOM NUMBER DRIVER
+ M:	"Theodore Ts'o" <tytso@mit.edu>
++M:	Jason A. Donenfeld <Jason@zx2c4.com>
+ S:	Maintained
+ F:	drivers/char/random.c
+ 
+diff --git a/Makefile b/Makefile
+index bf4a7b0fe8e74..04cefc7d5b47f 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,6 +1,6 @@
+ VERSION = 4
+ PATCHLEVEL = 9
+-SUBLEVEL = 319
++SUBLEVEL = 320
+ EXTRAVERSION =
+ NAME = Roaring Lionus
+ 
+diff --git a/arch/alpha/include/asm/timex.h b/arch/alpha/include/asm/timex.h
+index afa0c45e3e987..c3ed97c790868 100644
+--- a/arch/alpha/include/asm/timex.h
++++ b/arch/alpha/include/asm/timex.h
+@@ -27,5 +27,6 @@ static inline cycles_t get_cycles (void)
+ 	__asm__ __volatile__ ("rpcc %0" : "=r"(ret));
+ 	return ret;
+ }
++#define get_cycles get_cycles
+ 
+ #endif
+diff --git a/arch/arm/include/asm/timex.h b/arch/arm/include/asm/timex.h
+index f6fcc67ef06ef..c06d38f0df8ec 100644
+--- a/arch/arm/include/asm/timex.h
++++ b/arch/arm/include/asm/timex.h
+@@ -14,5 +14,6 @@
+ 
+ typedef unsigned long cycles_t;
+ #define get_cycles()	({ cycles_t c; read_current_timer(&c) ? 0 : c; })
++#define random_get_entropy() (((unsigned long)get_cycles()) ?: random_get_entropy_fallback())
+ 
+ #endif
+diff --git a/arch/ia64/include/asm/timex.h b/arch/ia64/include/asm/timex.h
+index 86c7db8611803..0117fa73ad490 100644
+--- a/arch/ia64/include/asm/timex.h
++++ b/arch/ia64/include/asm/timex.h
+@@ -38,6 +38,7 @@ get_cycles (void)
+ 	ret = ia64_getreg(_IA64_REG_AR_ITC);
+ 	return ret;
+ }
++#define get_cycles get_cycles
+ 
+ extern void ia64_cpu_local_tick (void);
+ extern unsigned long long ia64_native_sched_clock (void);
+diff --git a/arch/m68k/include/asm/timex.h b/arch/m68k/include/asm/timex.h
+index efc1f48923573..bbaf67f3a952d 100644
+--- a/arch/m68k/include/asm/timex.h
++++ b/arch/m68k/include/asm/timex.h
+@@ -34,7 +34,7 @@ static inline unsigned long random_get_entropy(void)
+ {
+ 	if (mach_random_get_entropy)
+ 		return mach_random_get_entropy();
+-	return 0;
++	return random_get_entropy_fallback();
+ }
+ #define random_get_entropy	random_get_entropy
+ 
+diff --git a/arch/mips/include/asm/timex.h b/arch/mips/include/asm/timex.h
+index 8026baf46e729..2e107886f97ac 100644
+--- a/arch/mips/include/asm/timex.h
++++ b/arch/mips/include/asm/timex.h
+@@ -76,25 +76,24 @@ static inline cycles_t get_cycles(void)
+ 	else
+ 		return 0;	/* no usable counter */
+ }
++#define get_cycles get_cycles
+ 
+ /*
+  * Like get_cycles - but where c0_count is not available we desperately
+  * use c0_random in an attempt to get at least a little bit of entropy.
+- *
+- * R6000 and R6000A neither have a count register nor a random register.
+- * That leaves no entropy source in the CPU itself.
+  */
+ static inline unsigned long random_get_entropy(void)
+ {
+-	unsigned int prid = read_c0_prid();
+-	unsigned int imp = prid & PRID_IMP_MASK;
++	unsigned int c0_random;
+ 
+-	if (can_use_mips_counter(prid))
++	if (can_use_mips_counter(read_c0_prid()))
+ 		return read_c0_count();
+-	else if (likely(imp != PRID_IMP_R6000 && imp != PRID_IMP_R6000A))
+-		return read_c0_random();
++
++	if (cpu_has_3kex)
++		c0_random = (read_c0_random() >> 8) & 0x3f;
+ 	else
+-		return 0;	/* no usable register */
++		c0_random = read_c0_random() & 0x3f;
++	return (random_get_entropy_fallback() << 6) | (0x3f - c0_random);
+ }
+ #define random_get_entropy random_get_entropy
+ 
+diff --git a/arch/nios2/include/asm/timex.h b/arch/nios2/include/asm/timex.h
+index 2f2abb28ec2fd..9c9b50599ea30 100644
+--- a/arch/nios2/include/asm/timex.h
++++ b/arch/nios2/include/asm/timex.h
+@@ -20,5 +20,8 @@
+ typedef unsigned long cycles_t;
+ 
+ extern cycles_t get_cycles(void);
++#define get_cycles get_cycles
++
++#define random_get_entropy() (((unsigned long)get_cycles()) ?: random_get_entropy_fallback())
+ 
+ #endif
+diff --git a/arch/parisc/include/asm/timex.h b/arch/parisc/include/asm/timex.h
+index 2bd51f6d832bb..87aeeee5b700f 100644
+--- a/arch/parisc/include/asm/timex.h
++++ b/arch/parisc/include/asm/timex.h
+@@ -11,9 +11,10 @@
+ 
+ typedef unsigned long cycles_t;
+ 
+-static inline cycles_t get_cycles (void)
++static inline cycles_t get_cycles(void)
+ {
+ 	return mfctl(16);
+ }
++#define get_cycles get_cycles
+ 
+ #endif
+diff --git a/arch/powerpc/include/asm/archrandom.h b/arch/powerpc/include/asm/archrandom.h
+index 9ff848e3c4a62..d8da8c0fb928c 100644
+--- a/arch/powerpc/include/asm/archrandom.h
++++ b/arch/powerpc/include/asm/archrandom.h
+@@ -5,27 +5,28 @@
+ 
+ #include <asm/machdep.h>
+ 
+-static inline int arch_get_random_long(unsigned long *v)
++static inline bool arch_get_random_long(unsigned long *v)
+ {
+-	return 0;
++	return false;
+ }
+ 
+-static inline int arch_get_random_int(unsigned int *v)
++static inline bool arch_get_random_int(unsigned int *v)
+ {
+-	return 0;
++	return false;
+ }
+ 
+-static inline int arch_get_random_seed_long(unsigned long *v)
++static inline bool arch_get_random_seed_long(unsigned long *v)
+ {
+ 	if (ppc_md.get_random_seed)
+ 		return ppc_md.get_random_seed(v);
+ 
+-	return 0;
++	return false;
+ }
+-static inline int arch_get_random_seed_int(unsigned int *v)
++
++static inline bool arch_get_random_seed_int(unsigned int *v)
+ {
+ 	unsigned long val;
+-	int rc;
++	bool rc;
+ 
+ 	rc = arch_get_random_seed_long(&val);
+ 	if (rc)
+@@ -33,16 +34,6 @@ static inline int arch_get_random_seed_int(unsigned int *v)
+ 
+ 	return rc;
+ }
+-
+-static inline int arch_has_random(void)
+-{
+-	return 0;
+-}
+-
+-static inline int arch_has_random_seed(void)
+-{
+-	return !!ppc_md.get_random_seed;
+-}
+ #endif /* CONFIG_ARCH_RANDOM */
+ 
+ #ifdef CONFIG_PPC_POWERNV
+diff --git a/arch/powerpc/include/asm/timex.h b/arch/powerpc/include/asm/timex.h
+index 2cf846edb3fcc..28b8a63bc3661 100644
+--- a/arch/powerpc/include/asm/timex.h
++++ b/arch/powerpc/include/asm/timex.h
+@@ -53,6 +53,7 @@ static inline cycles_t get_cycles(void)
+ 	return ret;
+ #endif
+ }
++#define get_cycles get_cycles
+ 
+ #endif	/* __KERNEL__ */
+ #endif	/* _ASM_POWERPC_TIMEX_H */
+diff --git a/arch/s390/include/asm/timex.h b/arch/s390/include/asm/timex.h
+index f1330245b5840..f9c222cfc65c2 100644
+--- a/arch/s390/include/asm/timex.h
++++ b/arch/s390/include/asm/timex.h
+@@ -168,6 +168,7 @@ static inline cycles_t get_cycles(void)
+ {
+ 	return (cycles_t) get_tod_clock() >> 2;
+ }
++#define get_cycles get_cycles
+ 
+ int get_phys_clock(unsigned long long *clock);
+ void init_cpu_timer(void);
+diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c
+index 7678f7956409b..1847bc3ff163b 100644
+--- a/arch/s390/mm/pgtable.c
++++ b/arch/s390/mm/pgtable.c
+@@ -595,7 +595,7 @@ void ptep_zap_key(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
+ 			      PGSTE_GR_BIT | PGSTE_GC_BIT);
+ 	ptev = pte_val(*ptep);
+ 	if (!(ptev & _PAGE_INVALID) && (ptev & _PAGE_WRITE))
+-		page_set_storage_key(ptev & PAGE_MASK, PAGE_DEFAULT_KEY, 1);
++		page_set_storage_key(ptev & PAGE_MASK, PAGE_DEFAULT_KEY, 0);
+ 	pgste_set_unlock(ptep, pgste);
+ 	preempt_enable();
+ }
+diff --git a/arch/sparc/include/asm/timex_32.h b/arch/sparc/include/asm/timex_32.h
+index b6ccdb0d6f7de..b805c511755d6 100644
+--- a/arch/sparc/include/asm/timex_32.h
++++ b/arch/sparc/include/asm/timex_32.h
+@@ -8,8 +8,6 @@
+ 
+ #define CLOCK_TICK_RATE	1193180 /* Underlying HZ */
+ 
+-/* XXX Maybe do something better at some point... -DaveM */
+-typedef unsigned long cycles_t;
+-#define get_cycles()	(0)
++#include <asm-generic/timex.h>
+ 
+ #endif
+diff --git a/arch/um/include/asm/timex.h b/arch/um/include/asm/timex.h
+index 0f4ada08f7488..62a0fbf79420f 100644
+--- a/arch/um/include/asm/timex.h
++++ b/arch/um/include/asm/timex.h
+@@ -1,13 +1,8 @@
+ #ifndef __UM_TIMEX_H
+ #define __UM_TIMEX_H
+ 
+-typedef unsigned long cycles_t;
+-
+-static inline cycles_t get_cycles (void)
+-{
+-	return 0;
+-}
+-
+ #define CLOCK_TICK_RATE (HZ)
+ 
++#include <asm-generic/timex.h>
++
+ #endif
+diff --git a/arch/x86/include/asm/archrandom.h b/arch/x86/include/asm/archrandom.h
+index 3ac991d81e74d..4d3cac3c9b250 100644
+--- a/arch/x86/include/asm/archrandom.h
++++ b/arch/x86/include/asm/archrandom.h
+@@ -86,10 +86,6 @@ static inline bool rdseed_int(unsigned int *v)
+ 	return ok;
+ }
+ 
+-/* Conditional execution based on CPU type */
+-#define arch_has_random()	static_cpu_has(X86_FEATURE_RDRAND)
+-#define arch_has_random_seed()	static_cpu_has(X86_FEATURE_RDSEED)
+-
+ /*
+  * These are the generic interfaces; they must not be declared if the
+  * stubs in <linux/random.h> are to be invoked,
+@@ -99,22 +95,22 @@ static inline bool rdseed_int(unsigned int *v)
+ 
+ static inline bool arch_get_random_long(unsigned long *v)
+ {
+-	return arch_has_random() ? rdrand_long(v) : false;
++	return static_cpu_has(X86_FEATURE_RDRAND) ? rdrand_long(v) : false;
+ }
+ 
+ static inline bool arch_get_random_int(unsigned int *v)
+ {
+-	return arch_has_random() ? rdrand_int(v) : false;
++	return static_cpu_has(X86_FEATURE_RDRAND) ? rdrand_int(v) : false;
+ }
+ 
+ static inline bool arch_get_random_seed_long(unsigned long *v)
+ {
+-	return arch_has_random_seed() ? rdseed_long(v) : false;
++	return static_cpu_has(X86_FEATURE_RDSEED) ? rdseed_long(v) : false;
+ }
+ 
+ static inline bool arch_get_random_seed_int(unsigned int *v)
+ {
+-	return arch_has_random_seed() ? rdseed_int(v) : false;
++	return static_cpu_has(X86_FEATURE_RDSEED) ? rdseed_int(v) : false;
+ }
+ 
+ extern void x86_init_rdrand(struct cpuinfo_x86 *c);
+diff --git a/arch/x86/include/asm/timex.h b/arch/x86/include/asm/timex.h
+index 1375cfc93960e..627802b6204c2 100644
+--- a/arch/x86/include/asm/timex.h
++++ b/arch/x86/include/asm/timex.h
+@@ -4,6 +4,15 @@
+ #include <asm/processor.h>
+ #include <asm/tsc.h>
+ 
++static inline unsigned long random_get_entropy(void)
++{
++	if (!IS_ENABLED(CONFIG_X86_TSC) &&
++	    !cpu_feature_enabled(X86_FEATURE_TSC))
++		return random_get_entropy_fallback();
++	return rdtsc();
++}
++#define random_get_entropy random_get_entropy
++
+ /* Assume we use the PIT time source for the clock tick */
+ #define CLOCK_TICK_RATE		PIT_TICK_RATE
+ 
+diff --git a/arch/x86/include/asm/tsc.h b/arch/x86/include/asm/tsc.h
+index 33b6365c22fed..23235c5ef1a14 100644
+--- a/arch/x86/include/asm/tsc.h
++++ b/arch/x86/include/asm/tsc.h
+@@ -21,13 +21,12 @@ extern void disable_TSC(void);
+ 
+ static inline cycles_t get_cycles(void)
+ {
+-#ifndef CONFIG_X86_TSC
+-	if (!boot_cpu_has(X86_FEATURE_TSC))
++	if (!IS_ENABLED(CONFIG_X86_TSC) &&
++	    !cpu_feature_enabled(X86_FEATURE_TSC))
+ 		return 0;
+-#endif
+-
+ 	return rdtsc();
+ }
++#define get_cycles get_cycles
+ 
+ extern struct system_counterval_t convert_art_to_tsc(cycle_t art);
+ 
+diff --git a/arch/xtensa/include/asm/timex.h b/arch/xtensa/include/asm/timex.h
+index f9b389d4e9739..d866bc847d8dc 100644
+--- a/arch/xtensa/include/asm/timex.h
++++ b/arch/xtensa/include/asm/timex.h
+@@ -30,10 +30,6 @@
+ 
+ extern unsigned long ccount_freq;
+ 
+-typedef unsigned long long cycles_t;
+-
+-#define get_cycles()	(0)
+-
+ void local_timer_setup(unsigned cpu);
+ 
+ /*
+@@ -69,4 +65,6 @@ static inline void set_linux_timer (unsigned long ccompare)
+ 	WSR_CCOMPARE(LINUX_TIMER, ccompare);
+ }
+ 
++#include <asm-generic/timex.h>
++
+ #endif	/* _XTENSA_TIMEX_H */
+diff --git a/crypto/chacha20_generic.c b/crypto/chacha20_generic.c
+index 1cab83146e33b..56603afbf6bd0 100644
+--- a/crypto/chacha20_generic.c
++++ b/crypto/chacha20_generic.c
+@@ -23,7 +23,8 @@ static inline u32 le32_to_cpuvp(const void *p)
+ static void chacha20_docrypt(u32 *state, u8 *dst, const u8 *src,
+ 			     unsigned int bytes)
+ {
+-	u8 stream[CHACHA20_BLOCK_SIZE];
++	/* aligned to potentially speed up crypto_xor() */
++	u8 stream[CHACHA20_BLOCK_SIZE] __aligned(sizeof(long));
+ 
+ 	if (dst != src)
+ 		memcpy(dst, src, bytes);
+diff --git a/crypto/drbg.c b/crypto/drbg.c
+index 4bb5f93c94cdb..1b94a4306dfc4 100644
+--- a/crypto/drbg.c
++++ b/crypto/drbg.c
+@@ -219,6 +219,57 @@ static inline unsigned short drbg_sec_strength(drbg_flag_t flags)
+ 	}
+ }
+ 
++/*
++ * FIPS 140-2 continuous self test for the noise source
++ * The test is performed on the noise source input data. Thus, the function
++ * implicitly knows the size of the buffer to be equal to the security
++ * strength.
++ *
++ * Note, this function disregards the nonce trailing the entropy data during
++ * initial seeding.
++ *
++ * drbg->drbg_mutex must have been taken.
++ *
++ * @drbg DRBG handle
++ * @entropy buffer of seed data to be checked
++ *
++ * return:
++ *	0 on success
++ *	-EAGAIN on when the CTRNG is not yet primed
++ *	< 0 on error
++ */
++static int drbg_fips_continuous_test(struct drbg_state *drbg,
++				     const unsigned char *entropy)
++{
++	unsigned short entropylen = drbg_sec_strength(drbg->core->flags);
++	int ret = 0;
++
++	if (!IS_ENABLED(CONFIG_CRYPTO_FIPS))
++		return 0;
++
++	/* skip test if we test the overall system */
++	if (list_empty(&drbg->test_data.list))
++		return 0;
++	/* only perform test in FIPS mode */
++	if (!fips_enabled)
++		return 0;
++
++	if (!drbg->fips_primed) {
++		/* Priming of FIPS test */
++		memcpy(drbg->prev, entropy, entropylen);
++		drbg->fips_primed = true;
++		/* priming: another round is needed */
++		return -EAGAIN;
++	}
++	ret = memcmp(drbg->prev, entropy, entropylen);
++	if (!ret)
++		panic("DRBG continuous self test failed\n");
++	memcpy(drbg->prev, entropy, entropylen);
++
++	/* the test shall pass when the two values are not equal */
++	return 0;
++}
++
+ /*
+  * Convert an integer into a byte representation of this integer.
+  * The byte representation is big-endian
+@@ -986,55 +1037,79 @@ static const struct drbg_state_ops drbg_hash_ops = {
+  ******************************************************************/
+ 
+ static inline int __drbg_seed(struct drbg_state *drbg, struct list_head *seed,
+-			      int reseed)
++			      int reseed, enum drbg_seed_state new_seed_state)
+ {
+ 	int ret = drbg->d_ops->update(drbg, seed, reseed);
+ 
+ 	if (ret)
+ 		return ret;
+ 
+-	drbg->seeded = true;
++	drbg->seeded = new_seed_state;
+ 	/* 10.1.1.2 / 10.1.1.3 step 5 */
+ 	drbg->reseed_ctr = 1;
+ 
++	switch (drbg->seeded) {
++	case DRBG_SEED_STATE_UNSEEDED:
++		/* Impossible, but handle it to silence compiler warnings. */
++	case DRBG_SEED_STATE_PARTIAL:
++		/*
++		 * Require frequent reseeds until the seed source is
++		 * fully initialized.
++		 */
++		drbg->reseed_threshold = 50;
++		break;
++
++	case DRBG_SEED_STATE_FULL:
++		/*
++		 * Seed source has become fully initialized, frequent
++		 * reseeds no longer required.
++		 */
++		drbg->reseed_threshold = drbg_max_requests(drbg);
++		break;
++	}
++
+ 	return ret;
+ }
+ 
+-static void drbg_async_seed(struct work_struct *work)
++static inline int drbg_get_random_bytes(struct drbg_state *drbg,
++					unsigned char *entropy,
++					unsigned int entropylen)
++{
++	int ret;
++
++	do {
++		get_random_bytes(entropy, entropylen);
++		ret = drbg_fips_continuous_test(drbg, entropy);
++		if (ret && ret != -EAGAIN)
++			return ret;
++	} while (ret);
++
++	return 0;
++}
++
++static int drbg_seed_from_random(struct drbg_state *drbg)
+ {
+ 	struct drbg_string data;
+ 	LIST_HEAD(seedlist);
+-	struct drbg_state *drbg = container_of(work, struct drbg_state,
+-					       seed_work);
+ 	unsigned int entropylen = drbg_sec_strength(drbg->core->flags);
+ 	unsigned char entropy[32];
++	int ret;
+ 
+ 	BUG_ON(!entropylen);
+ 	BUG_ON(entropylen > sizeof(entropy));
+-	get_random_bytes(entropy, entropylen);
+ 
+ 	drbg_string_fill(&data, entropy, entropylen);
+ 	list_add_tail(&data.list, &seedlist);
+ 
+-	mutex_lock(&drbg->drbg_mutex);
+-
+-	/* If nonblocking pool is initialized, deactivate Jitter RNG */
+-	crypto_free_rng(drbg->jent);
+-	drbg->jent = NULL;
+-
+-	/* Set seeded to false so that if __drbg_seed fails the
+-	 * next generate call will trigger a reseed.
+-	 */
+-	drbg->seeded = false;
+-
+-	__drbg_seed(drbg, &seedlist, true);
+-
+-	if (drbg->seeded)
+-		drbg->reseed_threshold = drbg_max_requests(drbg);
++	ret = drbg_get_random_bytes(drbg, entropy, entropylen);
++	if (ret)
++		goto out;
+ 
+-	mutex_unlock(&drbg->drbg_mutex);
++	ret = __drbg_seed(drbg, &seedlist, true, DRBG_SEED_STATE_FULL);
+ 
++out:
+ 	memzero_explicit(entropy, entropylen);
++	return ret;
+ }
+ 
+ /*
+@@ -1056,6 +1131,7 @@ static int drbg_seed(struct drbg_state *drbg, struct drbg_string *pers,
+ 	unsigned int entropylen = drbg_sec_strength(drbg->core->flags);
+ 	struct drbg_string data1;
+ 	LIST_HEAD(seedlist);
++	enum drbg_seed_state new_seed_state = DRBG_SEED_STATE_FULL;
+ 
+ 	/* 9.1 / 9.2 / 9.3.1 step 3 */
+ 	if (pers && pers->len > (drbg_max_addtl(drbg))) {
+@@ -1083,7 +1159,12 @@ static int drbg_seed(struct drbg_state *drbg, struct drbg_string *pers,
+ 		BUG_ON((entropylen * 2) > sizeof(entropy));
+ 
+ 		/* Get seed from in-kernel /dev/urandom */
+-		get_random_bytes(entropy, entropylen);
++		if (!rng_is_initialized())
++			new_seed_state = DRBG_SEED_STATE_PARTIAL;
++
++		ret = drbg_get_random_bytes(drbg, entropy, entropylen);
++		if (ret)
++			goto out;
+ 
+ 		if (!drbg->jent) {
+ 			drbg_string_fill(&data1, entropy, entropylen);
+@@ -1096,7 +1177,23 @@ static int drbg_seed(struct drbg_state *drbg, struct drbg_string *pers,
+ 						   entropylen);
+ 			if (ret) {
+ 				pr_devel("DRBG: jent failed with %d\n", ret);
+-				return ret;
++
++				/*
++				 * Do not treat the transient failure of the
++				 * Jitter RNG as an error that needs to be
++				 * reported. The combined number of the
++				 * maximum reseed threshold times the maximum
++				 * number of Jitter RNG transient errors is
++				 * less than the reseed threshold required by
++				 * SP800-90A allowing us to treat the
++				 * transient errors as such.
++				 *
++				 * However, we mandate that at least the first
++				 * seeding operation must succeed with the
++				 * Jitter RNG.
++				 */
++				if (!reseed || ret != -EAGAIN)
++					goto out;
+ 			}
+ 
+ 			drbg_string_fill(&data1, entropy, entropylen * 2);
+@@ -1121,8 +1218,9 @@ static int drbg_seed(struct drbg_state *drbg, struct drbg_string *pers,
+ 		memset(drbg->C, 0, drbg_statelen(drbg));
+ 	}
+ 
+-	ret = __drbg_seed(drbg, &seedlist, reseed);
++	ret = __drbg_seed(drbg, &seedlist, reseed, new_seed_state);
+ 
++out:
+ 	memzero_explicit(entropy, entropylen * 2);
+ 
+ 	return ret;
+@@ -1144,6 +1242,11 @@ static inline void drbg_dealloc_state(struct drbg_state *drbg)
+ 	drbg->reseed_ctr = 0;
+ 	drbg->d_ops = NULL;
+ 	drbg->core = NULL;
++	if (IS_ENABLED(CONFIG_CRYPTO_FIPS)) {
++		kzfree(drbg->prev);
++		drbg->prev = NULL;
++		drbg->fips_primed = false;
++	}
+ }
+ 
+ /*
+@@ -1213,6 +1316,14 @@ static inline int drbg_alloc_state(struct drbg_state *drbg)
+ 		drbg->scratchpad = PTR_ALIGN(drbg->scratchpadbuf, ret + 1);
+ 	}
+ 
++	if (IS_ENABLED(CONFIG_CRYPTO_FIPS)) {
++		drbg->prev = kzalloc(drbg_sec_strength(drbg->core->flags),
++				     GFP_KERNEL);
++		if (!drbg->prev)
++			goto fini;
++		drbg->fips_primed = false;
++	}
++
+ 	return 0;
+ 
+ fini:
+@@ -1285,19 +1396,25 @@ static int drbg_generate(struct drbg_state *drbg,
+ 	 * here. The spec is a bit convoluted here, we make it simpler.
+ 	 */
+ 	if (drbg->reseed_threshold < drbg->reseed_ctr)
+-		drbg->seeded = false;
++		drbg->seeded = DRBG_SEED_STATE_UNSEEDED;
+ 
+-	if (drbg->pr || !drbg->seeded) {
++	if (drbg->pr || drbg->seeded == DRBG_SEED_STATE_UNSEEDED) {
+ 		pr_devel("DRBG: reseeding before generation (prediction "
+ 			 "resistance: %s, state %s)\n",
+ 			 drbg->pr ? "true" : "false",
+-			 drbg->seeded ? "seeded" : "unseeded");
++			 (drbg->seeded ==  DRBG_SEED_STATE_FULL ?
++			  "seeded" : "unseeded"));
+ 		/* 9.3.1 steps 7.1 through 7.3 */
+ 		len = drbg_seed(drbg, addtl, true);
+ 		if (len)
+ 			goto err;
+ 		/* 9.3.1 step 7.4 */
+ 		addtl = NULL;
++	} else if (rng_is_initialized() &&
++		   drbg->seeded == DRBG_SEED_STATE_PARTIAL) {
++		len = drbg_seed_from_random(drbg);
++		if (len)
++			goto err;
+ 	}
+ 
+ 	if (addtl && 0 < addtl->len)
+@@ -1390,51 +1507,15 @@ static int drbg_generate_long(struct drbg_state *drbg,
+ 	return 0;
+ }
+ 
+-static void drbg_schedule_async_seed(struct random_ready_callback *rdy)
+-{
+-	struct drbg_state *drbg = container_of(rdy, struct drbg_state,
+-					       random_ready);
+-
+-	schedule_work(&drbg->seed_work);
+-}
+-
+ static int drbg_prepare_hrng(struct drbg_state *drbg)
+ {
+-	int err;
+-
+ 	/* We do not need an HRNG in test mode. */
+ 	if (list_empty(&drbg->test_data.list))
+ 		return 0;
+ 
+-	INIT_WORK(&drbg->seed_work, drbg_async_seed);
+-
+-	drbg->random_ready.owner = THIS_MODULE;
+-	drbg->random_ready.func = drbg_schedule_async_seed;
+-
+-	err = add_random_ready_callback(&drbg->random_ready);
+-
+-	switch (err) {
+-	case 0:
+-		break;
+-
+-	case -EALREADY:
+-		err = 0;
+-		/* fall through */
+-
+-	default:
+-		drbg->random_ready.func = NULL;
+-		return err;
+-	}
+-
+ 	drbg->jent = crypto_alloc_rng("jitterentropy_rng", 0, 0);
+ 
+-	/*
+-	 * Require frequent reseeds until the seed source is fully
+-	 * initialized.
+-	 */
+-	drbg->reseed_threshold = 50;
+-
+-	return err;
++	return 0;
+ }
+ 
+ /*
+@@ -1477,7 +1558,7 @@ static int drbg_instantiate(struct drbg_state *drbg, struct drbg_string *pers,
+ 	if (!drbg->core) {
+ 		drbg->core = &drbg_cores[coreref];
+ 		drbg->pr = pr;
+-		drbg->seeded = false;
++		drbg->seeded = DRBG_SEED_STATE_UNSEEDED;
+ 		drbg->reseed_threshold = drbg_max_requests(drbg);
+ 
+ 		ret = drbg_alloc_state(drbg);
+@@ -1528,12 +1609,9 @@ free_everything:
+  */
+ static int drbg_uninstantiate(struct drbg_state *drbg)
+ {
+-	if (drbg->random_ready.func) {
+-		del_random_ready_callback(&drbg->random_ready);
+-		cancel_work_sync(&drbg->seed_work);
++	if (!IS_ERR_OR_NULL(drbg->jent))
+ 		crypto_free_rng(drbg->jent);
+-		drbg->jent = NULL;
+-	}
++	drbg->jent = NULL;
+ 
+ 	if (drbg->d_ops)
+ 		drbg->d_ops->crypto_fini(drbg);
+diff --git a/crypto/md4.c b/crypto/md4.c
+index 3515af425cc91..810fefb0a007a 100644
+--- a/crypto/md4.c
++++ b/crypto/md4.c
+@@ -64,23 +64,6 @@ static inline u32 H(u32 x, u32 y, u32 z)
+ #define ROUND2(a,b,c,d,k,s) (a = lshift(a + G(b,c,d) + k + (u32)0x5A827999,s))
+ #define ROUND3(a,b,c,d,k,s) (a = lshift(a + H(b,c,d) + k + (u32)0x6ED9EBA1,s))
+ 
+-/* XXX: this stuff can be optimized */
+-static inline void le32_to_cpu_array(u32 *buf, unsigned int words)
+-{
+-	while (words--) {
+-		__le32_to_cpus(buf);
+-		buf++;
+-	}
+-}
+-
+-static inline void cpu_to_le32_array(u32 *buf, unsigned int words)
+-{
+-	while (words--) {
+-		__cpu_to_le32s(buf);
+-		buf++;
+-	}
+-}
+-
+ static void md4_transform(u32 *hash, u32 const *in)
+ {
+ 	u32 a, b, c, d;
+diff --git a/crypto/md5.c b/crypto/md5.c
+index 2355a7c25c458..419f2379b406b 100644
+--- a/crypto/md5.c
++++ b/crypto/md5.c
+@@ -30,23 +30,6 @@ const u8 md5_zero_message_hash[MD5_DIGEST_SIZE] = {
+ };
+ EXPORT_SYMBOL_GPL(md5_zero_message_hash);
+ 
+-/* XXX: this stuff can be optimized */
+-static inline void le32_to_cpu_array(u32 *buf, unsigned int words)
+-{
+-	while (words--) {
+-		__le32_to_cpus(buf);
+-		buf++;
+-	}
+-}
+-
+-static inline void cpu_to_le32_array(u32 *buf, unsigned int words)
+-{
+-	while (words--) {
+-		__cpu_to_le32s(buf);
+-		buf++;
+-	}
+-}
+-
+ static inline void md5_transform_helper(struct md5_state *ctx)
+ {
+ 	le32_to_cpu_array(ctx->block, sizeof(ctx->block) / sizeof(u32));
+diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
+index 35db918a1de56..42f0a592b5ab0 100644
+--- a/drivers/ata/libata-core.c
++++ b/drivers/ata/libata-core.c
+@@ -6051,7 +6051,7 @@ struct ata_host *ata_host_alloc_pinfo(struct device *dev,
+ 				      const struct ata_port_info * const * ppi,
+ 				      int n_ports)
+ {
+-	const struct ata_port_info *pi;
++	const struct ata_port_info *pi = &ata_dummy_port_info;
+ 	struct ata_host *host;
+ 	int i, j;
+ 
+@@ -6059,7 +6059,7 @@ struct ata_host *ata_host_alloc_pinfo(struct device *dev,
+ 	if (!host)
+ 		return NULL;
+ 
+-	for (i = 0, j = 0, pi = NULL; i < host->n_ports; i++) {
++	for (i = 0, j = 0; i < host->n_ports; i++) {
+ 		struct ata_port *ap = host->ports[i];
+ 
+ 		if (ppi[j])
+diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
+index f4ae000eb2855..1d3813d4f5c81 100644
+--- a/drivers/char/Kconfig
++++ b/drivers/char/Kconfig
+@@ -593,5 +593,41 @@ config TILE_SROM
+ 
+ source "drivers/char/xillybus/Kconfig"
+ 
+-endmenu
++config RANDOM_TRUST_CPU
++	bool "Initialize RNG using CPU RNG instructions"
++	default y
++	depends on ARCH_RANDOM
++	help
++	  Initialize the RNG using random numbers supplied by the CPU's
++	  RNG instructions (e.g. RDRAND), if supported and available. These
++	  random numbers are never used directly, but are rather hashed into
++	  the main input pool, and this happens regardless of whether or not
++	  this option is enabled. Instead, this option controls whether the
++	  they are credited and hence can initialize the RNG. Additionally,
++	  other sources of randomness are always used, regardless of this
++	  setting.  Enabling this implies trusting that the CPU can supply high
++	  quality and non-backdoored random numbers.
++
++	  Say Y here unless you have reason to mistrust your CPU or believe
++	  its RNG facilities may be faulty. This may also be configured at
++	  boot time with "random.trust_cpu=on/off".
++
++config RANDOM_TRUST_BOOTLOADER
++	bool "Initialize RNG using bootloader-supplied seed"
++	default y
++	help
++	  Initialize the RNG using a seed supplied by the bootloader or boot
++	  environment (e.g. EFI or a bootloader-generated device tree). This
++	  seed is not used directly, but is rather hashed into the main input
++	  pool, and this happens regardless of whether or not this option is
++	  enabled. Instead, this option controls whether the seed is credited
++	  and hence can initialize the RNG. Additionally, other sources of
++	  randomness are always used, regardless of this setting. Enabling
++	  this implies trusting that the bootloader can supply high quality and
++	  non-backdoored seeds.
++
++	  Say Y here unless you have reason to mistrust your bootloader or
++	  believe its RNG facilities may be faulty. This may also be configured
++	  at boot time with "random.trust_bootloader=on/off".
+ 
++endmenu
+diff --git a/drivers/char/hw_random/core.c b/drivers/char/hw_random/core.c
+index 5e79b4bfe27a9..f1121a162ef02 100644
+--- a/drivers/char/hw_random/core.c
++++ b/drivers/char/hw_random/core.c
+@@ -1,38 +1,18 @@
+ /*
+-        Added support for the AMD Geode LX RNG
+-	(c) Copyright 2004-2005 Advanced Micro Devices, Inc.
+-
+-	derived from
+-
+- 	Hardware driver for the Intel/AMD/VIA Random Number Generators (RNG)
+-	(c) Copyright 2003 Red Hat Inc <jgarzik@redhat.com>
+-
+- 	derived from
+-
+-        Hardware driver for the AMD 768 Random Number Generator (RNG)
+-        (c) Copyright 2001 Red Hat Inc <alan@redhat.com>
+-
+- 	derived from
+-
+-	Hardware driver for Intel i810 Random Number Generator (RNG)
+-	Copyright 2000,2001 Jeff Garzik <jgarzik@pobox.com>
+-	Copyright 2000,2001 Philipp Rumpf <prumpf@mandrakesoft.com>
+-
+-	Added generic RNG API
+-	Copyright 2006 Michael Buesch <m@bues.ch>
+-	Copyright 2005 (c) MontaVista Software, Inc.
+-
+-	Please read Documentation/hw_random.txt for details on use.
+-
+-	----------------------------------------------------------
+-	This software may be used and distributed according to the terms
+-        of the GNU General Public License, incorporated herein by reference.
+-
++ * hw_random/core.c: HWRNG core API
++ *
++ * Copyright 2006 Michael Buesch <m@bues.ch>
++ * Copyright 2005 (c) MontaVista Software, Inc.
++ *
++ * Please read Documentation/hw_random.txt for details on use.
++ *
++ * This software may be used and distributed according to the terms
++ * of the GNU General Public License, incorporated herein by reference.
+  */
+ 
+-
+ #include <linux/device.h>
+ #include <linux/hw_random.h>
++#include <linux/random.h>
+ #include <linux/module.h>
+ #include <linux/kernel.h>
+ #include <linux/fs.h>
+@@ -45,14 +25,13 @@
+ #include <linux/err.h>
+ #include <asm/uaccess.h>
+ 
+-
+ #define RNG_MODULE_NAME		"hw_random"
+-#define PFX			RNG_MODULE_NAME ": "
+-#define RNG_MISCDEV_MINOR	183 /* official */
+-
+ 
+ static struct hwrng *current_rng;
++/* the current rng has been explicitly chosen by user via sysfs */
++static int cur_rng_set_by_user;
+ static struct task_struct *hwrng_fill;
++/* list of registered rngs, sorted decending by quality */
+ static LIST_HEAD(rng_list);
+ /* Protects rng_list and current_rng */
+ static DEFINE_MUTEX(rng_mutex);
+@@ -296,7 +275,6 @@ out_put:
+ 	goto out;
+ }
+ 
+-
+ static const struct file_operations rng_chrdev_ops = {
+ 	.owner		= THIS_MODULE,
+ 	.open		= rng_dev_open,
+@@ -307,14 +285,13 @@ static const struct file_operations rng_chrdev_ops = {
+ static const struct attribute_group *rng_dev_groups[];
+ 
+ static struct miscdevice rng_miscdev = {
+-	.minor		= RNG_MISCDEV_MINOR,
++	.minor		= HWRNG_MINOR,
+ 	.name		= RNG_MODULE_NAME,
+ 	.nodename	= "hwrng",
+ 	.fops		= &rng_chrdev_ops,
+ 	.groups		= rng_dev_groups,
+ };
+ 
+-
+ static ssize_t hwrng_attr_current_store(struct device *dev,
+ 					struct device_attribute *attr,
+ 					const char *buf, size_t len)
+@@ -329,6 +306,7 @@ static ssize_t hwrng_attr_current_store(struct device *dev,
+ 	list_for_each_entry(rng, &rng_list, list) {
+ 		if (sysfs_streq(rng->name, buf)) {
+ 			err = 0;
++			cur_rng_set_by_user = 1;
+ 			if (rng != current_rng)
+ 				err = set_current_rng(rng);
+ 			break;
+@@ -377,16 +355,27 @@ static ssize_t hwrng_attr_available_show(struct device *dev,
+ 	return strlen(buf);
+ }
+ 
++static ssize_t hwrng_attr_selected_show(struct device *dev,
++					struct device_attribute *attr,
++					char *buf)
++{
++	return snprintf(buf, PAGE_SIZE, "%d\n", cur_rng_set_by_user);
++}
++
+ static DEVICE_ATTR(rng_current, S_IRUGO | S_IWUSR,
+ 		   hwrng_attr_current_show,
+ 		   hwrng_attr_current_store);
+ static DEVICE_ATTR(rng_available, S_IRUGO,
+ 		   hwrng_attr_available_show,
+ 		   NULL);
++static DEVICE_ATTR(rng_selected, S_IRUGO,
++		   hwrng_attr_selected_show,
++		   NULL);
+ 
+ static struct attribute *rng_dev_attrs[] = {
+ 	&dev_attr_rng_current.attr,
+ 	&dev_attr_rng_available.attr,
++	&dev_attr_rng_selected.attr,
+ 	NULL
+ };
+ 
+@@ -443,9 +432,9 @@ int hwrng_register(struct hwrng *rng)
+ {
+ 	int err = -EINVAL;
+ 	struct hwrng *old_rng, *tmp;
++	struct list_head *rng_list_ptr;
+ 
+-	if (rng->name == NULL ||
+-	    (rng->data_read == NULL && rng->read == NULL))
++	if (!rng->name || (!rng->data_read && !rng->read))
+ 		goto out;
+ 
+ 	mutex_lock(&rng_mutex);
+@@ -459,14 +448,27 @@ int hwrng_register(struct hwrng *rng)
+ 	init_completion(&rng->cleanup_done);
+ 	complete(&rng->cleanup_done);
+ 
++	/* rng_list is sorted by decreasing quality */
++	list_for_each(rng_list_ptr, &rng_list) {
++		tmp = list_entry(rng_list_ptr, struct hwrng, list);
++		if (tmp->quality < rng->quality)
++			break;
++	}
++	list_add_tail(&rng->list, rng_list_ptr);
++
+ 	old_rng = current_rng;
+ 	err = 0;
+-	if (!old_rng) {
++	if (!old_rng ||
++	    (!cur_rng_set_by_user && rng->quality > old_rng->quality)) {
++		/*
++		 * Set new rng as current as the new rng source
++		 * provides better entropy quality and was not
++		 * chosen by userspace.
++		 */
+ 		err = set_current_rng(rng);
+ 		if (err)
+ 			goto out_unlock;
+ 	}
+-	list_add_tail(&rng->list, &rng_list);
+ 
+ 	if (old_rng && !rng->init) {
+ 		/*
+@@ -493,12 +495,13 @@ void hwrng_unregister(struct hwrng *rng)
+ 	list_del(&rng->list);
+ 	if (current_rng == rng) {
+ 		drop_current_rng();
++		cur_rng_set_by_user = 0;
++		/* rng_list is sorted by quality, use the best (=first) one */
+ 		if (!list_empty(&rng_list)) {
+-			struct hwrng *tail;
+-
+-			tail = list_entry(rng_list.prev, struct hwrng, list);
++			struct hwrng *new_rng;
+ 
+-			set_current_rng(tail);
++			new_rng = list_entry(rng_list.next, struct hwrng, list);
++			set_current_rng(new_rng);
+ 		}
+ 	}
+ 
+diff --git a/drivers/char/random.c b/drivers/char/random.c
+index 70ee86e034fcd..8e701ea78b0da 100644
+--- a/drivers/char/random.c
++++ b/drivers/char/random.c
+@@ -1,239 +1,29 @@
++// SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
+ /*
+- * random.c -- A strong random number generator
+- *
++ * Copyright (C) 2017-2022 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
+  * Copyright Matt Mackall <mpm@selenic.com>, 2003, 2004, 2005
+- *
+- * Copyright Theodore Ts'o, 1994, 1995, 1996, 1997, 1998, 1999.  All
+- * rights reserved.
+- *
+- * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions
+- * are met:
+- * 1. Redistributions of source code must retain the above copyright
+- *    notice, and the entire permission notice in its entirety,
+- *    including the disclaimer of warranties.
+- * 2. Redistributions in binary form must reproduce the above copyright
+- *    notice, this list of conditions and the following disclaimer in the
+- *    documentation and/or other materials provided with the distribution.
+- * 3. The name of the author may not be used to endorse or promote
+- *    products derived from this software without specific prior
+- *    written permission.
+- *
+- * ALTERNATIVELY, this product may be distributed under the terms of
+- * the GNU General Public License, in which case the provisions of the GPL are
+- * required INSTEAD OF the above restrictions.  (This clause is
+- * necessary due to a potential bad interaction between the GPL and
+- * the restrictions contained in a BSD-style copyright.)
+- *
+- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF
+- * WHICH ARE HEREBY DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE
+- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+- * USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH
+- * DAMAGE.
++ * Copyright Theodore Ts'o, 1994, 1995, 1996, 1997, 1998, 1999. All rights reserved.
++ *
++ * This driver produces cryptographically secure pseudorandom data. It is divided
++ * into roughly six sections, each with a section header:
++ *
++ *   - Initialization and readiness waiting.
++ *   - Fast key erasure RNG, the "crng".
++ *   - Entropy accumulation and extraction routines.
++ *   - Entropy collection routines.
++ *   - Userspace reader/writer interfaces.
++ *   - Sysctl interface.
++ *
++ * The high level overview is that there is one input pool, into which
++ * various pieces of data are hashed. Prior to initialization, some of that
++ * data is then "credited" as having a certain number of bits of entropy.
++ * When enough bits of entropy are available, the hash is finalized and
++ * handed as a key to a stream cipher that expands it indefinitely for
++ * various consumers. This key is periodically refreshed as the various
++ * entropy collectors, described below, add data to the input pool.
+  */
+ 
+-/*
+- * (now, with legal B.S. out of the way.....)
+- *
+- * This routine gathers environmental noise from device drivers, etc.,
+- * and returns good random numbers, suitable for cryptographic use.
+- * Besides the obvious cryptographic uses, these numbers are also good
+- * for seeding TCP sequence numbers, and other places where it is
+- * desirable to have numbers which are not only random, but hard to
+- * predict by an attacker.
+- *
+- * Theory of operation
+- * ===================
+- *
+- * Computers are very predictable devices.  Hence it is extremely hard
+- * to produce truly random numbers on a computer --- as opposed to
+- * pseudo-random numbers, which can easily generated by using a
+- * algorithm.  Unfortunately, it is very easy for attackers to guess
+- * the sequence of pseudo-random number generators, and for some
+- * applications this is not acceptable.  So instead, we must try to
+- * gather "environmental noise" from the computer's environment, which
+- * must be hard for outside attackers to observe, and use that to
+- * generate random numbers.  In a Unix environment, this is best done
+- * from inside the kernel.
+- *
+- * Sources of randomness from the environment include inter-keyboard
+- * timings, inter-interrupt timings from some interrupts, and other
+- * events which are both (a) non-deterministic and (b) hard for an
+- * outside observer to measure.  Randomness from these sources are
+- * added to an "entropy pool", which is mixed using a CRC-like function.
+- * This is not cryptographically strong, but it is adequate assuming
+- * the randomness is not chosen maliciously, and it is fast enough that
+- * the overhead of doing it on every interrupt is very reasonable.
+- * As random bytes are mixed into the entropy pool, the routines keep
+- * an *estimate* of how many bits of randomness have been stored into
+- * the random number generator's internal state.
+- *
+- * When random bytes are desired, they are obtained by taking the SHA
+- * hash of the contents of the "entropy pool".  The SHA hash avoids
+- * exposing the internal state of the entropy pool.  It is believed to
+- * be computationally infeasible to derive any useful information
+- * about the input of SHA from its output.  Even if it is possible to
+- * analyze SHA in some clever way, as long as the amount of data
+- * returned from the generator is less than the inherent entropy in
+- * the pool, the output data is totally unpredictable.  For this
+- * reason, the routine decreases its internal estimate of how many
+- * bits of "true randomness" are contained in the entropy pool as it
+- * outputs random numbers.
+- *
+- * If this estimate goes to zero, the routine can still generate
+- * random numbers; however, an attacker may (at least in theory) be
+- * able to infer the future output of the generator from prior
+- * outputs.  This requires successful cryptanalysis of SHA, which is
+- * not believed to be feasible, but there is a remote possibility.
+- * Nonetheless, these numbers should be useful for the vast majority
+- * of purposes.
+- *
+- * Exported interfaces ---- output
+- * ===============================
+- *
+- * There are three exported interfaces; the first is one designed to
+- * be used from within the kernel:
+- *
+- * 	void get_random_bytes(void *buf, int nbytes);
+- *
+- * This interface will return the requested number of random bytes,
+- * and place it in the requested buffer.
+- *
+- * The two other interfaces are two character devices /dev/random and
+- * /dev/urandom.  /dev/random is suitable for use when very high
+- * quality randomness is desired (for example, for key generation or
+- * one-time pads), as it will only return a maximum of the number of
+- * bits of randomness (as estimated by the random number generator)
+- * contained in the entropy pool.
+- *
+- * The /dev/urandom device does not have this limit, and will return
+- * as many bytes as are requested.  As more and more random bytes are
+- * requested without giving time for the entropy pool to recharge,
+- * this will result in random numbers that are merely cryptographically
+- * strong.  For many applications, however, this is acceptable.
+- *
+- * Exported interfaces ---- input
+- * ==============================
+- *
+- * The current exported interfaces for gathering environmental noise
+- * from the devices are:
+- *
+- *	void add_device_randomness(const void *buf, unsigned int size);
+- * 	void add_input_randomness(unsigned int type, unsigned int code,
+- *                                unsigned int value);
+- *	void add_interrupt_randomness(int irq, int irq_flags);
+- * 	void add_disk_randomness(struct gendisk *disk);
+- *
+- * add_device_randomness() is for adding data to the random pool that
+- * is likely to differ between two devices (or possibly even per boot).
+- * This would be things like MAC addresses or serial numbers, or the
+- * read-out of the RTC. This does *not* add any actual entropy to the
+- * pool, but it initializes the pool to different values for devices
+- * that might otherwise be identical and have very little entropy
+- * available to them (particularly common in the embedded world).
+- *
+- * add_input_randomness() uses the input layer interrupt timing, as well as
+- * the event type information from the hardware.
+- *
+- * add_interrupt_randomness() uses the interrupt timing as random
+- * inputs to the entropy pool. Using the cycle counters and the irq source
+- * as inputs, it feeds the randomness roughly once a second.
+- *
+- * add_disk_randomness() uses what amounts to the seek time of block
+- * layer request events, on a per-disk_devt basis, as input to the
+- * entropy pool. Note that high-speed solid state drives with very low
+- * seek times do not make for good sources of entropy, as their seek
+- * times are usually fairly consistent.
+- *
+- * All of these routines try to estimate how many bits of randomness a
+- * particular randomness source.  They do this by keeping track of the
+- * first and second order deltas of the event timings.
+- *
+- * Ensuring unpredictability at system startup
+- * ============================================
+- *
+- * When any operating system starts up, it will go through a sequence
+- * of actions that are fairly predictable by an adversary, especially
+- * if the start-up does not involve interaction with a human operator.
+- * This reduces the actual number of bits of unpredictability in the
+- * entropy pool below the value in entropy_count.  In order to
+- * counteract this effect, it helps to carry information in the
+- * entropy pool across shut-downs and start-ups.  To do this, put the
+- * following lines an appropriate script which is run during the boot
+- * sequence:
+- *
+- *	echo "Initializing random number generator..."
+- *	random_seed=/var/run/random-seed
+- *	# Carry a random seed from start-up to start-up
+- *	# Load and then save the whole entropy pool
+- *	if [ -f $random_seed ]; then
+- *		cat $random_seed >/dev/urandom
+- *	else
+- *		touch $random_seed
+- *	fi
+- *	chmod 600 $random_seed
+- *	dd if=/dev/urandom of=$random_seed count=1 bs=512
+- *
+- * and the following lines in an appropriate script which is run as
+- * the system is shutdown:
+- *
+- *	# Carry a random seed from shut-down to start-up
+- *	# Save the whole entropy pool
+- *	echo "Saving random seed..."
+- *	random_seed=/var/run/random-seed
+- *	touch $random_seed
+- *	chmod 600 $random_seed
+- *	dd if=/dev/urandom of=$random_seed count=1 bs=512
+- *
+- * For example, on most modern systems using the System V init
+- * scripts, such code fragments would be found in
+- * /etc/rc.d/init.d/random.  On older Linux systems, the correct script
+- * location might be in /etc/rcb.d/rc.local or /etc/rc.d/rc.0.
+- *
+- * Effectively, these commands cause the contents of the entropy pool
+- * to be saved at shut-down time and reloaded into the entropy pool at
+- * start-up.  (The 'dd' in the addition to the bootup script is to
+- * make sure that /etc/random-seed is different for every start-up,
+- * even if the system crashes without executing rc.0.)  Even with
+- * complete knowledge of the start-up activities, predicting the state
+- * of the entropy pool requires knowledge of the previous history of
+- * the system.
+- *
+- * Configuring the /dev/random driver under Linux
+- * ==============================================
+- *
+- * The /dev/random driver under Linux uses minor numbers 8 and 9 of
+- * the /dev/mem major number (#1).  So if your system does not have
+- * /dev/random and /dev/urandom created already, they can be created
+- * by using the commands:
+- *
+- * 	mknod /dev/random c 1 8
+- * 	mknod /dev/urandom c 1 9
+- *
+- * Acknowledgements:
+- * =================
+- *
+- * Ideas for constructing this random number generator were derived
+- * from Pretty Good Privacy's random number generator, and from private
+- * discussions with Phil Karn.  Colin Plumb provided a faster random
+- * number generator, which speed up the mixing function of the entropy
+- * pool, taken from PGPfone.  Dale Worley has also contributed many
+- * useful ideas and suggestions to improve this driver.
+- *
+- * Any flaws in the design are solely my responsibility, and should
+- * not be attributed to the Phil, Colin, or any of authors of PGP.
+- *
+- * Further background information on this topic may be obtained from
+- * RFC 1750, "Randomness Recommendations for Security", by Donald
+- * Eastlake, Steve Crocker, and Jeff Schiller.
+- */
++#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+ 
+ #include <linux/utsname.h>
+ #include <linux/module.h>
+@@ -253,8 +43,6 @@
+ #include <linux/spinlock.h>
+ #include <linux/kthread.h>
+ #include <linux/percpu.h>
+-#include <linux/cryptohash.h>
+-#include <linux/fips.h>
+ #include <linux/ptrace.h>
+ #include <linux/kmemcheck.h>
+ #include <linux/workqueue.h>
+@@ -263,1480 +51,1067 @@
+ #include <linux/syscalls.h>
+ #include <linux/completion.h>
+ #include <linux/uuid.h>
++#include <linux/siphash.h>
++#include <linux/uio.h>
+ #include <crypto/chacha20.h>
+-
++#include <crypto/blake2s.h>
+ #include <asm/processor.h>
+ #include <asm/uaccess.h>
+ #include <asm/irq.h>
+ #include <asm/irq_regs.h>
+ #include <asm/io.h>
+ 
+-#define CREATE_TRACE_POINTS
+-#include <trace/events/random.h>
+-
+-/* #define ADD_INTERRUPT_BENCH */
++/*********************************************************************
++ *
++ * Initialization and readiness waiting.
++ *
++ * Much of the RNG infrastructure is devoted to various dependencies
++ * being able to wait until the RNG has collected enough entropy and
++ * is ready for safe consumption.
++ *
++ *********************************************************************/
+ 
+ /*
+- * Configuration information
++ * crng_init is protected by base_crng->lock, and only increases
++ * its value (from empty->early->ready).
+  */
+-#define INPUT_POOL_SHIFT	12
+-#define INPUT_POOL_WORDS	(1 << (INPUT_POOL_SHIFT-5))
+-#define OUTPUT_POOL_SHIFT	10
+-#define OUTPUT_POOL_WORDS	(1 << (OUTPUT_POOL_SHIFT-5))
+-#define SEC_XFER_SIZE		512
+-#define EXTRACT_SIZE		10
+-
+-#define DEBUG_RANDOM_BOOT 0
++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 __read_mostly = CRNG_EMPTY;
++#define crng_ready() (likely(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;
++static DEFINE_SPINLOCK(random_ready_chain_lock);
++static RAW_NOTIFIER_HEAD(random_ready_chain);
+ 
+-#define LONGS(x) (((x) + sizeof(unsigned long) - 1)/sizeof(unsigned long))
++/* Control how we warn userspace. */
++static struct ratelimit_state urandom_warning =
++	RATELIMIT_STATE_INIT("warn_urandom_randomness", HZ, 3);
++static int ratelimit_disable __read_mostly =
++	IS_ENABLED(CONFIG_WARN_ALL_UNSEEDED_RANDOM);
++module_param_named(ratelimit_disable, ratelimit_disable, int, 0644);
++MODULE_PARM_DESC(ratelimit_disable, "Disable random ratelimit suppression");
+ 
+ /*
+- * To allow fractional bits to be tracked, the entropy_count field is
+- * denominated in units of 1/8th bits.
++ * Returns whether or not the input pool has been seeded and thus guaranteed
++ * to supply cryptographically secure random numbers. This applies to: the
++ * /dev/urandom device, the get_random_bytes function, and the get_random_{u32,
++ * ,u64,int,long} family of functions.
+  *
+- * 2*(ENTROPY_SHIFT + log2(poolbits)) must <= 31, or the multiply in
+- * credit_entropy_bits() needs to be 64 bits wide.
++ * Returns: true if the input pool has been seeded.
++ *          false if the input pool has not been seeded.
+  */
+-#define ENTROPY_SHIFT 3
+-#define ENTROPY_BITS(r) ((r)->entropy_count >> ENTROPY_SHIFT)
++bool rng_is_initialized(void)
++{
++	return crng_ready();
++}
++EXPORT_SYMBOL(rng_is_initialized);
+ 
+-/*
+- * The minimum number of bits of entropy before we wake up a read on
+- * /dev/random.  Should be enough to do a significant reseed.
+- */
+-static int random_read_wakeup_bits = 64;
++/* Used by wait_for_random_bytes(), and considered an entropy collector, below. */
++static void try_to_generate_entropy(void);
+ 
+ /*
+- * If the entropy count falls under this number of bits, then we
+- * should wake up processes which are selecting or polling on write
+- * access to /dev/random.
++ * Wait for the input pool to be seeded and thus guaranteed to supply
++ * cryptographically secure random numbers. This applies to: the /dev/urandom
++ * device, the get_random_bytes function, and the get_random_{u32,u64,int,long}
++ * family of functions. Using any of these functions without first calling
++ * this function forfeits the guarantee of security.
++ *
++ * Returns: 0 if the input pool has been seeded.
++ *          -ERESTARTSYS if the function was interrupted by a signal.
+  */
+-static int random_write_wakeup_bits = 28 * OUTPUT_POOL_WORDS;
++int wait_for_random_bytes(void)
++{
++	while (!crng_ready()) {
++		int ret;
+ 
+-/*
+- * The minimum number of seconds between urandom pool reseeding.  We
+- * do this to limit the amount of entropy that can be drained from the
+- * input pool even if there are heavy demands on /dev/urandom.
+- */
+-static int random_min_urandom_seed = 60;
++		try_to_generate_entropy();
++		ret = wait_event_interruptible_timeout(crng_init_wait, crng_ready(), HZ);
++		if (ret)
++			return ret > 0 ? 0 : ret;
++	}
++	return 0;
++}
++EXPORT_SYMBOL(wait_for_random_bytes);
+ 
+ /*
+- * Originally, we used a primitive polynomial of degree .poolwords
+- * over GF(2).  The taps for various sizes are defined below.  They
+- * were chosen to be evenly spaced except for the last tap, which is 1
+- * to get the twisting happening as fast as possible.
+- *
+- * For the purposes of better mixing, we use the CRC-32 polynomial as
+- * well to make a (modified) twisted Generalized Feedback Shift
+- * Register.  (See M. Matsumoto & Y. Kurita, 1992.  Twisted GFSR
+- * generators.  ACM Transactions on Modeling and Computer Simulation
+- * 2(3):179-194.  Also see M. Matsumoto & Y. Kurita, 1994.  Twisted
+- * GFSR generators II.  ACM Transactions on Modeling and Computer
+- * Simulation 4:254-266)
+- *
+- * Thanks to Colin Plumb for suggesting this.
+- *
+- * The mixing operation is much less sensitive than the output hash,
+- * where we use SHA-1.  All that we want of mixing operation is that
+- * it be a good non-cryptographic hash; i.e. it not produce collisions
+- * when fed "random" data of the sort we expect to see.  As long as
+- * the pool state differs for different inputs, we have preserved the
+- * input entropy and done a good job.  The fact that an intelligent
+- * attacker can construct inputs that will produce controlled
+- * alterations to the pool's state is not important because we don't
+- * consider such inputs to contribute any randomness.  The only
+- * property we need with respect to them is that the attacker can't
+- * increase his/her knowledge of the pool's state.  Since all
+- * additions are reversible (knowing the final state and the input,
+- * you can reconstruct the initial state), if an attacker has any
+- * uncertainty about the initial state, he/she can only shuffle that
+- * uncertainty about, but never cause any collisions (which would
+- * decrease the uncertainty).
++ * Add a callback function that will be invoked when the input
++ * pool is initialised.
+  *
+- * Our mixing functions were analyzed by Lacharme, Roeck, Strubel, and
+- * Videau in their paper, "The Linux Pseudorandom Number Generator
+- * Revisited" (see: http://eprint.iacr.org/2012/251.pdf).  In their
+- * paper, they point out that we are not using a true Twisted GFSR,
+- * since Matsumoto & Kurita used a trinomial feedback polynomial (that
+- * is, with only three taps, instead of the six that we are using).
+- * As a result, the resulting polynomial is neither primitive nor
+- * irreducible, and hence does not have a maximal period over
+- * GF(2**32).  They suggest a slight change to the generator
+- * polynomial which improves the resulting TGFSR polynomial to be
+- * irreducible, which we have made here.
++ * returns: 0 if callback is successfully added
++ *	    -EALREADY if pool is already initialised (callback not called)
+  */
+-static struct poolinfo {
+-	int poolbitshift, poolwords, poolbytes, poolbits, poolfracbits;
+-#define S(x) ilog2(x)+5, (x), (x)*4, (x)*32, (x) << (ENTROPY_SHIFT+5)
+-	int tap1, tap2, tap3, tap4, tap5;
+-} poolinfo_table[] = {
+-	/* was: x^128 + x^103 + x^76 + x^51 +x^25 + x + 1 */
+-	/* x^128 + x^104 + x^76 + x^51 +x^25 + x + 1 */
+-	{ S(128),	104,	76,	51,	25,	1 },
+-	/* was: x^32 + x^26 + x^20 + x^14 + x^7 + x + 1 */
+-	/* x^32 + x^26 + x^19 + x^14 + x^7 + x + 1 */
+-	{ S(32),	26,	19,	14,	7,	1 },
+-#if 0
+-	/* x^2048 + x^1638 + x^1231 + x^819 + x^411 + x + 1  -- 115 */
+-	{ S(2048),	1638,	1231,	819,	411,	1 },
+-
+-	/* x^1024 + x^817 + x^615 + x^412 + x^204 + x + 1 -- 290 */
+-	{ S(1024),	817,	615,	412,	204,	1 },
+-
+-	/* x^1024 + x^819 + x^616 + x^410 + x^207 + x^2 + 1 -- 115 */
+-	{ S(1024),	819,	616,	410,	207,	2 },
+-
+-	/* x^512 + x^411 + x^308 + x^208 + x^104 + x + 1 -- 225 */
+-	{ S(512),	411,	308,	208,	104,	1 },
+-
+-	/* x^512 + x^409 + x^307 + x^206 + x^102 + x^2 + 1 -- 95 */
+-	{ S(512),	409,	307,	206,	102,	2 },
+-	/* x^512 + x^409 + x^309 + x^205 + x^103 + x^2 + 1 -- 95 */
+-	{ S(512),	409,	309,	205,	103,	2 },
+-
+-	/* x^256 + x^205 + x^155 + x^101 + x^52 + x + 1 -- 125 */
+-	{ S(256),	205,	155,	101,	52,	1 },
+-
+-	/* x^128 + x^103 + x^78 + x^51 + x^27 + x^2 + 1 -- 70 */
+-	{ S(128),	103,	78,	51,	27,	2 },
+-
+-	/* x^64 + x^52 + x^39 + x^26 + x^14 + x + 1 -- 15 */
+-	{ S(64),	52,	39,	26,	14,	1 },
+-#endif
+-};
++int __cold register_random_ready_notifier(struct notifier_block *nb)
++{
++	unsigned long flags;
++	int ret = -EALREADY;
++
++	if (crng_ready())
++		return ret;
++
++	spin_lock_irqsave(&random_ready_chain_lock, flags);
++	if (!crng_ready())
++		ret = raw_notifier_chain_register(&random_ready_chain, nb);
++	spin_unlock_irqrestore(&random_ready_chain_lock, flags);
++	return ret;
++}
+ 
+ /*
+- * Static global variables
++ * Delete a previously registered readiness callback function.
+  */
+-static DECLARE_WAIT_QUEUE_HEAD(random_read_wait);
+-static DECLARE_WAIT_QUEUE_HEAD(random_write_wait);
+-static DECLARE_WAIT_QUEUE_HEAD(urandom_init_wait);
+-static struct fasync_struct *fasync;
+-
+-static DEFINE_SPINLOCK(random_ready_list_lock);
+-static LIST_HEAD(random_ready_list);
++int __cold unregister_random_ready_notifier(struct notifier_block *nb)
++{
++	unsigned long flags;
++	int ret;
+ 
+-struct crng_state {
+-	__u32		state[16];
+-	unsigned long	init_time;
+-	spinlock_t	lock;
+-};
++	spin_lock_irqsave(&random_ready_chain_lock, flags);
++	ret = raw_notifier_chain_unregister(&random_ready_chain, nb);
++	spin_unlock_irqrestore(&random_ready_chain_lock, flags);
++	return ret;
++}
+ 
+-struct crng_state primary_crng = {
+-	.lock = __SPIN_LOCK_UNLOCKED(primary_crng.lock),
+-};
++static void __cold process_random_ready_list(void)
++{
++	unsigned long flags;
+ 
+-/*
+- * crng_init =  0 --> Uninitialized
+- *		1 --> Initialized
+- *		2 --> Initialized from input_pool
+- *
+- * crng_init is protected by primary_crng->lock, and only increases
+- * its value (from 0->1->2).
+- */
+-static int crng_init = 0;
+-#define crng_ready() (likely(crng_init > 1))
+-static int crng_init_cnt = 0;
+-static unsigned long crng_global_init_time = 0;
+-#define CRNG_INIT_CNT_THRESH (2*CHACHA20_KEY_SIZE)
+-static void _extract_crng(struct crng_state *crng,
+-			  __u8 out[CHACHA20_BLOCK_SIZE]);
+-static void _crng_backtrack_protect(struct crng_state *crng,
+-				    __u8 tmp[CHACHA20_BLOCK_SIZE], int used);
+-static void process_random_ready_list(void);
+-
+-static struct ratelimit_state unseeded_warning =
+-	RATELIMIT_STATE_INIT("warn_unseeded_randomness", HZ, 3);
+-static struct ratelimit_state urandom_warning =
+-	RATELIMIT_STATE_INIT("warn_urandom_randomness", HZ, 3);
++	spin_lock_irqsave(&random_ready_chain_lock, flags);
++	raw_notifier_call_chain(&random_ready_chain, 0, NULL);
++	spin_unlock_irqrestore(&random_ready_chain_lock, flags);
++}
+ 
+-static int ratelimit_disable __read_mostly;
++#define warn_unseeded_randomness() \
++	if (IS_ENABLED(CONFIG_WARN_ALL_UNSEEDED_RANDOM) && !crng_ready()) \
++		pr_notice("%s called from %pS with crng_init=%d\n", \
++			  __func__, (void *)_RET_IP_, crng_init)
+ 
+-module_param_named(ratelimit_disable, ratelimit_disable, int, 0644);
+-MODULE_PARM_DESC(ratelimit_disable, "Disable random ratelimit suppression");
+ 
+-/**********************************************************************
++/*********************************************************************
+  *
+- * OS independent entropy store.   Here are the functions which handle
+- * storing entropy in an entropy pool.
++ * Fast key erasure RNG, the "crng".
+  *
+- **********************************************************************/
++ * These functions expand entropy from the entropy extractor into
++ * long streams for external consumption using the "fast key erasure"
++ * RNG described at <https://blog.cr.yp.to/20170723-random.html>.
++ *
++ * There are a few exported interfaces for use by other drivers:
++ *
++ *	void get_random_bytes(void *buf, size_t len)
++ *	u32 get_random_u32()
++ *	u64 get_random_u64()
++ *	unsigned int get_random_int()
++ *	unsigned long get_random_long()
++ *
++ * These interfaces will return the requested number of random bytes
++ * into the given buffer or as a return value. This is equivalent to
++ * a read from /dev/urandom. The u32, u64, int, and long family of
++ * functions may be higher performance for one-off random integers,
++ * because they do a bit of buffering and do not invoke reseeding
++ * until the buffer is emptied.
++ *
++ *********************************************************************/
+ 
+-struct entropy_store;
+-struct entropy_store {
+-	/* read-only data: */
+-	const struct poolinfo *poolinfo;
+-	__u32 *pool;
+-	const char *name;
+-	struct entropy_store *pull;
+-	struct work_struct push_work;
+-
+-	/* read-write data: */
+-	unsigned long last_pulled;
+-	spinlock_t lock;
+-	unsigned short add_ptr;
+-	unsigned short input_rotate;
+-	int entropy_count;
+-	int entropy_total;
+-	unsigned int initialized:1;
+-	unsigned int limit:1;
+-	unsigned int last_data_init:1;
+-	__u8 last_data[EXTRACT_SIZE];
++enum {
++	CRNG_RESEED_START_INTERVAL = HZ,
++	CRNG_RESEED_INTERVAL = 60 * HZ
+ };
+ 
+-static ssize_t extract_entropy(struct entropy_store *r, void *buf,
+-			       size_t nbytes, int min, int rsvd);
+-static ssize_t _extract_entropy(struct entropy_store *r, void *buf,
+-				size_t nbytes, int fips);
+-
+-static void crng_reseed(struct crng_state *crng, struct entropy_store *r);
+-static void push_to_pool(struct work_struct *work);
+-static __u32 input_pool_data[INPUT_POOL_WORDS] __latent_entropy;
+-static __u32 blocking_pool_data[OUTPUT_POOL_WORDS] __latent_entropy;
+-
+-static struct entropy_store input_pool = {
+-	.poolinfo = &poolinfo_table[0],
+-	.name = "input",
+-	.limit = 1,
+-	.lock = __SPIN_LOCK_UNLOCKED(input_pool.lock),
+-	.pool = input_pool_data
++static struct {
++	u8 key[CHACHA20_KEY_SIZE] __aligned(__alignof__(long));
++	unsigned long birth;
++	unsigned long generation;
++	spinlock_t lock;
++} base_crng = {
++	.lock = __SPIN_LOCK_UNLOCKED(base_crng.lock)
+ };
+ 
+-static struct entropy_store blocking_pool = {
+-	.poolinfo = &poolinfo_table[1],
+-	.name = "blocking",
+-	.limit = 1,
+-	.pull = &input_pool,
+-	.lock = __SPIN_LOCK_UNLOCKED(blocking_pool.lock),
+-	.pool = blocking_pool_data,
+-	.push_work = __WORK_INITIALIZER(blocking_pool.push_work,
+-					push_to_pool),
++struct crng {
++	u8 key[CHACHA20_KEY_SIZE];
++	unsigned long generation;
+ };
+ 
+-static __u32 const twist_table[8] = {
+-	0x00000000, 0x3b6e20c8, 0x76dc4190, 0x4db26158,
+-	0xedb88320, 0xd6d6a3e8, 0x9b64c2b0, 0xa00ae278 };
+-
+-/*
+- * This function adds bytes into the entropy "pool".  It does not
+- * update the entropy estimate.  The caller should call
+- * credit_entropy_bits if this is appropriate.
+- *
+- * The pool is stirred with a primitive polynomial of the appropriate
+- * degree, and then twisted.  We twist by three bits at a time because
+- * it's cheap to do so and helps slightly in the expected case where
+- * the entropy is concentrated in the low-order bits.
+- */
+-static void _mix_pool_bytes(struct entropy_store *r, const void *in,
+-			    int nbytes)
+-{
+-	unsigned long i, tap1, tap2, tap3, tap4, tap5;
+-	int input_rotate;
+-	int wordmask = r->poolinfo->poolwords - 1;
+-	const char *bytes = in;
+-	__u32 w;
+-
+-	tap1 = r->poolinfo->tap1;
+-	tap2 = r->poolinfo->tap2;
+-	tap3 = r->poolinfo->tap3;
+-	tap4 = r->poolinfo->tap4;
+-	tap5 = r->poolinfo->tap5;
+-
+-	input_rotate = r->input_rotate;
+-	i = r->add_ptr;
+-
+-	/* mix one byte at a time to simplify size handling and churn faster */
+-	while (nbytes--) {
+-		w = rol32(*bytes++, input_rotate);
+-		i = (i - 1) & wordmask;
+-
+-		/* XOR in the various taps */
+-		w ^= r->pool[i];
+-		w ^= r->pool[(i + tap1) & wordmask];
+-		w ^= r->pool[(i + tap2) & wordmask];
+-		w ^= r->pool[(i + tap3) & wordmask];
+-		w ^= r->pool[(i + tap4) & wordmask];
+-		w ^= r->pool[(i + tap5) & wordmask];
+-
+-		/* Mix the result back in with a twist */
+-		r->pool[i] = (w >> 3) ^ twist_table[w & 7];
+-
+-		/*
+-		 * Normally, we add 7 bits of rotation to the pool.
+-		 * At the beginning of the pool, add an extra 7 bits
+-		 * rotation, so that successive passes spread the
+-		 * input bits across the pool evenly.
+-		 */
+-		input_rotate = (input_rotate + (i ? 7 : 14)) & 31;
+-	}
+-
+-	r->input_rotate = input_rotate;
+-	r->add_ptr = i;
+-}
++static DEFINE_PER_CPU(struct crng, crngs) = {
++	.generation = ULONG_MAX
++};
+ 
+-static void __mix_pool_bytes(struct entropy_store *r, const void *in,
+-			     int nbytes)
+-{
+-	trace_mix_pool_bytes_nolock(r->name, nbytes, _RET_IP_);
+-	_mix_pool_bytes(r, in, nbytes);
+-}
++/* 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 len);
+ 
+-static void mix_pool_bytes(struct entropy_store *r, const void *in,
+-			   int nbytes)
++/* This extracts a new crng key from the input pool. */
++static void crng_reseed(void)
+ {
+ 	unsigned long flags;
++	unsigned long next_gen;
++	u8 key[CHACHA20_KEY_SIZE];
+ 
+-	trace_mix_pool_bytes(r->name, nbytes, _RET_IP_);
+-	spin_lock_irqsave(&r->lock, flags);
+-	_mix_pool_bytes(r, in, nbytes);
+-	spin_unlock_irqrestore(&r->lock, flags);
+-}
++	extract_entropy(key, sizeof(key));
+ 
+-struct fast_pool {
+-	__u32		pool[4];
+-	unsigned long	last;
+-	unsigned short	reg_idx;
+-	unsigned char	count;
+-};
++	/*
++	 * We copy the new key into the base_crng, overwriting the old one,
++	 * and update the generation counter. We avoid hitting ULONG_MAX,
++	 * because the per-cpu crngs are initialized to ULONG_MAX, so this
++	 * forces new CPUs that come online to always initialize.
++	 */
++	spin_lock_irqsave(&base_crng.lock, flags);
++	memcpy(base_crng.key, key, sizeof(base_crng.key));
++	next_gen = base_crng.generation + 1;
++	if (next_gen == ULONG_MAX)
++		++next_gen;
++	WRITE_ONCE(base_crng.generation, next_gen);
++	WRITE_ONCE(base_crng.birth, jiffies);
++	if (!crng_ready())
++		crng_init = CRNG_READY;
++	spin_unlock_irqrestore(&base_crng.lock, flags);
++	memzero_explicit(key, sizeof(key));
++}
+ 
+ /*
+- * This is a fast mixing routine used by the interrupt randomness
+- * collector.  It's hardcoded for an 128 bit pool and assumes that any
+- * locks that might be needed are taken by the caller.
++ * This generates a ChaCha block using the provided key, and then
++ * immediately overwites that key with half the block. It returns
++ * the resultant ChaCha state to the user, along with the second
++ * half of the block containing 32 bytes of random data that may
++ * be used; random_data_len may not be greater than 32.
++ *
++ * The returned ChaCha state contains within it a copy of the old
++ * key value, at index 4, so the state should always be zeroed out
++ * immediately after using in order to maintain forward secrecy.
++ * If the state cannot be erased in a timely manner, then it is
++ * safer to set the random_data parameter to &chacha_state[4] so
++ * that this function overwrites it before returning.
+  */
+-static void fast_mix(struct fast_pool *f)
++static void crng_fast_key_erasure(u8 key[CHACHA20_KEY_SIZE],
++				  u32 chacha_state[CHACHA20_BLOCK_SIZE / sizeof(u32)],
++				  u8 *random_data, size_t random_data_len)
+ {
+-	__u32 a = f->pool[0],	b = f->pool[1];
+-	__u32 c = f->pool[2],	d = f->pool[3];
++	u8 first_block[CHACHA20_BLOCK_SIZE];
+ 
+-	a += b;			c += d;
+-	b = rol32(b, 6);	d = rol32(d, 27);
+-	d ^= a;			b ^= c;
++	BUG_ON(random_data_len > 32);
+ 
+-	a += b;			c += d;
+-	b = rol32(b, 16);	d = rol32(d, 14);
+-	d ^= a;			b ^= c;
++	chacha_init_consts(chacha_state);
++	memcpy(&chacha_state[4], key, CHACHA20_KEY_SIZE);
++	memset(&chacha_state[12], 0, sizeof(u32) * 4);
++	chacha20_block(chacha_state, first_block);
+ 
+-	a += b;			c += d;
+-	b = rol32(b, 6);	d = rol32(d, 27);
+-	d ^= a;			b ^= c;
+-
+-	a += b;			c += d;
+-	b = rol32(b, 16);	d = rol32(d, 14);
+-	d ^= a;			b ^= c;
+-
+-	f->pool[0] = a;  f->pool[1] = b;
+-	f->pool[2] = c;  f->pool[3] = d;
+-	f->count++;
++	memcpy(key, first_block, CHACHA20_KEY_SIZE);
++	memcpy(random_data, first_block + CHACHA20_KEY_SIZE, random_data_len);
++	memzero_explicit(first_block, sizeof(first_block));
+ }
+ 
+-static void process_random_ready_list(void)
++/*
++ * Return whether the crng seed is considered to be sufficiently old
++ * that a reseeding is needed. This happens if the last reseeding
++ * was CRNG_RESEED_INTERVAL ago, or during early boot, at an interval
++ * proportional to the uptime.
++ */
++static bool crng_has_old_seed(void)
+ {
+-	unsigned long flags;
+-	struct random_ready_callback *rdy, *tmp;
+-
+-	spin_lock_irqsave(&random_ready_list_lock, flags);
+-	list_for_each_entry_safe(rdy, tmp, &random_ready_list, list) {
+-		struct module *owner = rdy->owner;
+-
+-		list_del_init(&rdy->list);
+-		rdy->func(rdy);
+-		module_put(owner);
++	static bool early_boot = true;
++	unsigned long interval = CRNG_RESEED_INTERVAL;
++
++	if (unlikely(READ_ONCE(early_boot))) {
++		time64_t uptime = ktime_get_seconds();
++		if (uptime >= CRNG_RESEED_INTERVAL / HZ * 2)
++			WRITE_ONCE(early_boot, false);
++		else
++			interval = max_t(unsigned int, CRNG_RESEED_START_INTERVAL,
++					 (unsigned int)uptime / 2 * HZ);
+ 	}
+-	spin_unlock_irqrestore(&random_ready_list_lock, flags);
++	return time_is_before_jiffies(READ_ONCE(base_crng.birth) + interval);
+ }
+ 
+ /*
+- * Credit (or debit) the entropy store with n bits of entropy.
+- * Use credit_entropy_bits_safe() if the value comes from userspace
+- * or otherwise should be checked for extreme values.
++ * This function returns a ChaCha state that you may use for generating
++ * random data. It also returns up to 32 bytes on its own of random data
++ * that may be used; random_data_len may not be greater than 32.
+  */
+-static void credit_entropy_bits(struct entropy_store *r, int nbits)
++static void crng_make_state(u32 chacha_state[CHACHA20_BLOCK_SIZE / sizeof(u32)],
++			    u8 *random_data, size_t random_data_len)
+ {
+-	int entropy_count, orig;
+-	const int pool_size = r->poolinfo->poolfracbits;
+-	int nfrac = nbits << ENTROPY_SHIFT;
++	unsigned long flags;
++	struct crng *crng;
+ 
+-	if (!nbits)
+-		return;
++	BUG_ON(random_data_len > 32);
+ 
+-retry:
+-	entropy_count = orig = ACCESS_ONCE(r->entropy_count);
+-	if (nfrac < 0) {
+-		/* Debit */
+-		entropy_count += nfrac;
+-	} else {
+-		/*
+-		 * Credit: we have to account for the possibility of
+-		 * overwriting already present entropy.	 Even in the
+-		 * ideal case of pure Shannon entropy, new contributions
+-		 * approach the full value asymptotically:
+-		 *
+-		 * entropy <- entropy + (pool_size - entropy) *
+-		 *	(1 - exp(-add_entropy/pool_size))
+-		 *
+-		 * For add_entropy <= pool_size/2 then
+-		 * (1 - exp(-add_entropy/pool_size)) >=
+-		 *    (add_entropy/pool_size)*0.7869...
+-		 * so we can approximate the exponential with
+-		 * 3/4*add_entropy/pool_size and still be on the
+-		 * safe side by adding at most pool_size/2 at a time.
+-		 *
+-		 * The use of pool_size-2 in the while statement is to
+-		 * prevent rounding artifacts from making the loop
+-		 * arbitrarily long; this limits the loop to log2(pool_size)*2
+-		 * turns no matter how large nbits is.
+-		 */
+-		int pnfrac = nfrac;
+-		const int s = r->poolinfo->poolbitshift + ENTROPY_SHIFT + 2;
+-		/* The +2 corresponds to the /4 in the denominator */
+-
+-		do {
+-			unsigned int anfrac = min(pnfrac, pool_size/2);
+-			unsigned int add =
+-				((pool_size - entropy_count)*anfrac*3) >> s;
+-
+-			entropy_count += add;
+-			pnfrac -= anfrac;
+-		} while (unlikely(entropy_count < pool_size-2 && pnfrac));
+-	}
+-
+-	if (unlikely(entropy_count < 0)) {
+-		pr_warn("random: negative entropy/overflow: pool %s count %d\n",
+-			r->name, entropy_count);
+-		WARN_ON(1);
+-		entropy_count = 0;
+-	} else if (entropy_count > pool_size)
+-		entropy_count = pool_size;
+-	if (cmpxchg(&r->entropy_count, orig, entropy_count) != orig)
+-		goto retry;
+-
+-	r->entropy_total += nbits;
+-	if (!r->initialized && r->entropy_total > 128) {
+-		r->initialized = 1;
+-		r->entropy_total = 0;
++	/*
++	 * For the fast path, we check whether we're ready, unlocked first, and
++	 * then re-check once locked later. In the case where we're really not
++	 * ready, we do fast key erasure with the base_crng directly, extracting
++	 * when crng_init is CRNG_EMPTY.
++	 */
++	if (!crng_ready()) {
++		bool ready;
++
++		spin_lock_irqsave(&base_crng.lock, flags);
++		ready = crng_ready();
++		if (!ready) {
++			if (crng_init == CRNG_EMPTY)
++				extract_entropy(base_crng.key, sizeof(base_crng.key));
++			crng_fast_key_erasure(base_crng.key, chacha_state,
++					      random_data, random_data_len);
++		}
++		spin_unlock_irqrestore(&base_crng.lock, flags);
++		if (!ready)
++			return;
+ 	}
+ 
+-	trace_credit_entropy_bits(r->name, nbits,
+-				  entropy_count >> ENTROPY_SHIFT,
+-				  r->entropy_total, _RET_IP_);
+-
+-	if (r == &input_pool) {
+-		int entropy_bits = entropy_count >> ENTROPY_SHIFT;
++	/*
++	 * If the base_crng is old enough, we reseed, which in turn bumps the
++	 * generation counter that we check below.
++	 */
++	if (unlikely(crng_has_old_seed()))
++		crng_reseed();
+ 
+-		if (crng_init < 2 && entropy_bits >= 128) {
+-			crng_reseed(&primary_crng, r);
+-			entropy_bits = r->entropy_count >> ENTROPY_SHIFT;
+-		}
++	local_irq_save(flags);
++	crng = raw_cpu_ptr(&crngs);
+ 
+-		/* should we wake readers? */
+-		if (entropy_bits >= random_read_wakeup_bits) {
+-			wake_up_interruptible(&random_read_wait);
+-			kill_fasync(&fasync, SIGIO, POLL_IN);
+-		}
+-		/* If the input pool is getting full, send some
+-		 * entropy to the blocking pool until it is 75% full.
+-		 */
+-		if (entropy_bits > random_write_wakeup_bits &&
+-		    r->initialized &&
+-		    r->entropy_total >= 2*random_read_wakeup_bits) {
+-			struct entropy_store *other = &blocking_pool;
+-
+-			if (other->entropy_count <=
+-			    3 * other->poolinfo->poolfracbits / 4) {
+-				schedule_work(&other->push_work);
+-				r->entropy_total = 0;
+-			}
+-		}
++	/*
++	 * If our per-cpu crng is older than the base_crng, then it means
++	 * somebody reseeded the base_crng. In that case, we do fast key
++	 * erasure on the base_crng, and use its output as the new key
++	 * for our per-cpu crng. This brings us up to date with base_crng.
++	 */
++	if (unlikely(crng->generation != READ_ONCE(base_crng.generation))) {
++		spin_lock(&base_crng.lock);
++		crng_fast_key_erasure(base_crng.key, chacha_state,
++				      crng->key, sizeof(crng->key));
++		crng->generation = base_crng.generation;
++		spin_unlock(&base_crng.lock);
+ 	}
++
++	/*
++	 * Finally, when we've made it this far, our per-cpu crng has an up
++	 * to date key, and we can do fast key erasure with it to produce
++	 * some random data and a ChaCha state for the caller. All other
++	 * branches of this function are "unlikely", so most of the time we
++	 * should wind up here immediately.
++	 */
++	crng_fast_key_erasure(crng->key, chacha_state, random_data, random_data_len);
++	local_irq_restore(flags);
+ }
+ 
+-static int credit_entropy_bits_safe(struct entropy_store *r, int nbits)
++static void _get_random_bytes(void *buf, size_t len)
+ {
+-	const int nbits_max = r->poolinfo->poolwords * 32;
++	u32 chacha_state[CHACHA20_BLOCK_SIZE / sizeof(u32)];
++	u8 tmp[CHACHA20_BLOCK_SIZE];
++	size_t first_block_len;
+ 
+-	if (nbits < 0)
+-		return -EINVAL;
+-
+-	/* Cap the value to avoid overflows */
+-	nbits = min(nbits,  nbits_max);
++	if (!len)
++		return;
+ 
+-	credit_entropy_bits(r, nbits);
+-	return 0;
+-}
++	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;
+ 
+-/*********************************************************************
+- *
+- * CRNG using CHACHA20
+- *
+- *********************************************************************/
++	while (len) {
++		if (len < CHACHA20_BLOCK_SIZE) {
++			chacha20_block(chacha_state, tmp);
++			memcpy(buf, tmp, len);
++			memzero_explicit(tmp, sizeof(tmp));
++			break;
++		}
+ 
+-#define CRNG_RESEED_INTERVAL (300*HZ)
++		chacha20_block(chacha_state, buf);
++		if (unlikely(chacha_state[12] == 0))
++			++chacha_state[13];
++		len -= CHACHA20_BLOCK_SIZE;
++		buf += CHACHA20_BLOCK_SIZE;
++	}
+ 
+-static DECLARE_WAIT_QUEUE_HEAD(crng_init_wait);
++	memzero_explicit(chacha_state, sizeof(chacha_state));
++}
+ 
+-#ifdef CONFIG_NUMA
+ /*
+- * Hack to deal with crazy userspace progams when they are all trying
+- * to access /dev/urandom in parallel.  The programs are almost
+- * certainly doing something terribly wrong, but we'll work around
+- * their brain damage.
++ * This function is the exported kernel interface.  It returns some
++ * number of good random numbers, suitable for key generation, seeding
++ * TCP sequence numbers, etc.  It does not rely on the hardware random
++ * number generator.  For random bytes direct from the hardware RNG
++ * (when available), use get_random_bytes_arch(). In order to ensure
++ * that the randomness 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.
+  */
+-static struct crng_state **crng_node_pool __read_mostly;
+-#endif
+-
+-static void crng_initialize(struct crng_state *crng)
++void get_random_bytes(void *buf, size_t len)
+ {
+-	int		i;
+-	unsigned long	rv;
+-
+-	memcpy(&crng->state[0], "expand 32-byte k", 16);
+-	if (crng == &primary_crng)
+-		_extract_entropy(&input_pool, &crng->state[4],
+-				 sizeof(__u32) * 12, 0);
+-	else
+-		get_random_bytes(&crng->state[4], sizeof(__u32) * 12);
+-	for (i = 4; i < 16; i++) {
+-		if (!arch_get_random_seed_long(&rv) &&
+-		    !arch_get_random_long(&rv))
+-			rv = random_get_entropy();
+-		crng->state[i] ^= rv;
+-	}
+-	crng->init_time = jiffies - CRNG_RESEED_INTERVAL - 1;
++	warn_unseeded_randomness();
++	_get_random_bytes(buf, len);
+ }
++EXPORT_SYMBOL(get_random_bytes);
+ 
+-static int crng_fast_load(const char *cp, size_t len)
++static ssize_t get_random_bytes_user(struct iov_iter *iter)
+ {
+-	unsigned long flags;
+-	char *p;
++	u32 chacha_state[CHACHA20_BLOCK_SIZE / sizeof(u32)];
++	u8 block[CHACHA20_BLOCK_SIZE];
++	size_t ret = 0, copied;
+ 
+-	if (!spin_trylock_irqsave(&primary_crng.lock, flags))
++	if (unlikely(!iov_iter_count(iter)))
+ 		return 0;
+-	if (crng_init != 0) {
+-		spin_unlock_irqrestore(&primary_crng.lock, flags);
+-		return 0;
+-	}
+-	p = (unsigned char *) &primary_crng.state[4];
+-	while (len > 0 && crng_init_cnt < CRNG_INIT_CNT_THRESH) {
+-		p[crng_init_cnt % CHACHA20_KEY_SIZE] ^= *cp;
+-		cp++; crng_init_cnt++; len--;
+-	}
+-	if (crng_init_cnt >= CRNG_INIT_CNT_THRESH) {
+-		crng_init = 1;
+-		wake_up_interruptible(&crng_init_wait);
+-		pr_notice("random: fast init done\n");
+-	}
+-	spin_unlock_irqrestore(&primary_crng.lock, flags);
+-	return 1;
+-}
+ 
+-#ifdef CONFIG_NUMA
+-static void do_numa_crng_init(struct work_struct *work)
+-{
+-	int i;
+-	struct crng_state *crng;
+-	struct crng_state **pool;
+-
+-	pool = kcalloc(nr_node_ids, sizeof(*pool), GFP_KERNEL|__GFP_NOFAIL);
+-	for_each_online_node(i) {
+-		crng = kmalloc_node(sizeof(struct crng_state),
+-				    GFP_KERNEL | __GFP_NOFAIL, i);
+-		spin_lock_init(&crng->lock);
+-		crng_initialize(crng);
+-		pool[i] = crng;
+-	}
+-	/* pairs with READ_ONCE() in select_crng() */
+-	if (cmpxchg_release(&crng_node_pool, NULL, pool) != NULL) {
+-		for_each_node(i)
+-			kfree(pool[i]);
+-		kfree(pool);
++	/*
++	 * Immediately overwrite the ChaCha key at index 4 with random
++	 * bytes, in case userspace causes copy_to_user() below to sleep
++	 * forever, so that we still retain forward secrecy in that case.
++	 */
++	crng_make_state(chacha_state, (u8 *)&chacha_state[4], CHACHA20_KEY_SIZE);
++	/*
++	 * However, if we're doing a read of len <= 32, we don't need to
++	 * use chacha_state after, so we can simply return those bytes to
++	 * the user directly.
++	 */
++	if (iov_iter_count(iter) <= CHACHA20_KEY_SIZE) {
++		ret = copy_to_iter(&chacha_state[4], CHACHA20_KEY_SIZE, iter);
++		goto out_zero_chacha;
+ 	}
+-}
+-
+-static DECLARE_WORK(numa_crng_init_work, do_numa_crng_init);
+-
+-static void numa_crng_init(void)
+-{
+-	schedule_work(&numa_crng_init_work);
+-}
+ 
+-static struct crng_state *select_crng(void)
+-{
+-	struct crng_state **pool;
+-	int nid = numa_node_id();
+-
+-	/* pairs with cmpxchg_release() in do_numa_crng_init() */
+-	pool = READ_ONCE(crng_node_pool);
+-	if (pool && pool[nid])
+-		return pool[nid];
++	for (;;) {
++		chacha20_block(chacha_state, block);
++		if (unlikely(chacha_state[12] == 0))
++			++chacha_state[13];
+ 
+-	return &primary_crng;
+-}
+-#else
+-static void numa_crng_init(void) {}
+-
+-static struct crng_state *select_crng(void)
+-{
+-	return &primary_crng;
+-}
+-#endif
++		copied = copy_to_iter(block, sizeof(block), iter);
++		ret += copied;
++		if (!iov_iter_count(iter) || copied != sizeof(block))
++			break;
+ 
+-static void crng_reseed(struct crng_state *crng, struct entropy_store *r)
+-{
+-	unsigned long	flags;
+-	int		i, num;
+-	union {
+-		__u8	block[CHACHA20_BLOCK_SIZE];
+-		__u32	key[8];
+-	} buf;
+-
+-	if (r) {
+-		num = extract_entropy(r, &buf, 32, 16, 0);
+-		if (num == 0)
+-			return;
+-	} else {
+-		_extract_crng(&primary_crng, buf.block);
+-		_crng_backtrack_protect(&primary_crng, buf.block,
+-					CHACHA20_KEY_SIZE);
+-	}
+-	spin_lock_irqsave(&crng->lock, flags);
+-	for (i = 0; i < 8; i++) {
+-		unsigned long	rv;
+-		if (!arch_get_random_seed_long(&rv) &&
+-		    !arch_get_random_long(&rv))
+-			rv = random_get_entropy();
+-		crng->state[i+4] ^= buf.key[i] ^ rv;
+-	}
+-	memzero_explicit(&buf, sizeof(buf));
+-	WRITE_ONCE(crng->init_time, jiffies);
+-	if (crng == &primary_crng && crng_init < 2) {
+-		numa_crng_init();
+-		crng_init = 2;
+-		process_random_ready_list();
+-		wake_up_interruptible(&crng_init_wait);
+-		pr_notice("random: crng init done\n");
+-		if (unseeded_warning.missed) {
+-			pr_notice("random: %d get_random_xx warning(s) missed "
+-				  "due to ratelimiting\n",
+-				  unseeded_warning.missed);
+-			unseeded_warning.missed = 0;
+-		}
+-		if (urandom_warning.missed) {
+-			pr_notice("random: %d urandom warning(s) missed "
+-				  "due to ratelimiting\n",
+-				  urandom_warning.missed);
+-			urandom_warning.missed = 0;
++		BUILD_BUG_ON(PAGE_SIZE % sizeof(block) != 0);
++		if (ret % PAGE_SIZE == 0) {
++			if (signal_pending(current))
++				break;
++			cond_resched();
+ 		}
+ 	}
+-	spin_unlock_irqrestore(&crng->lock, flags);
+-}
+ 
+-static inline void maybe_reseed_primary_crng(void)
+-{
+-	if (crng_init > 2 &&
+-	    time_after(jiffies, primary_crng.init_time + CRNG_RESEED_INTERVAL))
+-		crng_reseed(&primary_crng, &input_pool);
++	memzero_explicit(block, sizeof(block));
++out_zero_chacha:
++	memzero_explicit(chacha_state, sizeof(chacha_state));
++	return ret ? ret : -EFAULT;
+ }
+ 
+-static inline void crng_wait_ready(void)
+-{
+-	wait_event_interruptible(crng_init_wait, crng_ready());
+-}
+-
+-static void _extract_crng(struct crng_state *crng,
+-			  __u8 out[CHACHA20_BLOCK_SIZE])
+-{
+-	unsigned long v, flags, init_time;
+-
+-	if (crng_ready()) {
+-		init_time = READ_ONCE(crng->init_time);
+-		if (time_after(READ_ONCE(crng_global_init_time), init_time) ||
+-		    time_after(jiffies, init_time + CRNG_RESEED_INTERVAL))
+-			crng_reseed(crng, crng == &primary_crng ?
+-				    &input_pool : NULL);
+-	}
+-	spin_lock_irqsave(&crng->lock, flags);
+-	if (arch_get_random_long(&v))
+-		crng->state[14] ^= v;
+-	chacha20_block(&crng->state[0], out);
+-	if (crng->state[12] == 0)
+-		crng->state[13]++;
+-	spin_unlock_irqrestore(&crng->lock, flags);
+-}
+-
+-static void extract_crng(__u8 out[CHACHA20_BLOCK_SIZE])
+-{
+-	_extract_crng(select_crng(), out);
+-}
++/*
++ * Batched entropy returns random integers. The quality of the random
++ * number is good as /dev/urandom. In order to ensure that the randomness
++ * 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.
++ */
+ 
++#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) * CHACHA20_BLOCK_SIZE.		\
++	 */									\
++	type entropy[CHACHA20_BLOCK_SIZE * 3 / (2 * sizeof(type))];		\
++	unsigned long generation;						\
++	unsigned int position;							\
++};										\
++										\
++static DEFINE_PER_CPU(struct batch_ ##type, batched_entropy_ ##type) = {	\
++	.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_irq_save(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_irq_restore(flags);		\
++	return ret;								\
++}										\
++EXPORT_SYMBOL(get_random_ ##type);
++
++DEFINE_BATCHED_ENTROPY(u64)
++DEFINE_BATCHED_ENTROPY(u32)
++
++#ifdef CONFIG_SMP
+ /*
+- * Use the leftover bytes from the CRNG block output (if there is
+- * enough) to mutate the CRNG key to provide backtracking protection.
++ * This function is called when the CPU is coming up, with entry
++ * CPUHP_RANDOM_PREPARE, which comes before CPUHP_WORKQUEUE_PREP.
+  */
+-static void _crng_backtrack_protect(struct crng_state *crng,
+-				    __u8 tmp[CHACHA20_BLOCK_SIZE], int used)
++int __cold random_prepare_cpu(unsigned int cpu)
+ {
+-	unsigned long	flags;
+-	__u32		*s, *d;
+-	int		i;
+-
+-	used = round_up(used, sizeof(__u32));
+-	if (used + CHACHA20_KEY_SIZE > CHACHA20_BLOCK_SIZE) {
+-		extract_crng(tmp);
+-		used = 0;
+-	}
+-	spin_lock_irqsave(&crng->lock, flags);
+-	s = (__u32 *) &tmp[used];
+-	d = &crng->state[4];
+-	for (i=0; i < 8; i++)
+-		*d++ ^= *s++;
+-	spin_unlock_irqrestore(&crng->lock, flags);
++	/*
++	 * When the cpu comes back online, immediately invalidate both
++	 * the per-cpu crng and all batches, so that we serve fresh
++	 * randomness.
++	 */
++	per_cpu_ptr(&crngs, cpu)->generation = ULONG_MAX;
++	per_cpu_ptr(&batched_entropy_u32, cpu)->position = UINT_MAX;
++	per_cpu_ptr(&batched_entropy_u64, cpu)->position = UINT_MAX;
++	return 0;
+ }
++#endif
+ 
+-static void crng_backtrack_protect(__u8 tmp[CHACHA20_BLOCK_SIZE], int used)
++/*
++ * This function will use the architecture-specific hardware random
++ * number generator if it is available. It is not recommended for
++ * 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 len)
+ {
+-	_crng_backtrack_protect(select_crng(), tmp, used);
+-}
++	size_t left = len;
++	u8 *p = buf;
+ 
+-static ssize_t extract_crng_user(void __user *buf, size_t nbytes)
+-{
+-	ssize_t ret = 0, i = CHACHA20_BLOCK_SIZE;
+-	__u8 tmp[CHACHA20_BLOCK_SIZE];
+-	int large_request = (nbytes > 256);
+-
+-	while (nbytes) {
+-		if (large_request && need_resched()) {
+-			if (signal_pending(current)) {
+-				if (ret == 0)
+-					ret = -ERESTARTSYS;
+-				break;
+-			}
+-			schedule();
+-		}
++	while (left) {
++		unsigned long v;
++		size_t block_len = min_t(size_t, left, sizeof(unsigned long));
+ 
+-		extract_crng(tmp);
+-		i = min_t(int, nbytes, CHACHA20_BLOCK_SIZE);
+-		if (copy_to_user(buf, tmp, i)) {
+-			ret = -EFAULT;
++		if (!arch_get_random_long(&v))
+ 			break;
+-		}
+ 
+-		nbytes -= i;
+-		buf += i;
+-		ret += i;
++		memcpy(p, &v, block_len);
++		p += block_len;
++		left -= block_len;
+ 	}
+-	crng_backtrack_protect(tmp, i);
+-
+-	/* Wipe data just written to memory */
+-	memzero_explicit(tmp, sizeof(tmp));
+ 
+-	return ret;
++	return len - left;
+ }
++EXPORT_SYMBOL(get_random_bytes_arch);
+ 
+ 
+-/*********************************************************************
++/**********************************************************************
+  *
+- * Entropy input management
++ * Entropy accumulation and extraction routines.
+  *
+- *********************************************************************/
++ * Callers may add entropy via:
++ *
++ *     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 bits)
++ *
++ * Finally, extract entropy via:
++ *
++ *     static void extract_entropy(void *buf, size_t len)
++ *
++ **********************************************************************/
+ 
+-/* There is one of these per entropy source */
+-struct timer_rand_state {
+-	cycles_t last_time;
+-	long last_delta, last_delta2;
+-	unsigned dont_count_entropy:1;
++enum {
++	POOL_BITS = BLAKE2S_HASH_SIZE * 8,
++	POOL_READY_BITS = POOL_BITS, /* When crng_init->CRNG_READY */
++	POOL_EARLY_BITS = POOL_READY_BITS / 2 /* When crng_init->CRNG_EARLY */
++};
++
++static struct {
++	struct blake2s_state hash;
++	spinlock_t lock;
++	unsigned int init_bits;
++} input_pool = {
++	.hash.h = { BLAKE2S_IV0 ^ (0x01010000 | BLAKE2S_HASH_SIZE),
++		    BLAKE2S_IV1, BLAKE2S_IV2, BLAKE2S_IV3, BLAKE2S_IV4,
++		    BLAKE2S_IV5, BLAKE2S_IV6, BLAKE2S_IV7 },
++	.hash.outlen = BLAKE2S_HASH_SIZE,
++	.lock = __SPIN_LOCK_UNLOCKED(input_pool.lock),
+ };
+ 
+-#define INIT_TIMER_RAND_STATE { INITIAL_JIFFIES, };
++static void _mix_pool_bytes(const void *buf, size_t len)
++{
++	blake2s_update(&input_pool.hash, buf, len);
++}
+ 
+ /*
+- * Add device- or boot-specific data to the input pool to help
+- * initialize it.
+- *
+- * None of this adds any entropy; it is meant to avoid the problem of
+- * the entropy pool having similar initial state across largely
+- * identical devices.
++ * This function adds bytes into the input pool. It does not
++ * update the initialization bit counter; the caller should call
++ * credit_init_bits if this is appropriate.
+  */
+-void add_device_randomness(const void *buf, unsigned int size)
++static void mix_pool_bytes(const void *buf, size_t len)
+ {
+-	unsigned long time = random_get_entropy() ^ jiffies;
+ 	unsigned long flags;
+ 
+-	trace_add_device_randomness(size, _RET_IP_);
+ 	spin_lock_irqsave(&input_pool.lock, flags);
+-	_mix_pool_bytes(&input_pool, buf, size);
+-	_mix_pool_bytes(&input_pool, &time, sizeof(time));
++	_mix_pool_bytes(buf, len);
+ 	spin_unlock_irqrestore(&input_pool.lock, flags);
+ }
+-EXPORT_SYMBOL(add_device_randomness);
+-
+-static struct timer_rand_state input_timer_state = INIT_TIMER_RAND_STATE;
+ 
+ /*
+- * This function adds entropy to the entropy "pool" by using timing
+- * delays.  It uses the timer_rand_state structure to make an estimate
+- * of how many bits of entropy this call has added to the pool.
+- *
+- * The number "num" is also added to the pool - it should somehow describe
+- * the type of event which just happened.  This is currently 0-255 for
+- * keyboard scan codes, and 256 upwards for interrupts.
+- *
++ * 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 add_timer_randomness(struct timer_rand_state *state, unsigned num)
++static void extract_entropy(void *buf, size_t len)
+ {
+-	struct entropy_store	*r;
++	unsigned long flags;
++	u8 seed[BLAKE2S_HASH_SIZE], next_key[BLAKE2S_HASH_SIZE];
+ 	struct {
+-		long jiffies;
+-		unsigned cycles;
+-		unsigned num;
+-	} sample;
+-	long delta, delta2, delta3;
+-
+-	preempt_disable();
+-
+-	sample.jiffies = jiffies;
+-	sample.cycles = random_get_entropy();
+-	sample.num = num;
+-	r = &input_pool;
+-	mix_pool_bytes(r, &sample, sizeof(sample));
+-
+-	/*
+-	 * Calculate number of bits of randomness we probably added.
+-	 * We take into account the first, second and third-order deltas
+-	 * in order to make our estimate.
+-	 */
+-
+-	if (!state->dont_count_entropy) {
+-		delta = sample.jiffies - state->last_time;
+-		state->last_time = sample.jiffies;
+-
+-		delta2 = delta - state->last_delta;
+-		state->last_delta = delta;
+-
+-		delta3 = delta2 - state->last_delta2;
+-		state->last_delta2 = delta2;
+-
+-		if (delta < 0)
+-			delta = -delta;
+-		if (delta2 < 0)
+-			delta2 = -delta2;
+-		if (delta3 < 0)
+-			delta3 = -delta3;
+-		if (delta > delta2)
+-			delta = delta2;
+-		if (delta > delta3)
+-			delta = delta3;
+-
+-		/*
+-		 * delta is now minimum absolute delta.
+-		 * Round down by 1 bit on general principles,
+-		 * and limit entropy entimate to 12 bits.
+-		 */
+-		credit_entropy_bits(r, min_t(int, fls(delta>>1), 11));
++		unsigned long rdseed[32 / sizeof(long)];
++		size_t counter;
++	} block;
++	size_t i;
++
++	for (i = 0; i < ARRAY_SIZE(block.rdseed); ++i) {
++		if (!arch_get_random_seed_long(&block.rdseed[i]) &&
++		    !arch_get_random_long(&block.rdseed[i]))
++			block.rdseed[i] = random_get_entropy();
+ 	}
+-	preempt_enable();
+-}
+-
+-void add_input_randomness(unsigned int type, unsigned int code,
+-				 unsigned int value)
+-{
+-	static unsigned char last_value;
+ 
+-	/* ignore autorepeat and the like */
+-	if (value == last_value)
+-		return;
+-
+-	last_value = value;
+-	add_timer_randomness(&input_timer_state,
+-			     (type << 4) ^ code ^ (code >> 4) ^ value);
+-	trace_add_input_randomness(ENTROPY_BITS(&input_pool));
+-}
+-EXPORT_SYMBOL_GPL(add_input_randomness);
++	spin_lock_irqsave(&input_pool.lock, flags);
+ 
+-static DEFINE_PER_CPU(struct fast_pool, irq_randomness);
++	/* seed = HASHPRF(last_key, entropy_input) */
++	blake2s_final(&input_pool.hash, seed);
+ 
+-#ifdef ADD_INTERRUPT_BENCH
+-static unsigned long avg_cycles, avg_deviation;
++	/* next_key = HASHPRF(seed, RDSEED || 0) */
++	block.counter = 0;
++	blake2s(next_key, (u8 *)&block, seed, sizeof(next_key), sizeof(block), sizeof(seed));
++	blake2s_init_key(&input_pool.hash, BLAKE2S_HASH_SIZE, next_key, sizeof(next_key));
+ 
+-#define AVG_SHIFT 8     /* Exponential average factor k=1/256 */
+-#define FIXED_1_2 (1 << (AVG_SHIFT-1))
++	spin_unlock_irqrestore(&input_pool.lock, flags);
++	memzero_explicit(next_key, sizeof(next_key));
++
++	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));
++		len -= i;
++		buf += i;
++	}
+ 
+-static void add_interrupt_bench(cycles_t start)
+-{
+-        long delta = random_get_entropy() - start;
+-
+-        /* Use a weighted moving average */
+-        delta = delta - ((avg_cycles + FIXED_1_2) >> AVG_SHIFT);
+-        avg_cycles += delta;
+-        /* And average deviation */
+-        delta = abs(delta) - ((avg_deviation + FIXED_1_2) >> AVG_SHIFT);
+-        avg_deviation += delta;
++	memzero_explicit(seed, sizeof(seed));
++	memzero_explicit(&block, sizeof(block));
+ }
+-#else
+-#define add_interrupt_bench(x)
+-#endif
+ 
+-static __u32 get_reg(struct fast_pool *f, struct pt_regs *regs)
+-{
+-	__u32 *ptr = (__u32 *) regs;
+-	unsigned int idx;
+-
+-	if (regs == NULL)
+-		return 0;
+-	idx = READ_ONCE(f->reg_idx);
+-	if (idx >= sizeof(struct pt_regs) / sizeof(__u32))
+-		idx = 0;
+-	ptr += idx++;
+-	WRITE_ONCE(f->reg_idx, idx);
+-	return *ptr;
+-}
++#define credit_init_bits(bits) if (!crng_ready()) _credit_init_bits(bits)
+ 
+-void add_interrupt_randomness(int irq, int irq_flags)
++static void __cold _credit_init_bits(size_t bits)
+ {
+-	struct entropy_store	*r;
+-	struct fast_pool	*fast_pool = this_cpu_ptr(&irq_randomness);
+-	struct pt_regs		*regs = get_irq_regs();
+-	unsigned long		now = jiffies;
+-	cycles_t		cycles = random_get_entropy();
+-	__u32			c_high, j_high;
+-	__u64			ip;
+-	unsigned long		seed;
+-	int			credit = 0;
+-
+-	if (cycles == 0)
+-		cycles = get_reg(fast_pool, regs);
+-	c_high = (sizeof(cycles) > 4) ? cycles >> 32 : 0;
+-	j_high = (sizeof(now) > 4) ? now >> 32 : 0;
+-	fast_pool->pool[0] ^= cycles ^ j_high ^ irq;
+-	fast_pool->pool[1] ^= now ^ c_high;
+-	ip = regs ? instruction_pointer(regs) : _RET_IP_;
+-	fast_pool->pool[2] ^= ip;
+-	fast_pool->pool[3] ^= (sizeof(ip) > 4) ? ip >> 32 :
+-		get_reg(fast_pool, regs);
+-
+-	fast_mix(fast_pool);
+-	add_interrupt_bench(cycles);
+-
+-	if (unlikely(crng_init == 0)) {
+-		if ((fast_pool->count >= 64) &&
+-		    crng_fast_load((char *) fast_pool->pool,
+-				   sizeof(fast_pool->pool))) {
+-			fast_pool->count = 0;
+-			fast_pool->last = now;
+-		}
+-		return;
+-	}
++	unsigned int new, orig, add;
++	unsigned long flags;
+ 
+-	if ((fast_pool->count < 64) &&
+-	    !time_after(now, fast_pool->last + HZ))
++	if (!bits)
+ 		return;
+ 
+-	r = &input_pool;
+-	if (!spin_trylock(&r->lock))
+-		return;
++	add = min_t(size_t, bits, POOL_BITS);
+ 
+-	fast_pool->last = now;
+-	__mix_pool_bytes(r, &fast_pool->pool, sizeof(fast_pool->pool));
++	do {
++		orig = READ_ONCE(input_pool.init_bits);
++		new = min_t(unsigned int, POOL_BITS, orig + add);
++	} while (cmpxchg(&input_pool.init_bits, orig, new) != orig);
+ 
+-	/*
+-	 * If we have architectural seed generator, produce a seed and
+-	 * add it to the pool.  For the sake of paranoia don't let the
+-	 * architectural seed generator dominate the input from the
+-	 * interrupt noise.
+-	 */
+-	if (arch_get_random_seed_long(&seed)) {
+-		__mix_pool_bytes(r, &seed, sizeof(seed));
+-		credit = 1;
++	if (orig < POOL_READY_BITS && new >= POOL_READY_BITS) {
++		crng_reseed(); /* Sets crng_init to CRNG_READY under base_crng.lock. */
++		process_random_ready_list();
++		wake_up_interruptible(&crng_init_wait);
++		kill_fasync(&fasync, SIGIO, POLL_IN);
++		pr_notice("crng init done\n");
++		if (urandom_warning.missed)
++			pr_notice("%d urandom warning(s) missed due to ratelimiting\n",
++				  urandom_warning.missed);
++	} else if (orig < POOL_EARLY_BITS && new >= POOL_EARLY_BITS) {
++		spin_lock_irqsave(&base_crng.lock, flags);
++		/* Check if crng_init is CRNG_EMPTY, to avoid race with crng_reseed(). */
++		if (crng_init == CRNG_EMPTY) {
++			extract_entropy(base_crng.key, sizeof(base_crng.key));
++			crng_init = CRNG_EARLY;
++		}
++		spin_unlock_irqrestore(&base_crng.lock, flags);
+ 	}
+-	spin_unlock(&r->lock);
+-
+-	fast_pool->count = 0;
+-
+-	/* award one bit for the contents of the fast pool */
+-	credit_entropy_bits(r, credit + 1);
+ }
+-EXPORT_SYMBOL_GPL(add_interrupt_randomness);
+ 
+-#ifdef CONFIG_BLOCK
+-void add_disk_randomness(struct gendisk *disk)
+-{
+-	if (!disk || !disk->random)
+-		return;
+-	/* first major is 1, so we get >= 0x200 here */
+-	add_timer_randomness(disk->random, 0x100 + disk_devt(disk));
+-	trace_add_disk_randomness(disk_devt(disk), ENTROPY_BITS(&input_pool));
+-}
+-EXPORT_SYMBOL_GPL(add_disk_randomness);
+-#endif
+ 
+-/*********************************************************************
++/**********************************************************************
+  *
+- * Entropy extraction routines
++ * Entropy collection routines.
+  *
+- *********************************************************************/
+-
+-/*
+- * This utility inline function is responsible for transferring entropy
+- * from the primary pool to the secondary extraction pool. We make
+- * sure we pull enough for a 'catastrophic reseed'.
+- */
+-static void _xfer_secondary_pool(struct entropy_store *r, size_t nbytes);
+-static void xfer_secondary_pool(struct entropy_store *r, size_t nbytes)
+-{
+-	if (!r->pull ||
+-	    r->entropy_count >= (nbytes << (ENTROPY_SHIFT + 3)) ||
+-	    r->entropy_count > r->poolinfo->poolfracbits)
+-		return;
+-
+-	if (r->limit == 0 && random_min_urandom_seed) {
+-		unsigned long now = jiffies;
+-
+-		if (time_before(now,
+-				r->last_pulled + random_min_urandom_seed * HZ))
+-			return;
+-		r->last_pulled = now;
+-	}
+-
+-	_xfer_secondary_pool(r, nbytes);
+-}
+-
+-static void _xfer_secondary_pool(struct entropy_store *r, size_t nbytes)
+-{
+-	__u32	tmp[OUTPUT_POOL_WORDS];
+-
+-	/* For /dev/random's pool, always leave two wakeups' worth */
+-	int rsvd_bytes = r->limit ? 0 : random_read_wakeup_bits / 4;
+-	int bytes = nbytes;
+-
+-	/* pull at least as much as a wakeup */
+-	bytes = max_t(int, bytes, random_read_wakeup_bits / 8);
+-	/* but never more than the buffer size */
+-	bytes = min_t(int, bytes, sizeof(tmp));
+-
+-	trace_xfer_secondary_pool(r->name, bytes * 8, nbytes * 8,
+-				  ENTROPY_BITS(r), ENTROPY_BITS(r->pull));
+-	bytes = extract_entropy(r->pull, tmp, bytes,
+-				random_read_wakeup_bits / 8, rsvd_bytes);
+-	mix_pool_bytes(r, tmp, bytes);
+-	credit_entropy_bits(r, bytes*8);
+-}
++ * The following exported functions are used for pushing entropy into
++ * the above entropy accumulation routines:
++ *
++ *	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_disk_randomness(struct gendisk *disk);
++ *
++ * add_device_randomness() adds data to the input pool that
++ * is likely to differ between two devices (or possibly even per boot).
++ * This would be things like MAC addresses or serial numbers, or the
++ * read-out of the RTC. This does *not* credit any actual entropy to
++ * the pool, but it initializes the pool to different values for devices
++ * that might otherwise be identical and have very little entropy
++ * available to them (particularly common in the embedded world).
++ *
++ * add_hwgenerator_randomness() is for true hardware RNGs, and will credit
++ * entropy as specified by the caller. If the entropy pool is full it will
++ * block until more entropy is needed.
++ *
++ * add_bootloader_randomness() is called by bootloader drivers, such as EFI
++ * and device tree, and credits its input depending on whether or not the
++ * configuration option CONFIG_RANDOM_TRUST_BOOTLOADER is set.
++ *
++ * add_interrupt_randomness() uses the interrupt timing as random
++ * inputs to the entropy pool. Using the cycle counters and the irq source
++ * as inputs, it feeds the input pool roughly once a second or after 64
++ * interrupts, crediting 1 bit of entropy for whichever comes first.
++ *
++ * add_input_randomness() uses the input layer interrupt timing, as well
++ * as the event type information from the hardware.
++ *
++ * add_disk_randomness() uses what amounts to the seek time of block
++ * layer request events, on a per-disk_devt basis, as input to the
++ * entropy pool. Note that high-speed solid state drives with very low
++ * seek times do not make for good sources of entropy, as their seek
++ * times are usually fairly consistent.
++ *
++ * The last two routines try to estimate how many bits of entropy
++ * to credit. They do this by keeping track of the first and second
++ * order deltas of the event timings.
++ *
++ **********************************************************************/
+ 
+-/*
+- * Used as a workqueue function so that when the input pool is getting
+- * full, we can "spill over" some entropy to the output pools.  That
+- * way the output pools can store some of the excess entropy instead
+- * of letting it go to waste.
+- */
+-static void push_to_pool(struct work_struct *work)
++static bool trust_cpu __initdata = IS_ENABLED(CONFIG_RANDOM_TRUST_CPU);
++static bool trust_bootloader __initdata = IS_ENABLED(CONFIG_RANDOM_TRUST_BOOTLOADER);
++static int __init parse_trust_cpu(char *arg)
+ {
+-	struct entropy_store *r = container_of(work, struct entropy_store,
+-					      push_work);
+-	BUG_ON(!r);
+-	_xfer_secondary_pool(r, random_read_wakeup_bits/8);
+-	trace_push_to_pool(r->name, r->entropy_count >> ENTROPY_SHIFT,
+-			   r->pull->entropy_count >> ENTROPY_SHIFT);
++	return kstrtobool(arg, &trust_cpu);
+ }
+-
+-/*
+- * This function decides how many bytes to actually take from the
+- * given pool, and also debits the entropy count accordingly.
+- */
+-static size_t account(struct entropy_store *r, size_t nbytes, int min,
+-		      int reserved)
++static int __init parse_trust_bootloader(char *arg)
+ {
+-	int entropy_count, orig;
+-	size_t ibytes, nfrac;
+-
+-	BUG_ON(r->entropy_count > r->poolinfo->poolfracbits);
+-
+-	/* Can we pull enough? */
+-retry:
+-	entropy_count = orig = ACCESS_ONCE(r->entropy_count);
+-	ibytes = nbytes;
+-	/* If limited, never pull more than available */
+-	if (r->limit) {
+-		int have_bytes = entropy_count >> (ENTROPY_SHIFT + 3);
+-
+-		if ((have_bytes -= reserved) < 0)
+-			have_bytes = 0;
+-		ibytes = min_t(size_t, ibytes, have_bytes);
+-	}
+-	if (ibytes < min)
+-		ibytes = 0;
+-
+-	if (unlikely(entropy_count < 0)) {
+-		pr_warn("random: negative entropy count: pool %s count %d\n",
+-			r->name, entropy_count);
+-		WARN_ON(1);
+-		entropy_count = 0;
+-	}
+-	nfrac = ibytes << (ENTROPY_SHIFT + 3);
+-	if ((size_t) entropy_count > nfrac)
+-		entropy_count -= nfrac;
+-	else
+-		entropy_count = 0;
+-
+-	if (cmpxchg(&r->entropy_count, orig, entropy_count) != orig)
+-		goto retry;
+-
+-	trace_debit_entropy(r->name, 8 * ibytes);
+-	if (ibytes &&
+-	    (r->entropy_count >> ENTROPY_SHIFT) < random_write_wakeup_bits) {
+-		wake_up_interruptible(&random_write_wait);
+-		kill_fasync(&fasync, SIGIO, POLL_OUT);
+-	}
+-
+-	return ibytes;
++	return kstrtobool(arg, &trust_bootloader);
+ }
++early_param("random.trust_cpu", parse_trust_cpu);
++early_param("random.trust_bootloader", parse_trust_bootloader);
+ 
+ /*
+- * This function does the actual extraction for extract_entropy and
+- * extract_entropy_user.
+- *
+- * Note: we assume that .poolwords is a multiple of 16 words.
++ * The first collection of entropy occurs at system boot while interrupts
++ * 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.
+  */
+-static void extract_buf(struct entropy_store *r, __u8 *out)
++int __init random_init(const char *command_line)
+ {
+-	int i;
+-	union {
+-		__u32 w[5];
+-		unsigned long l[LONGS(20)];
+-	} hash;
+-	__u32 workspace[SHA_WORKSPACE_WORDS];
+-	unsigned long flags;
+-
+-	/*
+-	 * If we have an architectural hardware random number
+-	 * generator, use it for SHA's initial vector
+-	 */
+-	sha_init(hash.w);
+-	for (i = 0; i < LONGS(20); i++) {
+-		unsigned long v;
+-		if (!arch_get_random_long(&v))
+-			break;
+-		hash.l[i] = v;
+-	}
+-
+-	/* Generate a hash across the pool, 16 words (512 bits) at a time */
+-	spin_lock_irqsave(&r->lock, flags);
+-	for (i = 0; i < r->poolinfo->poolwords; i += 16)
+-		sha_transform(hash.w, (__u8 *)(r->pool + i), workspace);
+-
+-	/*
+-	 * We mix the hash back into the pool to prevent backtracking
+-	 * attacks (where the attacker knows the state of the pool
+-	 * plus the current outputs, and attempts to find previous
+-	 * ouputs), unless the hash function can be inverted. By
+-	 * mixing at least a SHA1 worth of hash data back, we make
+-	 * brute-forcing the feedback as hard as brute-forcing the
+-	 * hash.
+-	 */
+-	__mix_pool_bytes(r, hash.w, sizeof(hash.w));
+-	spin_unlock_irqrestore(&r->lock, flags);
+-
+-	memzero_explicit(workspace, sizeof(workspace));
+-
+-	/*
+-	 * In case the hash function has some recognizable output
+-	 * pattern, we fold it in half. Thus, we always feed back
+-	 * twice as much data as we output.
+-	 */
+-	hash.w[0] ^= hash.w[3];
+-	hash.w[1] ^= hash.w[4];
+-	hash.w[2] ^= rol32(hash.w[2], 16);
+-
+-	memcpy(out, &hash, EXTRACT_SIZE);
+-	memzero_explicit(&hash, sizeof(hash));
+-}
+-
+-static ssize_t _extract_entropy(struct entropy_store *r, void *buf,
+-				size_t nbytes, int fips)
+-{
+-	ssize_t ret = 0, i;
+-	__u8 tmp[EXTRACT_SIZE];
+-	unsigned long flags;
++	ktime_t now = ktime_get_real();
++	unsigned int i, arch_bits;
++	unsigned long entropy;
+ 
+-	while (nbytes) {
+-		extract_buf(r, tmp);
++#if defined(LATENT_ENTROPY_PLUGIN)
++	static const u8 compiletime_seed[BLAKE2S_BLOCK_SIZE] __initconst __latent_entropy;
++	_mix_pool_bytes(compiletime_seed, sizeof(compiletime_seed));
++#endif
+ 
+-		if (fips) {
+-			spin_lock_irqsave(&r->lock, flags);
+-			if (!memcmp(tmp, r->last_data, EXTRACT_SIZE))
+-				panic("Hardware RNG duplicated output!\n");
+-			memcpy(r->last_data, tmp, EXTRACT_SIZE);
+-			spin_unlock_irqrestore(&r->lock, flags);
++	for (i = 0, arch_bits = BLAKE2S_BLOCK_SIZE * 8;
++	     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_bits -= sizeof(entropy) * 8;
+ 		}
+-		i = min_t(int, nbytes, EXTRACT_SIZE);
+-		memcpy(buf, tmp, i);
+-		nbytes -= i;
+-		buf += i;
+-		ret += i;
++		_mix_pool_bytes(&entropy, sizeof(entropy));
+ 	}
++	_mix_pool_bytes(&now, sizeof(now));
++	_mix_pool_bytes(utsname(), sizeof(*(utsname())));
++	_mix_pool_bytes(command_line, strlen(command_line));
++	add_latent_entropy();
+ 
+-	/* Wipe data just returned from memory */
+-	memzero_explicit(tmp, sizeof(tmp));
++	if (crng_ready())
++		crng_reseed();
++	else if (trust_cpu)
++		_credit_init_bits(arch_bits);
+ 
+-	return ret;
++	return 0;
+ }
+ 
+ /*
+- * This function extracts randomness from the "entropy pool", and
+- * returns it in a buffer.
++ * Add device- or boot-specific data to the input pool to help
++ * initialize it.
+  *
+- * The min parameter specifies the minimum amount we can pull before
+- * failing to avoid races that defeat catastrophic reseeding while the
+- * reserved parameter indicates how much entropy we must leave in the
+- * pool after each pull to avoid starving other readers.
++ * None of this adds any entropy; it is meant to avoid the problem of
++ * the entropy pool having similar initial state across largely
++ * identical devices.
+  */
+-static ssize_t extract_entropy(struct entropy_store *r, void *buf,
+-				 size_t nbytes, int min, int reserved)
++void add_device_randomness(const void *buf, size_t len)
+ {
+-	__u8 tmp[EXTRACT_SIZE];
++	unsigned long entropy = random_get_entropy();
+ 	unsigned long flags;
+ 
+-	/* if last_data isn't primed, we need EXTRACT_SIZE extra bytes */
+-	if (fips_enabled) {
+-		spin_lock_irqsave(&r->lock, flags);
+-		if (!r->last_data_init) {
+-			r->last_data_init = 1;
+-			spin_unlock_irqrestore(&r->lock, flags);
+-			trace_extract_entropy(r->name, EXTRACT_SIZE,
+-					      ENTROPY_BITS(r), _RET_IP_);
+-			xfer_secondary_pool(r, EXTRACT_SIZE);
+-			extract_buf(r, tmp);
+-			spin_lock_irqsave(&r->lock, flags);
+-			memcpy(r->last_data, tmp, EXTRACT_SIZE);
+-		}
+-		spin_unlock_irqrestore(&r->lock, flags);
+-	}
+-
+-	trace_extract_entropy(r->name, nbytes, ENTROPY_BITS(r), _RET_IP_);
+-	xfer_secondary_pool(r, nbytes);
+-	nbytes = account(r, nbytes, min, reserved);
+-
+-	return _extract_entropy(r, buf, nbytes, fips_enabled);
++	spin_lock_irqsave(&input_pool.lock, flags);
++	_mix_pool_bytes(&entropy, sizeof(entropy));
++	_mix_pool_bytes(buf, len);
++	spin_unlock_irqrestore(&input_pool.lock, flags);
+ }
++EXPORT_SYMBOL(add_device_randomness);
+ 
+ /*
+- * This function extracts randomness from the "entropy pool", and
+- * returns it in a userspace buffer.
++ * Interface for in-kernel drivers of true hardware RNGs.
++ * Those devices may produce endless random bits and will be throttled
++ * when our pool is full.
+  */
+-static ssize_t extract_entropy_user(struct entropy_store *r, void __user *buf,
+-				    size_t nbytes)
++void add_hwgenerator_randomness(const void *buf, size_t len, size_t entropy)
+ {
+-	ssize_t ret = 0, i;
+-	__u8 tmp[EXTRACT_SIZE];
+-	int large_request = (nbytes > 256);
+-
+-	trace_extract_entropy_user(r->name, nbytes, ENTROPY_BITS(r), _RET_IP_);
+-	xfer_secondary_pool(r, nbytes);
+-	nbytes = account(r, nbytes, 0, 0);
+-
+-	while (nbytes) {
+-		if (large_request && need_resched()) {
+-			if (signal_pending(current)) {
+-				if (ret == 0)
+-					ret = -ERESTARTSYS;
+-				break;
+-			}
+-			schedule();
+-		}
+-
+-		extract_buf(r, tmp);
+-		i = min_t(int, nbytes, EXTRACT_SIZE);
+-		if (copy_to_user(buf, tmp, i)) {
+-			ret = -EFAULT;
+-			break;
+-		}
++	mix_pool_bytes(buf, len);
++	credit_init_bits(entropy);
+ 
+-		nbytes -= i;
+-		buf += i;
+-		ret += i;
+-	}
+-
+-	/* Wipe data just returned from memory */
+-	memzero_explicit(tmp, sizeof(tmp));
+-
+-	return ret;
++	/*
++	 * Throttle writing to once every CRNG_RESEED_INTERVAL, unless
++	 * we're not yet initialized.
++	 */
++	if (!kthread_should_stop() && crng_ready())
++		schedule_timeout_interruptible(CRNG_RESEED_INTERVAL);
+ }
++EXPORT_SYMBOL_GPL(add_hwgenerator_randomness);
+ 
+ /*
+- * This function is the exported kernel interface.  It returns some
+- * number of good random numbers, suitable for key generation, seeding
+- * TCP sequence numbers, etc.  It does not rely on the hardware random
+- * number generator.  For random bytes direct from the hardware RNG
+- * (when available), use get_random_bytes_arch().
++ * Handle random seed passed by bootloader, and credit it if
++ * CONFIG_RANDOM_TRUST_BOOTLOADER is set.
+  */
+-void get_random_bytes(void *buf, int nbytes)
++void __init add_bootloader_randomness(const void *buf, size_t len)
+ {
+-	__u8 tmp[CHACHA20_BLOCK_SIZE];
++	mix_pool_bytes(buf, len);
++	if (trust_bootloader)
++		credit_init_bits(len * 8);
++}
+ 
+-#if DEBUG_RANDOM_BOOT > 0
+-	if (!crng_ready())
+-		printk(KERN_NOTICE "random: %pF get_random_bytes called "
+-		       "with crng_init = %d\n", (void *) _RET_IP_, crng_init);
+-#endif
+-	trace_get_random_bytes(nbytes, _RET_IP_);
++struct fast_pool {
++	struct work_struct mix;
++	unsigned long pool[4];
++	unsigned long last;
++	unsigned int count;
++};
+ 
+-	while (nbytes >= CHACHA20_BLOCK_SIZE) {
+-		extract_crng(buf);
+-		buf += CHACHA20_BLOCK_SIZE;
+-		nbytes -= CHACHA20_BLOCK_SIZE;
+-	}
++static DEFINE_PER_CPU(struct fast_pool, irq_randomness) = {
++#ifdef CONFIG_64BIT
++#define FASTMIX_PERM SIPHASH_PERMUTATION
++	.pool = { SIPHASH_CONST_0, SIPHASH_CONST_1, SIPHASH_CONST_2, SIPHASH_CONST_3 }
++#else
++#define FASTMIX_PERM HSIPHASH_PERMUTATION
++	.pool = { HSIPHASH_CONST_0, HSIPHASH_CONST_1, HSIPHASH_CONST_2, HSIPHASH_CONST_3 }
++#endif
++};
+ 
+-	if (nbytes > 0) {
+-		extract_crng(tmp);
+-		memcpy(buf, tmp, nbytes);
+-		crng_backtrack_protect(tmp, nbytes);
+-	} else
+-		crng_backtrack_protect(tmp, CHACHA20_BLOCK_SIZE);
+-	memzero_explicit(tmp, sizeof(tmp));
++/*
++ * This is [Half]SipHash-1-x, starting from an empty key. Because
++ * the key is fixed, it assumes that its inputs are non-malicious,
++ * and therefore this has no security on its own. s represents the
++ * four-word SipHash state, while v represents a two-word input.
++ */
++static void fast_mix(unsigned long s[4], unsigned long v1, unsigned long v2)
++{
++	s[3] ^= v1;
++	FASTMIX_PERM(s[0], s[1], s[2], s[3]);
++	s[0] ^= v1;
++	s[3] ^= v2;
++	FASTMIX_PERM(s[0], s[1], s[2], s[3]);
++	s[0] ^= v2;
+ }
+-EXPORT_SYMBOL(get_random_bytes);
+ 
++#ifdef CONFIG_SMP
+ /*
+- * Add a callback function that will be invoked when the nonblocking
+- * pool is initialised.
+- *
+- * returns: 0 if callback is successfully added
+- *	    -EALREADY if pool is already initialised (callback not called)
+- *	    -ENOENT if module for callback is not alive
++ * This function is called when the CPU has just come online, with
++ * entry CPUHP_AP_RANDOM_ONLINE, just after CPUHP_AP_WORKQUEUE_ONLINE.
+  */
+-int add_random_ready_callback(struct random_ready_callback *rdy)
++int __cold random_online_cpu(unsigned int cpu)
+ {
+-	struct module *owner;
+-	unsigned long flags;
+-	int err = -EALREADY;
++	/*
++	 * During CPU shutdown and before CPU onlining, add_interrupt_
++	 * randomness() may schedule mix_interrupt_randomness(), and
++	 * set the MIX_INFLIGHT flag. However, because the worker can
++	 * be scheduled on a different CPU during this period, that
++	 * flag will never be cleared. For that reason, we zero out
++	 * the flag here, which runs just after workqueues are onlined
++	 * for the CPU again. This also has the effect of setting the
++	 * irq randomness count to zero so that new accumulated irqs
++	 * are fresh.
++	 */
++	per_cpu_ptr(&irq_randomness, cpu)->count = 0;
++	return 0;
++}
++#endif
+ 
+-	if (crng_ready())
+-		return err;
++static void mix_interrupt_randomness(struct work_struct *work)
++{
++	struct fast_pool *fast_pool = container_of(work, struct fast_pool, mix);
++	/*
++	 * The size of the copied stack pool is explicitly 2 longs so that we
++	 * only ever ingest half of the siphash output each time, retaining
++	 * the other half as the next "key" that carries over. The entropy is
++	 * supposed to be sufficiently dispersed between bits so on average
++	 * we don't wind up "losing" some.
++	 */
++	unsigned long pool[2];
++	unsigned int count;
+ 
+-	owner = rdy->owner;
+-	if (!try_module_get(owner))
+-		return -ENOENT;
++	/* Check to see if we're running on the wrong CPU due to hotplug. */
++	local_irq_disable();
++	if (fast_pool != this_cpu_ptr(&irq_randomness)) {
++		local_irq_enable();
++		return;
++	}
+ 
+-	spin_lock_irqsave(&random_ready_list_lock, flags);
+-	if (crng_ready())
+-		goto out;
++	/*
++	 * Copy the pool to the stack so that the mixer always has a
++	 * consistent view, before we reenable irqs again.
++	 */
++	memcpy(pool, fast_pool->pool, sizeof(pool));
++	count = fast_pool->count;
++	fast_pool->count = 0;
++	fast_pool->last = jiffies;
++	local_irq_enable();
++
++	mix_pool_bytes(pool, sizeof(pool));
++	credit_init_bits(max(1u, (count & U16_MAX) / 64));
+ 
+-	owner = NULL;
++	memzero_explicit(pool, sizeof(pool));
++}
++
++void add_interrupt_randomness(int irq)
++{
++	enum { MIX_INFLIGHT = 1U << 31 };
++	unsigned long entropy = random_get_entropy();
++	struct fast_pool *fast_pool = this_cpu_ptr(&irq_randomness);
++	struct pt_regs *regs = get_irq_regs();
++	unsigned int new_count;
+ 
+-	list_add(&rdy->list, &random_ready_list);
+-	err = 0;
++	fast_mix(fast_pool->pool, entropy,
++		 (regs ? instruction_pointer(regs) : _RET_IP_) ^ swab(irq));
++	new_count = ++fast_pool->count;
+ 
+-out:
+-	spin_unlock_irqrestore(&random_ready_list_lock, flags);
++	if (new_count & MIX_INFLIGHT)
++		return;
+ 
+-	module_put(owner);
++	if (new_count < 64 && !time_is_before_jiffies(fast_pool->last + HZ))
++		return;
+ 
+-	return err;
++	if (unlikely(!fast_pool->mix.func))
++		INIT_WORK(&fast_pool->mix, mix_interrupt_randomness);
++	fast_pool->count |= MIX_INFLIGHT;
++	queue_work_on(raw_smp_processor_id(), system_highpri_wq, &fast_pool->mix);
+ }
+-EXPORT_SYMBOL(add_random_ready_callback);
++EXPORT_SYMBOL_GPL(add_interrupt_randomness);
++
++/* There is one of these per entropy source */
++struct timer_rand_state {
++	unsigned long last_time;
++	long last_delta, last_delta2;
++};
+ 
+ /*
+- * Delete a previously registered readiness callback function.
++ * This function adds entropy to the entropy "pool" by using timing
++ * delays. It uses the timer_rand_state structure to make an estimate
++ * of how many bits of entropy this call has added to the pool. The
++ * value "num" is also added to the pool; it should somehow describe
++ * the type of event that just happened.
+  */
+-void del_random_ready_callback(struct random_ready_callback *rdy)
++static void add_timer_randomness(struct timer_rand_state *state, unsigned int num)
+ {
+-	unsigned long flags;
+-	struct module *owner = NULL;
++	unsigned long entropy = random_get_entropy(), now = jiffies, flags;
++	long delta, delta2, delta3;
++	unsigned int bits;
+ 
+-	spin_lock_irqsave(&random_ready_list_lock, flags);
+-	if (!list_empty(&rdy->list)) {
+-		list_del_init(&rdy->list);
+-		owner = rdy->owner;
++	/*
++	 * If we're in a hard IRQ, add_interrupt_randomness() will be called
++	 * sometime after, so mix into the fast pool.
++	 */
++	if (in_irq()) {
++		fast_mix(this_cpu_ptr(&irq_randomness)->pool, entropy, num);
++	} else {
++		spin_lock_irqsave(&input_pool.lock, flags);
++		_mix_pool_bytes(&entropy, sizeof(entropy));
++		_mix_pool_bytes(&num, sizeof(num));
++		spin_unlock_irqrestore(&input_pool.lock, flags);
+ 	}
+-	spin_unlock_irqrestore(&random_ready_list_lock, flags);
+-
+-	module_put(owner);
+-}
+-EXPORT_SYMBOL(del_random_ready_callback);
+ 
+-/*
+- * This function will use the architecture-specific hardware random
+- * number generator if it is available.  The arch-specific hw RNG will
+- * almost certainly be faster than what we can do in software, but it
+- * is impossible to verify that it is implemented securely (as
+- * opposed, to, say, the AES encryption of a sequence number using a
+- * key known by the NSA).  So it's useful if we need the speed, but
+- * only if we're willing to trust the hardware manufacturer not to
+- * have put in a back door.
+- */
+-void get_random_bytes_arch(void *buf, int nbytes)
+-{
+-	char *p = buf;
++	if (crng_ready())
++		return;
+ 
+-	trace_get_random_bytes_arch(nbytes, _RET_IP_);
+-	while (nbytes) {
+-		unsigned long v;
+-		int chunk = min(nbytes, (int)sizeof(unsigned long));
++	/*
++	 * Calculate number of bits of randomness we probably added.
++	 * We take into account the first, second and third-order deltas
++	 * in order to make our estimate.
++	 */
++	delta = now - READ_ONCE(state->last_time);
++	WRITE_ONCE(state->last_time, now);
++
++	delta2 = delta - READ_ONCE(state->last_delta);
++	WRITE_ONCE(state->last_delta, delta);
++
++	delta3 = delta2 - READ_ONCE(state->last_delta2);
++	WRITE_ONCE(state->last_delta2, delta2);
++
++	if (delta < 0)
++		delta = -delta;
++	if (delta2 < 0)
++		delta2 = -delta2;
++	if (delta3 < 0)
++		delta3 = -delta3;
++	if (delta > delta2)
++		delta = delta2;
++	if (delta > delta3)
++		delta = delta3;
+ 
+-		if (!arch_get_random_long(&v))
+-			break;
+-		
+-		memcpy(p, &v, chunk);
+-		p += chunk;
+-		nbytes -= chunk;
+-	}
++	/*
++	 * delta is now minimum absolute delta. Round down by 1 bit
++	 * on general principles, and limit entropy estimate to 11 bits.
++	 */
++	bits = min(fls(delta >> 1), 11);
+ 
+-	if (nbytes)
+-		get_random_bytes(p, nbytes);
++	/*
++	 * As mentioned above, if we're in a hard IRQ, add_interrupt_randomness()
++	 * will run after this, which uses a different crediting scheme of 1 bit
++	 * per every 64 interrupts. In order to let that function do accounting
++	 * close to the one in this function, we credit a full 64/64 bit per bit,
++	 * and then subtract one to account for the extra one added.
++	 */
++	if (in_irq())
++		this_cpu_ptr(&irq_randomness)->count += max(1u, bits * 64) - 1;
++	else
++		_credit_init_bits(bits);
+ }
+-EXPORT_SYMBOL(get_random_bytes_arch);
+-
+ 
+-/*
+- * init_std_data - initialize pool with system data
+- *
+- * @r: pool to initialize
+- *
+- * This function clears the pool's entropy count and mixes some system
+- * data into the pool to prepare it for use. The pool is not cleared
+- * as that can only decrease the entropy in the pool.
+- */
+-static void init_std_data(struct entropy_store *r)
++void add_input_randomness(unsigned int type, unsigned int code, unsigned int value)
+ {
+-	int i;
+-	ktime_t now = ktime_get_real();
+-	unsigned long rv;
+-
+-	r->last_pulled = jiffies;
+-	mix_pool_bytes(r, &now, sizeof(now));
+-	for (i = r->poolinfo->poolbytes; i > 0; i -= sizeof(rv)) {
+-		if (!arch_get_random_seed_long(&rv) &&
+-		    !arch_get_random_long(&rv))
+-			rv = random_get_entropy();
+-		mix_pool_bytes(r, &rv, sizeof(rv));
+-	}
+-	mix_pool_bytes(r, utsname(), sizeof(*(utsname())));
++	static unsigned char last_value;
++	static struct timer_rand_state input_timer_state = { INITIAL_JIFFIES };
++
++	/* Ignore autorepeat and the like. */
++	if (value == last_value)
++		return;
++
++	last_value = value;
++	add_timer_randomness(&input_timer_state,
++			     (type << 4) ^ code ^ (code >> 4) ^ value);
+ }
++EXPORT_SYMBOL_GPL(add_input_randomness);
+ 
+-/*
+- * Note that setup_arch() may call add_device_randomness()
+- * long before we get here. This allows seeding of the pools
+- * with some platform dependent data very early in the boot
+- * process. But it limits our options here. We must use
+- * statically allocated structures that already have all
+- * initializations complete at compile time. We should also
+- * take care not to overwrite the precious per platform data
+- * we were given.
+- */
+-static int rand_initialize(void)
++#ifdef CONFIG_BLOCK
++void add_disk_randomness(struct gendisk *disk)
+ {
+-	init_std_data(&input_pool);
+-	init_std_data(&blocking_pool);
+-	crng_initialize(&primary_crng);
+-	crng_global_init_time = jiffies;
+-	if (ratelimit_disable) {
+-		urandom_warning.interval = 0;
+-		unseeded_warning.interval = 0;
+-	}
+-	return 0;
++	if (!disk || !disk->random)
++		return;
++	/* First major is 1, so we get >= 0x200 here. */
++	add_timer_randomness(disk->random, 0x100 + disk_devt(disk));
+ }
+-early_initcall(rand_initialize);
++EXPORT_SYMBOL_GPL(add_disk_randomness);
+ 
+-#ifdef CONFIG_BLOCK
+-void rand_initialize_disk(struct gendisk *disk)
++void __cold rand_initialize_disk(struct gendisk *disk)
+ {
+ 	struct timer_rand_state *state;
+ 
+@@ -1752,134 +1127,189 @@ void rand_initialize_disk(struct gendisk *disk)
+ }
+ #endif
+ 
+-static ssize_t
+-_random_read(int nonblock, char __user *buf, size_t nbytes)
++/*
++ * Each time the timer fires, we expect that we got an unpredictable
++ * jump in the cycle counter. Even if the timer is running on another
++ * CPU, the timer activity will be touching the stack of the CPU that is
++ * generating entropy..
++ *
++ * Note that we don't re-arm the timer in the timer itself - we are
++ * happy to be scheduled away, since that just makes the load more
++ * complex, but we do not want the timer to keep ticking unless the
++ * entropy loop is running.
++ *
++ * So the re-arming always happens in the entropy loop itself.
++ */
++static void __cold entropy_timer(unsigned long data)
++{
++	credit_init_bits(1);
++}
++
++/*
++ * If we have an actual cycle counter, see if we can
++ * generate enough entropy with timing noise
++ */
++static void __cold try_to_generate_entropy(void)
+ {
+-	ssize_t n;
++	struct {
++		unsigned long entropy;
++		struct timer_list timer;
++	} stack;
+ 
+-	if (nbytes == 0)
+-		return 0;
++	stack.entropy = random_get_entropy();
+ 
+-	nbytes = min_t(size_t, nbytes, SEC_XFER_SIZE);
+-	while (1) {
+-		n = extract_entropy_user(&blocking_pool, buf, nbytes);
+-		if (n < 0)
+-			return n;
+-		trace_random_read(n*8, (nbytes-n)*8,
+-				  ENTROPY_BITS(&blocking_pool),
+-				  ENTROPY_BITS(&input_pool));
+-		if (n > 0)
+-			return n;
+-
+-		/* Pool is (near) empty.  Maybe wait and retry. */
+-		if (nonblock)
+-			return -EAGAIN;
++	/* Slow counter - or none. Don't even bother */
++	if (stack.entropy == random_get_entropy())
++		return;
+ 
+-		wait_event_interruptible(random_read_wait,
+-			ENTROPY_BITS(&input_pool) >=
+-			random_read_wakeup_bits);
+-		if (signal_pending(current))
+-			return -ERESTARTSYS;
++	__setup_timer_on_stack(&stack.timer, entropy_timer, 0, 0);
++	while (!crng_ready() && !signal_pending(current)) {
++		if (!timer_pending(&stack.timer))
++			mod_timer(&stack.timer, jiffies + 1);
++		mix_pool_bytes(&stack.entropy, sizeof(stack.entropy));
++		schedule();
++		stack.entropy = random_get_entropy();
+ 	}
+-}
+ 
+-static ssize_t
+-random_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos)
+-{
+-	return _random_read(file->f_flags & O_NONBLOCK, buf, nbytes);
++	del_timer_sync(&stack.timer);
++	destroy_timer_on_stack(&stack.timer);
++	mix_pool_bytes(&stack.entropy, sizeof(stack.entropy));
+ }
+ 
+-static ssize_t
+-urandom_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos)
++
++/**********************************************************************
++ *
++ * Userspace reader/writer interfaces.
++ *
++ * getrandom(2) is the primary modern interface into the RNG and should
++ * be used in preference to anything else.
++ *
++ * Reading from /dev/random has the same functionality as calling
++ * getrandom(2) with flags=0. In earlier versions, however, it had
++ * vastly different semantics and should therefore be avoided, to
++ * prevent backwards compatibility issues.
++ *
++ * Reading from /dev/urandom has the same functionality as calling
++ * getrandom(2) with flags=GRND_INSECURE. Because it does not block
++ * waiting for the RNG to be ready, it should not be used.
++ *
++ * Writing to either /dev/random or /dev/urandom adds entropy to
++ * the input pool but does not credit it.
++ *
++ * Polling on /dev/random indicates when the RNG is initialized, on
++ * the read side, and when it wants new entropy, on the write side.
++ *
++ * Both /dev/random and /dev/urandom have the same set of ioctls for
++ * adding entropy, getting the entropy count, zeroing the count, and
++ * reseeding the crng.
++ *
++ **********************************************************************/
++
++SYSCALL_DEFINE3(getrandom, char __user *, ubuf, size_t, len, unsigned int, flags)
+ {
+-	unsigned long flags;
+-	static int maxwarn = 10;
++	struct iov_iter iter;
++	struct iovec iov;
+ 	int ret;
+ 
+-	if (!crng_ready() && maxwarn > 0) {
+-		maxwarn--;
+-		if (__ratelimit(&urandom_warning))
+-			printk(KERN_NOTICE "random: %s: uninitialized "
+-			       "urandom read (%zd bytes read)\n",
+-			       current->comm, nbytes);
+-		spin_lock_irqsave(&primary_crng.lock, flags);
+-		crng_init_cnt = 0;
+-		spin_unlock_irqrestore(&primary_crng.lock, flags);
++	if (flags & ~(GRND_NONBLOCK | GRND_RANDOM | GRND_INSECURE))
++		return -EINVAL;
++
++	/*
++	 * Requesting insecure and blocking randomness at the same time makes
++	 * no sense.
++	 */
++	if ((flags & (GRND_INSECURE | GRND_RANDOM)) == (GRND_INSECURE | GRND_RANDOM))
++		return -EINVAL;
++
++	if (!crng_ready() && !(flags & GRND_INSECURE)) {
++		if (flags & GRND_NONBLOCK)
++			return -EAGAIN;
++		ret = wait_for_random_bytes();
++		if (unlikely(ret))
++			return ret;
+ 	}
+-	nbytes = min_t(size_t, nbytes, INT_MAX >> (ENTROPY_SHIFT + 3));
+-	ret = extract_crng_user(buf, nbytes);
+-	trace_urandom_read(8 * nbytes, 0, ENTROPY_BITS(&input_pool));
+-	return ret;
++
++	ret = import_single_range(READ, ubuf, len, &iov, &iter);
++	if (unlikely(ret))
++		return ret;
++	return get_random_bytes_user(&iter);
+ }
+ 
+-static unsigned int
+-random_poll(struct file *file, poll_table * wait)
++static unsigned int random_poll(struct file *file, poll_table *wait)
+ {
+-	unsigned int mask;
+-
+-	poll_wait(file, &random_read_wait, wait);
+-	poll_wait(file, &random_write_wait, wait);
+-	mask = 0;
+-	if (ENTROPY_BITS(&input_pool) >= random_read_wakeup_bits)
+-		mask |= POLLIN | POLLRDNORM;
+-	if (ENTROPY_BITS(&input_pool) < random_write_wakeup_bits)
+-		mask |= POLLOUT | POLLWRNORM;
+-	return mask;
++	poll_wait(file, &crng_init_wait, wait);
++	return crng_ready() ? POLLIN | POLLRDNORM : POLLOUT | POLLWRNORM;
+ }
+ 
+-static int
+-write_pool(struct entropy_store *r, const char __user *buffer, size_t count)
++static ssize_t write_pool_user(struct iov_iter *iter)
+ {
+-	size_t bytes;
+-	__u32 t, buf[16];
+-	const char __user *p = buffer;
++	u8 block[BLAKE2S_BLOCK_SIZE];
++	ssize_t ret = 0;
++	size_t copied;
+ 
+-	while (count > 0) {
+-		int b, i = 0;
++	if (unlikely(!iov_iter_count(iter)))
++		return 0;
+ 
+-		bytes = min(count, sizeof(buf));
+-		if (copy_from_user(&buf, p, bytes))
+-			return -EFAULT;
++	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;
+ 
+-		for (b = bytes ; b > 0 ; b -= sizeof(__u32), i++) {
+-			if (!arch_get_random_int(&t))
++		BUILD_BUG_ON(PAGE_SIZE % sizeof(block) != 0);
++		if (ret % PAGE_SIZE == 0) {
++			if (signal_pending(current))
+ 				break;
+-			buf[i] ^= t;
++			cond_resched();
+ 		}
++	}
+ 
+-		count -= bytes;
+-		p += bytes;
++	memzero_explicit(block, sizeof(block));
++	return ret ? ret : -EFAULT;
++}
++
++static ssize_t random_write_iter(struct kiocb *kiocb, struct iov_iter *iter)
++{
++	return write_pool_user(iter);
++}
+ 
+-		mix_pool_bytes(r, buf, bytes);
+-		cond_resched();
++static ssize_t urandom_read_iter(struct kiocb *kiocb, struct iov_iter *iter)
++{
++	static int maxwarn = 10;
++
++	if (!crng_ready()) {
++		if (!ratelimit_disable && maxwarn <= 0)
++			++urandom_warning.missed;
++		else if (ratelimit_disable || __ratelimit(&urandom_warning)) {
++			--maxwarn;
++			pr_notice("%s: uninitialized urandom read (%zu bytes read)\n",
++				  current->comm, iov_iter_count(iter));
++		}
+ 	}
+ 
+-	return 0;
++	return get_random_bytes_user(iter);
+ }
+ 
+-static ssize_t random_write(struct file *file, const char __user *buffer,
+-			    size_t count, loff_t *ppos)
++static ssize_t random_read_iter(struct kiocb *kiocb, struct iov_iter *iter)
+ {
+-	size_t ret;
++	int ret;
+ 
+-	ret = write_pool(&input_pool, buffer, count);
+-	if (ret)
++	ret = wait_for_random_bytes();
++	if (ret != 0)
+ 		return ret;
+-
+-	return (ssize_t)count;
++	return get_random_bytes_user(iter);
+ }
+ 
+ static 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:
+-		/* inherently racy, no point locking */
+-		ent_count = ENTROPY_BITS(&input_pool);
+-		if (put_user(ent_count, p))
++		/* Inherently racy, no point locking. */
++		if (put_user(input_pool.init_bits, p))
+ 			return -EFAULT;
+ 		return 0;
+ 	case RNDADDTOENTCNT:
+@@ -1887,39 +1317,48 @@ static long random_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
+ 			return -EPERM;
+ 		if (get_user(ent_count, p))
+ 			return -EFAULT;
+-		return credit_entropy_bits_safe(&input_pool, ent_count);
+-	case RNDADDENTROPY:
++		if (ent_count < 0)
++			return -EINVAL;
++		credit_init_bits(ent_count);
++		return 0;
++	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;
+-		retval = write_pool(&input_pool, (const char __user *)p,
+-				    size);
+-		if (retval < 0)
+-			return retval;
+-		return credit_entropy_bits_safe(&input_pool, ent_count);
++		ret = import_single_range(WRITE, p, len, &iov, &iter);
++		if (unlikely(ret))
++			return ret;
++		ret = write_pool_user(&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;
++		credit_init_bits(ent_count);
++		return 0;
++	}
+ 	case RNDZAPENTCNT:
+ 	case RNDCLEARPOOL:
+-		/*
+-		 * Clear the entropy pool counters. We no longer clear
+-		 * the entropy pool, as that's silly.
+-		 */
++		/* No longer has any effect. */
+ 		if (!capable(CAP_SYS_ADMIN))
+ 			return -EPERM;
+-		input_pool.entropy_count = 0;
+-		blocking_pool.entropy_count = 0;
+ 		return 0;
+ 	case RNDRESEEDCRNG:
+ 		if (!capable(CAP_SYS_ADMIN))
+ 			return -EPERM;
+-		if (crng_init < 2)
++		if (!crng_ready())
+ 			return -ENODATA;
+-		crng_reseed(&primary_crng, &input_pool);
+-		WRITE_ONCE(crng_global_init_time, jiffies - 1);
++		crng_reseed();
+ 		return 0;
+ 	default:
+ 		return -EINVAL;
+@@ -1932,47 +1371,54 @@ static int random_fasync(int fd, struct file *filp, int on)
+ }
+ 
+ const struct file_operations random_fops = {
+-	.read  = random_read,
+-	.write = random_write,
+-	.poll  = random_poll,
++	.read_iter = random_read_iter,
++	.write_iter = random_write_iter,
++	.poll = random_poll,
+ 	.unlocked_ioctl = random_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 = {
+-	.read  = urandom_read,
+-	.write = random_write,
++	.read_iter = urandom_read_iter,
++	.write_iter = random_write_iter,
+ 	.unlocked_ioctl = random_ioctl,
+ 	.fasync = random_fasync,
+ 	.llseek = noop_llseek,
++	.splice_read = generic_file_splice_read,
++	.splice_write = iter_file_splice_write,
+ };
+ 
+-SYSCALL_DEFINE3(getrandom, char __user *, buf, size_t, count,
+-		unsigned int, flags)
+-{
+-	if (flags & ~(GRND_NONBLOCK|GRND_RANDOM))
+-		return -EINVAL;
+-
+-	if (count > INT_MAX)
+-		count = INT_MAX;
+-
+-	if (flags & GRND_RANDOM)
+-		return _random_read(flags & GRND_NONBLOCK, buf, count);
+-
+-	if (!crng_ready()) {
+-		if (flags & GRND_NONBLOCK)
+-			return -EAGAIN;
+-		crng_wait_ready();
+-		if (signal_pending(current))
+-			return -ERESTARTSYS;
+-	}
+-	return urandom_read(NULL, buf, count, NULL);
+-}
+ 
+ /********************************************************************
+  *
+- * Sysctl interface
++ * Sysctl interface.
++ *
++ * These are partly unused legacy knobs with dummy values to not break
++ * userspace and partly still useful things. They are usually accessible
++ * in /proc/sys/kernel/random/ and are as follows:
++ *
++ * - boot_id - a UUID representing the current boot.
++ *
++ * - uuid - a random UUID, different each time the file is read.
++ *
++ * - poolsize - the number of bits of entropy that the input pool can
++ *   hold, tied to the POOL_BITS constant.
++ *
++ * - entropy_avail - the number of bits of entropy currently in the
++ *   input pool. Always <= poolsize.
++ *
++ * - write_wakeup_threshold - the amount of entropy in the input pool
++ *   below which write polls to /dev/random will unblock, requesting
++ *   more entropy, tied to the POOL_READY_BITS constant. It is writable
++ *   to avoid breaking old userspaces, but writing to it does not
++ *   change any behavior of the RNG.
++ *
++ * - urandom_min_reseed_secs - fixed to the value CRNG_RESEED_INTERVAL.
++ *   It is writable to avoid breaking old userspaces, but writing
++ *   to it does not change any behavior of the RNG.
+  *
+  ********************************************************************/
+ 
+@@ -1980,25 +1426,28 @@ SYSCALL_DEFINE3(getrandom, char __user *, buf, size_t, count,
+ 
+ #include <linux/sysctl.h>
+ 
+-static int min_read_thresh = 8, min_write_thresh;
+-static int max_read_thresh = OUTPUT_POOL_WORDS * 32;
+-static int max_write_thresh = INPUT_POOL_WORDS * 32;
+-static char sysctl_bootid[16];
++static int sysctl_random_min_urandom_seed = CRNG_RESEED_INTERVAL / HZ;
++static int sysctl_random_write_wakeup_bits = POOL_READY_BITS;
++static int sysctl_poolsize = POOL_BITS;
++static u8 sysctl_bootid[UUID_SIZE];
+ 
+ /*
+  * This function is used to return both the bootid UUID, and random
+- * UUID.  The difference is in whether table->data is NULL; if it is,
++ * UUID. The difference is in whether table->data is NULL; if it is,
+  * then a new UUID is generated and returned to the user.
+- *
+- * If the user accesses this via the proc interface, the UUID will be
+- * returned as an ASCII string in the standard UUID format; if via the
+- * sysctl system call, as 16 bytes of binary data.
+  */
+-static int proc_do_uuid(struct ctl_table *table, int write,
+-			void __user *buffer, size_t *lenp, loff_t *ppos)
++static int proc_do_uuid(struct ctl_table *table, int write, void __user *buf,
++			size_t *lenp, loff_t *ppos)
+ {
+-	struct ctl_table fake_table;
+-	unsigned char buf[64], tmp_uuid[16], *uuid;
++	u8 tmp_uuid[UUID_SIZE], *uuid;
++	char uuid_string[UUID_STRING_LEN + 1];
++	struct ctl_table fake_table = {
++		.data = uuid_string,
++		.maxlen = UUID_STRING_LEN
++	};
++
++	if (write)
++		return -EPERM;
+ 
+ 	uuid = table->data;
+ 	if (!uuid) {
+@@ -2013,32 +1462,17 @@ static int proc_do_uuid(struct ctl_table *table, int write,
+ 		spin_unlock(&bootid_spinlock);
+ 	}
+ 
+-	sprintf(buf, "%pU", uuid);
+-
+-	fake_table.data = buf;
+-	fake_table.maxlen = sizeof(buf);
+-
+-	return proc_dostring(&fake_table, write, buffer, lenp, ppos);
++	snprintf(uuid_string, sizeof(uuid_string), "%pU", uuid);
++	return proc_dostring(&fake_table, 0, buf, lenp, ppos);
+ }
+ 
+-/*
+- * Return entropy available scaled to integral bits
+- */
+-static int proc_do_entropy(struct ctl_table *table, int write,
+-			   void __user *buffer, size_t *lenp, loff_t *ppos)
++/* The same as proc_dointvec, but writes don't change anything. */
++static int proc_do_rointvec(struct ctl_table *table, int write, void __user *buf,
++			    size_t *lenp, loff_t *ppos)
+ {
+-	struct ctl_table fake_table;
+-	int entropy_count;
+-
+-	entropy_count = *(int *)table->data >> ENTROPY_SHIFT;
+-
+-	fake_table.data = &entropy_count;
+-	fake_table.maxlen = sizeof(entropy_count);
+-
+-	return proc_dointvec(&fake_table, write, buffer, lenp, ppos);
++	return write ? 0 : proc_dointvec(table, 0, buf, lenp, ppos);
+ }
+ 
+-static int sysctl_poolsize = INPUT_POOL_WORDS * 32;
+ extern struct ctl_table random_table[];
+ struct ctl_table random_table[] = {
+ 	{
+@@ -2050,177 +1484,36 @@ struct ctl_table random_table[] = {
+ 	},
+ 	{
+ 		.procname	= "entropy_avail",
++		.data		= &input_pool.init_bits,
+ 		.maxlen		= sizeof(int),
+ 		.mode		= 0444,
+-		.proc_handler	= proc_do_entropy,
+-		.data		= &input_pool.entropy_count,
+-	},
+-	{
+-		.procname	= "read_wakeup_threshold",
+-		.data		= &random_read_wakeup_bits,
+-		.maxlen		= sizeof(int),
+-		.mode		= 0644,
+-		.proc_handler	= proc_dointvec_minmax,
+-		.extra1		= &min_read_thresh,
+-		.extra2		= &max_read_thresh,
++		.proc_handler	= proc_dointvec,
+ 	},
+ 	{
+ 		.procname	= "write_wakeup_threshold",
+-		.data		= &random_write_wakeup_bits,
++		.data		= &sysctl_random_write_wakeup_bits,
+ 		.maxlen		= sizeof(int),
+ 		.mode		= 0644,
+-		.proc_handler	= proc_dointvec_minmax,
+-		.extra1		= &min_write_thresh,
+-		.extra2		= &max_write_thresh,
++		.proc_handler	= proc_do_rointvec,
+ 	},
+ 	{
+ 		.procname	= "urandom_min_reseed_secs",
+-		.data		= &random_min_urandom_seed,
++		.data		= &sysctl_random_min_urandom_seed,
+ 		.maxlen		= sizeof(int),
+ 		.mode		= 0644,
+-		.proc_handler	= proc_dointvec,
++		.proc_handler	= proc_do_rointvec,
+ 	},
+ 	{
+ 		.procname	= "boot_id",
+ 		.data		= &sysctl_bootid,
+-		.maxlen		= 16,
+ 		.mode		= 0444,
+ 		.proc_handler	= proc_do_uuid,
+ 	},
+ 	{
+ 		.procname	= "uuid",
+-		.maxlen		= 16,
+ 		.mode		= 0444,
+ 		.proc_handler	= proc_do_uuid,
+ 	},
+-#ifdef ADD_INTERRUPT_BENCH
+-	{
+-		.procname	= "add_interrupt_avg_cycles",
+-		.data		= &avg_cycles,
+-		.maxlen		= sizeof(avg_cycles),
+-		.mode		= 0444,
+-		.proc_handler	= proc_doulongvec_minmax,
+-	},
+-	{
+-		.procname	= "add_interrupt_avg_deviation",
+-		.data		= &avg_deviation,
+-		.maxlen		= sizeof(avg_deviation),
+-		.mode		= 0444,
+-		.proc_handler	= proc_doulongvec_minmax,
+-	},
+-#endif
+ 	{ }
+ };
+-#endif 	/* CONFIG_SYSCTL */
+-
+-struct batched_entropy {
+-	union {
+-		unsigned long entropy_long[CHACHA20_BLOCK_SIZE / sizeof(unsigned long)];
+-		unsigned int entropy_int[CHACHA20_BLOCK_SIZE / sizeof(unsigned int)];
+-	};
+-	unsigned int position;
+-};
+-
+-/*
+- * Get a random word for internal kernel use only. The quality of the random
+- * number is good as /dev/urandom, but there is no backtrack protection, with
+- * the goal of being quite fast and not depleting entropy.
+- */
+-static DEFINE_PER_CPU(struct batched_entropy, batched_entropy_long);
+-unsigned long get_random_long(void)
+-{
+-	unsigned long ret;
+-	struct batched_entropy *batch;
+-
+-	batch = &get_cpu_var(batched_entropy_long);
+-	if (batch->position % ARRAY_SIZE(batch->entropy_long) == 0) {
+-		extract_crng((u8 *)batch->entropy_long);
+-		batch->position = 0;
+-	}
+-	ret = batch->entropy_long[batch->position++];
+-	put_cpu_var(batched_entropy_long);
+-	return ret;
+-}
+-EXPORT_SYMBOL(get_random_long);
+-
+-#if BITS_PER_LONG == 32
+-unsigned int get_random_int(void)
+-{
+-	return get_random_long();
+-}
+-#else
+-static DEFINE_PER_CPU(struct batched_entropy, batched_entropy_int);
+-unsigned int get_random_int(void)
+-{
+-	unsigned int ret;
+-	struct batched_entropy *batch;
+-
+-	batch = &get_cpu_var(batched_entropy_int);
+-	if (batch->position % ARRAY_SIZE(batch->entropy_int) == 0) {
+-		extract_crng((u8 *)batch->entropy_int);
+-		batch->position = 0;
+-	}
+-	ret = batch->entropy_int[batch->position++];
+-	put_cpu_var(batched_entropy_int);
+-	return ret;
+-}
+-#endif
+-EXPORT_SYMBOL(get_random_int);
+-
+-/**
+- * 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);
+-}
+-
+-/* Interface for in-kernel drivers of true hardware RNGs.
+- * Those devices may produce endless random bits and will be throttled
+- * when our pool is full.
+- */
+-void add_hwgenerator_randomness(const char *buffer, size_t count,
+-				size_t entropy)
+-{
+-	struct entropy_store *poolp = &input_pool;
+-
+-	if (unlikely(crng_init == 0)) {
+-		crng_fast_load(buffer, count);
+-		return;
+-	}
+-
+-	/* Suspend writing if we're above the trickle threshold.
+-	 * We'll be woken up again once below random_write_wakeup_thresh,
+-	 * or when the calling thread is about to terminate.
+-	 */
+-	wait_event_interruptible(random_write_wait, kthread_should_stop() ||
+-			ENTROPY_BITS(&input_pool) <= random_write_wakeup_bits);
+-	mix_pool_bytes(poolp, buffer, count);
+-	credit_entropy_bits(poolp, entropy);
+-}
+-EXPORT_SYMBOL_GPL(add_hwgenerator_randomness);
++#endif	/* CONFIG_SYSCTL */
+diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
+index 9a0d0d0ad6d0f..3248aa7a35b36 100644
+--- a/drivers/hv/vmbus_drv.c
++++ b/drivers/hv/vmbus_drv.c
+@@ -828,7 +828,7 @@ static void vmbus_isr(void)
+ 			tasklet_schedule(hv_context.msg_dpc[cpu]);
+ 	}
+ 
+-	add_interrupt_randomness(HYPERVISOR_CALLBACK_VECTOR, 0);
++	add_interrupt_randomness(HYPERVISOR_CALLBACK_VECTOR);
+ }
+ 
+ 
+diff --git a/drivers/irqchip/irq-gic-realview.c b/drivers/irqchip/irq-gic-realview.c
+index 54c296401525c..61024882c6854 100644
+--- a/drivers/irqchip/irq-gic-realview.c
++++ b/drivers/irqchip/irq-gic-realview.c
+@@ -56,6 +56,7 @@ realview_gic_of_init(struct device_node *node, struct device_node *parent)
+ 
+ 	/* The PB11MPCore GIC needs to be configured in the syscon */
+ 	map = syscon_node_to_regmap(np);
++	of_node_put(np);
+ 	if (!IS_ERR(map)) {
+ 		/* new irq mode with no DCC */
+ 		regmap_write(map, REALVIEW_SYS_LOCK_OFFSET,
+diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
+index 2ab6060031a43..9ae24ffb9b09c 100644
+--- a/drivers/irqchip/irq-gic-v3.c
++++ b/drivers/irqchip/irq-gic-v3.c
+@@ -982,7 +982,7 @@ static int get_cpu_number(struct device_node *dn)
+ {
+ 	const __be32 *cell;
+ 	u64 hwid;
+-	int i;
++	int cpu;
+ 
+ 	cell = of_get_property(dn, "reg", NULL);
+ 	if (!cell)
+@@ -996,9 +996,9 @@ static int get_cpu_number(struct device_node *dn)
+ 	if (hwid & ~MPIDR_HWID_BITMASK)
+ 		return -1;
+ 
+-	for (i = 0; i < num_possible_cpus(); i++)
+-		if (cpu_logical_map(i) == hwid)
+-			return i;
++	for_each_possible_cpu(cpu)
++		if (cpu_logical_map(cpu) == hwid)
++			return cpu;
+ 
+ 	return -1;
+ }
+diff --git a/drivers/misc/atmel-ssc.c b/drivers/misc/atmel-ssc.c
+index 8c9a444d61d3c..65bc573d6ab44 100644
+--- a/drivers/misc/atmel-ssc.c
++++ b/drivers/misc/atmel-ssc.c
+@@ -190,9 +190,9 @@ static int ssc_probe(struct platform_device *pdev)
+ 	clk_disable_unprepare(ssc->clk);
+ 
+ 	ssc->irq = platform_get_irq(pdev, 0);
+-	if (!ssc->irq) {
++	if (ssc->irq < 0) {
+ 		dev_dbg(&pdev->dev, "could not get irq\n");
+-		return -ENXIO;
++		return ssc->irq;
+ 	}
+ 
+ 	mutex_lock(&user_lock);
+diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+index 84d6679572210..61a9b60ab0225 100644
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -527,6 +527,17 @@ static inline void mtk_rx_get_desc(struct mtk_rx_dma *rxd,
+ 	rxd->rxd4 = READ_ONCE(dma_rxd->rxd4);
+ }
+ 
++static void *mtk_max_lro_buf_alloc(gfp_t gfp_mask)
++{
++	unsigned int size = mtk_max_frag_size(MTK_MAX_LRO_RX_LENGTH);
++	unsigned long data;
++
++	data = __get_free_pages(gfp_mask | __GFP_COMP | __GFP_NOWARN,
++				get_order(size));
++
++	return (void *)data;
++}
++
+ /* the qdma core needs scratch memory to be setup */
+ static int mtk_init_fq_dma(struct mtk_eth *eth)
+ {
+@@ -928,7 +939,10 @@ static int mtk_poll_rx(struct napi_struct *napi, int budget,
+ 			goto release_desc;
+ 
+ 		/* alloc new buffer */
+-		new_data = napi_alloc_frag(ring->frag_size);
++		if (ring->frag_size <= PAGE_SIZE)
++			new_data = napi_alloc_frag(ring->frag_size);
++		else
++			new_data = mtk_max_lro_buf_alloc(GFP_ATOMIC);
+ 		if (unlikely(!new_data)) {
+ 			netdev->stats.rx_dropped++;
+ 			goto release_desc;
+@@ -1231,7 +1245,10 @@ static int mtk_rx_alloc(struct mtk_eth *eth, int ring_no, int rx_flag)
+ 		return -ENOMEM;
+ 
+ 	for (i = 0; i < rx_dma_size; i++) {
+-		ring->data[i] = netdev_alloc_frag(ring->frag_size);
++		if (ring->frag_size <= PAGE_SIZE)
++			ring->data[i] = netdev_alloc_frag(ring->frag_size);
++		else
++			ring->data[i] = mtk_max_lro_buf_alloc(GFP_KERNEL);
+ 		if (!ring->data[i])
+ 			return -ENOMEM;
+ 	}
+diff --git a/drivers/nfc/nfcmrvl/usb.c b/drivers/nfc/nfcmrvl/usb.c
+index 585a0f20835b1..3263e2a2bdfd3 100644
+--- a/drivers/nfc/nfcmrvl/usb.c
++++ b/drivers/nfc/nfcmrvl/usb.c
+@@ -401,13 +401,25 @@ static void nfcmrvl_play_deferred(struct nfcmrvl_usb_drv_data *drv_data)
+ 	int err;
+ 
+ 	while ((urb = usb_get_from_anchor(&drv_data->deferred))) {
++		usb_anchor_urb(urb, &drv_data->tx_anchor);
++
+ 		err = usb_submit_urb(urb, GFP_ATOMIC);
+-		if (err)
++		if (err) {
++			kfree(urb->setup_packet);
++			usb_unanchor_urb(urb);
++			usb_free_urb(urb);
+ 			break;
++		}
+ 
+ 		drv_data->tx_in_flight++;
++		usb_free_urb(urb);
++	}
++
++	/* Cleanup the rest deferred urbs. */
++	while ((urb = usb_get_from_anchor(&drv_data->deferred))) {
++		kfree(urb->setup_packet);
++		usb_free_urb(urb);
+ 	}
+-	usb_scuttle_anchored_urbs(&drv_data->deferred);
+ }
+ 
+ static int nfcmrvl_resume(struct usb_interface *intf)
+diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
+index 6a239c9bbf59b..e797fa92c90dd 100644
+--- a/drivers/of/fdt.c
++++ b/drivers/of/fdt.c
+@@ -27,6 +27,7 @@
+ #include <linux/debugfs.h>
+ #include <linux/serial_core.h>
+ #include <linux/sysfs.h>
++#include <linux/random.h>
+ 
+ #include <asm/setup.h>  /* for COMMAND_LINE_SIZE */
+ #include <asm/page.h>
+@@ -1068,6 +1069,7 @@ int __init early_init_dt_scan_chosen(unsigned long node, const char *uname,
+ {
+ 	int l;
+ 	const char *p;
++	const void *rng_seed;
+ 
+ 	pr_debug("search \"chosen\", depth: %d, uname: %s\n", depth, uname);
+ 
+@@ -1102,6 +1104,14 @@ int __init early_init_dt_scan_chosen(unsigned long node, const char *uname,
+ 
+ 	pr_debug("Command line is: %s\n", (char*)data);
+ 
++	rng_seed = of_get_flat_dt_prop(node, "rng-seed", &l);
++	if (rng_seed && l > 0) {
++		add_bootloader_randomness(rng_seed, l);
++
++		/* try to clear seed so it won't be found. */
++		fdt_nop_property(initial_boot_params, node, "rng-seed");
++	}
++
+ 	/* break now */
+ 	return 1;
+ }
+@@ -1203,8 +1213,6 @@ bool __init early_init_dt_verify(void *params)
+ 
+ 	/* Setup flat device-tree pointer */
+ 	initial_boot_params = params;
+-	of_fdt_crc32 = crc32_be(~0, initial_boot_params,
+-				fdt_totalsize(initial_boot_params));
+ 	return true;
+ }
+ 
+@@ -1230,6 +1238,8 @@ bool __init early_init_dt_scan(void *params)
+ 		return false;
+ 
+ 	early_init_dt_scan_nodes();
++	of_fdt_crc32 = crc32_be(~0, initial_boot_params,
++				fdt_totalsize(initial_boot_params));
+ 	return true;
+ }
+ 
+diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c
+index 30b5f65b29d15..7f230d0b2fd62 100644
+--- a/drivers/scsi/lpfc/lpfc_nportdisc.c
++++ b/drivers/scsi/lpfc/lpfc_nportdisc.c
+@@ -633,7 +633,8 @@ lpfc_rcv_logo(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
+ 	else
+ 		lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL);
+ 	if (ndlp->nlp_DID == Fabric_DID) {
+-		if (vport->port_state <= LPFC_FDISC)
++		if (vport->port_state <= LPFC_FDISC ||
++		    vport->fc_flag & FC_PT2PT)
+ 			goto out;
+ 		lpfc_linkdown_port(vport);
+ 		spin_lock_irq(shost->host_lock);
+diff --git a/drivers/scsi/vmw_pvscsi.h b/drivers/scsi/vmw_pvscsi.h
+index d41292ef85f2f..98ad17cb6643d 100644
+--- a/drivers/scsi/vmw_pvscsi.h
++++ b/drivers/scsi/vmw_pvscsi.h
+@@ -333,8 +333,8 @@ struct PVSCSIRingReqDesc {
+ 	u8	tag;
+ 	u8	bus;
+ 	u8	target;
+-	u8	vcpuHint;
+-	u8	unused[59];
++	u16	vcpuHint;
++	u8	unused[58];
+ } __packed;
+ 
+ /*
+diff --git a/drivers/staging/comedi/drivers/vmk80xx.c b/drivers/staging/comedi/drivers/vmk80xx.c
+index 36470ee065967..6010c047f4f86 100644
+--- a/drivers/staging/comedi/drivers/vmk80xx.c
++++ b/drivers/staging/comedi/drivers/vmk80xx.c
+@@ -694,7 +694,7 @@ static int vmk80xx_alloc_usb_buffers(struct comedi_device *dev)
+ 	if (!devpriv->usb_rx_buf)
+ 		return -ENOMEM;
+ 
+-	size = max(usb_endpoint_maxp(devpriv->ep_rx), MIN_BUF_SIZE);
++	size = max(usb_endpoint_maxp(devpriv->ep_tx), MIN_BUF_SIZE);
+ 	devpriv->usb_tx_buf = kzalloc(size, GFP_KERNEL);
+ 	if (!devpriv->usb_tx_buf)
+ 		return -ENOMEM;
+diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c
+index 2d83f1dfb4d69..d3f17b23ac61f 100644
+--- a/drivers/tty/serial/8250/8250_port.c
++++ b/drivers/tty/serial/8250/8250_port.c
+@@ -1473,6 +1473,8 @@ static inline void __stop_tx(struct uart_8250_port *p)
+ 
+ 	if (em485) {
+ 		unsigned char lsr = serial_in(p, UART_LSR);
++		p->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS;
++
+ 		/*
+ 		 * To provide required timeing and allow FIFO transfer,
+ 		 * __stop_tx_rs485() must be called only when both FIFO and
+diff --git a/drivers/usb/gadget/udc/lpc32xx_udc.c b/drivers/usb/gadget/udc/lpc32xx_udc.c
+index 7107931617953..498a44ae2b925 100644
+--- a/drivers/usb/gadget/udc/lpc32xx_udc.c
++++ b/drivers/usb/gadget/udc/lpc32xx_udc.c
+@@ -3034,6 +3034,7 @@ static int lpc32xx_udc_probe(struct platform_device *pdev)
+ 	}
+ 
+ 	udc->isp1301_i2c_client = isp1301_get_client(isp1301_node);
++	of_node_put(isp1301_node);
+ 	if (!udc->isp1301_i2c_client) {
+ 		retval = -EPROBE_DEFER;
+ 		goto phy_fail;
+diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c
+index e98532feb0cce..8e49eb68896ac 100644
+--- a/drivers/usb/serial/io_ti.c
++++ b/drivers/usb/serial/io_ti.c
+@@ -172,6 +172,7 @@ static const struct usb_device_id edgeport_2port_id_table[] = {
+ 	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_8S) },
+ 	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_416) },
+ 	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_416B) },
++	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_E5805A) },
+ 	{ }
+ };
+ 
+@@ -210,6 +211,7 @@ static const struct usb_device_id id_table_combined[] = {
+ 	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_8S) },
+ 	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_416) },
+ 	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_416B) },
++	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_E5805A) },
+ 	{ }
+ };
+ 
+diff --git a/drivers/usb/serial/io_usbvend.h b/drivers/usb/serial/io_usbvend.h
+index 6f6a856bc37cd..a470262dcf48b 100644
+--- a/drivers/usb/serial/io_usbvend.h
++++ b/drivers/usb/serial/io_usbvend.h
+@@ -215,6 +215,7 @@
+ //
+ // Definitions for other product IDs
+ #define ION_DEVICE_ID_MT4X56USB			0x1403	// OEM device
++#define ION_DEVICE_ID_E5805A			0x1A01  // OEM device (rebranded Edgeport/4)
+ 
+ 
+ #define	GENERATION_ID_FROM_USB_PRODUCT_ID(ProductId)				\
+diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
+index 5b198d881a40a..8add5a762f219 100644
+--- a/drivers/usb/serial/option.c
++++ b/drivers/usb/serial/option.c
+@@ -430,6 +430,8 @@ static void option_instat_callback(struct urb *urb);
+ #define CINTERION_PRODUCT_CLS8			0x00b0
+ #define CINTERION_PRODUCT_MV31_MBIM		0x00b3
+ #define CINTERION_PRODUCT_MV31_RMNET		0x00b7
++#define CINTERION_PRODUCT_MV31_2_MBIM		0x00b8
++#define CINTERION_PRODUCT_MV31_2_RMNET		0x00b9
+ #define CINTERION_PRODUCT_MV32_WA		0x00f1
+ #define CINTERION_PRODUCT_MV32_WB		0x00f2
+ 
+@@ -1953,6 +1955,10 @@ static const struct usb_device_id option_ids[] = {
+ 	  .driver_info = RSVD(3)},
+ 	{ USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_MV31_RMNET, 0xff),
+ 	  .driver_info = RSVD(0)},
++	{ USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_MV31_2_MBIM, 0xff),
++	  .driver_info = RSVD(3)},
++	{ USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_MV31_2_RMNET, 0xff),
++	  .driver_info = RSVD(0)},
+ 	{ USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_MV32_WA, 0xff),
+ 	  .driver_info = RSVD(3)},
+ 	{ USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_MV32_WB, 0xff),
+diff --git a/drivers/virtio/virtio_mmio.c b/drivers/virtio/virtio_mmio.c
+index 50840984fbfac..f62da3b7c27b4 100644
+--- a/drivers/virtio/virtio_mmio.c
++++ b/drivers/virtio/virtio_mmio.c
+@@ -630,6 +630,7 @@ static int vm_cmdline_set(const char *device,
+ 	if (!vm_cmdline_parent_registered) {
+ 		err = device_register(&vm_cmdline_parent);
+ 		if (err) {
++			put_device(&vm_cmdline_parent);
+ 			pr_err("Failed to register parent device!\n");
+ 			return err;
+ 		}
+diff --git a/fs/9p/vfs_inode_dotl.c b/fs/9p/vfs_inode_dotl.c
+index 425bc1a2b8c14..77a97195ef355 100644
+--- a/fs/9p/vfs_inode_dotl.c
++++ b/fs/9p/vfs_inode_dotl.c
+@@ -656,14 +656,10 @@ v9fs_stat2inode_dotl(struct p9_stat_dotl *stat, struct inode *inode,
+ 		if (stat->st_result_mask & P9_STATS_NLINK)
+ 			set_nlink(inode, stat->st_nlink);
+ 		if (stat->st_result_mask & P9_STATS_MODE) {
+-			inode->i_mode = stat->st_mode;
+-			if ((S_ISBLK(inode->i_mode)) ||
+-						(S_ISCHR(inode->i_mode)))
+-				init_special_inode(inode, inode->i_mode,
+-								inode->i_rdev);
++			mode = stat->st_mode & S_IALLUGO;
++			mode |= inode->i_mode & ~S_IALLUGO;
++			inode->i_mode = mode;
+ 		}
+-		if (stat->st_result_mask & P9_STATS_RDEV)
+-			inode->i_rdev = new_decode_dev(stat->st_rdev);
+ 		if (!(flags & V9FS_STAT2INODE_KEEP_ISIZE) &&
+ 		    stat->st_result_mask & P9_STATS_SIZE)
+ 			v9fs_i_size_write(inode, stat->st_size);
+diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
+index 2a7fb2cf19b81..f39b656012339 100644
+--- a/fs/ext4/mballoc.c
++++ b/fs/ext4/mballoc.c
+@@ -3142,6 +3142,15 @@ ext4_mb_normalize_request(struct ext4_allocation_context *ac,
+ 	size = size >> bsbits;
+ 	start = start_off >> bsbits;
+ 
++	/*
++	 * For tiny groups (smaller than 8MB) the chosen allocation
++	 * alignment may be larger than group size. Make sure the
++	 * alignment does not move allocation to a different group which
++	 * makes mballoc fail assertions later.
++	 */
++	start = max(start, rounddown(ac->ac_o_ex.fe_logical,
++			(ext4_lblk_t)EXT4_BLOCKS_PER_GROUP(ac->ac_sb)));
++
+ 	/* don't cover already allocated blocks in selected range */
+ 	if (ar->pleft && start <= ar->lleft) {
+ 		size -= ar->lleft + 1 - start;
+diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
+index 159d259e5e5e9..edf78728ed322 100644
+--- a/fs/ext4/namei.c
++++ b/fs/ext4/namei.c
+@@ -1726,7 +1726,8 @@ static struct ext4_dir_entry_2 *do_split(handle_t *handle, struct inode *dir,
+ 			struct dx_hash_info *hinfo)
+ {
+ 	unsigned blocksize = dir->i_sb->s_blocksize;
+-	unsigned count, continued;
++	unsigned continued;
++	int count;
+ 	struct buffer_head *bh2;
+ 	ext4_lblk_t newblock;
+ 	u32 hash2;
+diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c
+index 51fa706707a3b..c367129dcdc16 100644
+--- a/fs/ext4/resize.c
++++ b/fs/ext4/resize.c
+@@ -51,6 +51,16 @@ int ext4_resize_begin(struct super_block *sb)
+ 	if (!capable(CAP_SYS_RESOURCE))
+ 		return -EPERM;
+ 
++	/*
++	 * If the reserved GDT blocks is non-zero, the resize_inode feature
++	 * should always be set.
++	 */
++	if (EXT4_SB(sb)->s_es->s_reserved_gdt_blocks &&
++	    !ext4_has_feature_resize_inode(sb)) {
++		ext4_error(sb, "resize_inode disabled but reserved GDT blocks non-zero");
++		return -EFSCORRUPTED;
++	}
++
+ 	/*
+ 	 * If we are not using the primary superblock/GDT copy don't resize,
+          * because the user tools have no way of handling this.  Probably a
+diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c
+index 585c52dbb2e39..13cf7c260a831 100644
+--- a/fs/fuse/dev.c
++++ b/fs/fuse/dev.c
+@@ -992,7 +992,17 @@ static int fuse_copy_page(struct fuse_copy_state *cs, struct page **pagep,
+ 
+ 	while (count) {
+ 		if (cs->write && cs->pipebufs && page) {
+-			return fuse_ref_page(cs, page, offset, count);
++			/*
++			 * Can't control lifetime of pipe buffers, so always
++			 * copy user pages.
++			 */
++			if (cs->req->user_pages) {
++				err = fuse_copy_fill(cs);
++				if (err)
++					return err;
++			} else {
++				return fuse_ref_page(cs, page, offset, count);
++			}
+ 		} else if (!cs->len) {
+ 			if (cs->move_pages && page &&
+ 			    offset == 0 && count == PAGE_SIZE) {
+diff --git a/fs/fuse/file.c b/fs/fuse/file.c
+index 8aef8e56eb1b6..aa4f0d632bed4 100644
+--- a/fs/fuse/file.c
++++ b/fs/fuse/file.c
+@@ -1319,6 +1319,7 @@ static int fuse_get_user_pages(struct fuse_req *req, struct iov_iter *ii,
+ 			(PAGE_SIZE - ret) & (PAGE_SIZE - 1);
+ 	}
+ 
++	req->user_pages = true;
+ 	if (write)
+ 		req->in.argpages = 1;
+ 	else
+diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h
+index 7e4b0e298bc73..6104534ddb7e6 100644
+--- a/fs/fuse/fuse_i.h
++++ b/fs/fuse/fuse_i.h
+@@ -310,6 +310,8 @@ struct fuse_req {
+ 	/** refcount */
+ 	atomic_t count;
+ 
++	bool user_pages;
++
+ 	/** Unique ID for the interrupt request */
+ 	u64 intr_unique;
+ 
+diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c
+index f19cded49b29d..317d22f844924 100644
+--- a/fs/nfs/pnfs.c
++++ b/fs/nfs/pnfs.c
+@@ -1753,6 +1753,12 @@ lookup_again:
+ 			/* Fallthrough */
+ 		case -EAGAIN:
+ 			break;
++		case -ENODATA:
++			/* The server returned NFS4ERR_LAYOUTUNAVAILABLE */
++			pnfs_layout_set_fail_bit(
++				lo, pnfs_iomode_to_fail_bit(iomode));
++			lseg = NULL;
++			goto out_put_layout_hdr;
+ 		default:
+ 			if (!nfs_error_is_fatal(PTR_ERR(lseg))) {
+ 				pnfs_layout_clear_fail_bit(lo, pnfs_iomode_to_fail_bit(iomode));
+diff --git a/include/crypto/blake2s.h b/include/crypto/blake2s.h
+new file mode 100644
+index 0000000000000..d439496fa6baa
+--- /dev/null
++++ b/include/crypto/blake2s.h
+@@ -0,0 +1,102 @@
++/* SPDX-License-Identifier: GPL-2.0 OR MIT */
++/*
++ * Copyright (C) 2015-2019 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
++ */
++
++#ifndef _CRYPTO_BLAKE2S_H
++#define _CRYPTO_BLAKE2S_H
++
++#include <linux/bug.h>
++#include <linux/types.h>
++#include <linux/kernel.h>
++#include <linux/string.h>
++
++enum blake2s_lengths {
++	BLAKE2S_BLOCK_SIZE = 64,
++	BLAKE2S_HASH_SIZE = 32,
++	BLAKE2S_KEY_SIZE = 32,
++
++	BLAKE2S_128_HASH_SIZE = 16,
++	BLAKE2S_160_HASH_SIZE = 20,
++	BLAKE2S_224_HASH_SIZE = 28,
++	BLAKE2S_256_HASH_SIZE = 32,
++};
++
++struct blake2s_state {
++	u32 h[8];
++	u32 t[2];
++	u32 f[2];
++	u8 buf[BLAKE2S_BLOCK_SIZE];
++	unsigned int buflen;
++	unsigned int outlen;
++};
++
++enum blake2s_iv {
++	BLAKE2S_IV0 = 0x6A09E667UL,
++	BLAKE2S_IV1 = 0xBB67AE85UL,
++	BLAKE2S_IV2 = 0x3C6EF372UL,
++	BLAKE2S_IV3 = 0xA54FF53AUL,
++	BLAKE2S_IV4 = 0x510E527FUL,
++	BLAKE2S_IV5 = 0x9B05688CUL,
++	BLAKE2S_IV6 = 0x1F83D9ABUL,
++	BLAKE2S_IV7 = 0x5BE0CD19UL,
++};
++
++void blake2s_update(struct blake2s_state *state, const u8 *in, size_t inlen);
++void blake2s_final(struct blake2s_state *state, u8 *out);
++
++static inline void blake2s_init_param(struct blake2s_state *state,
++				      const u32 param)
++{
++	*state = (struct blake2s_state){{
++		BLAKE2S_IV0 ^ param,
++		BLAKE2S_IV1,
++		BLAKE2S_IV2,
++		BLAKE2S_IV3,
++		BLAKE2S_IV4,
++		BLAKE2S_IV5,
++		BLAKE2S_IV6,
++		BLAKE2S_IV7,
++	}};
++}
++
++static inline void blake2s_init(struct blake2s_state *state,
++				const size_t outlen)
++{
++	blake2s_init_param(state, 0x01010000 | outlen);
++	state->outlen = outlen;
++}
++
++static inline void blake2s_init_key(struct blake2s_state *state,
++				    const size_t outlen, const void *key,
++				    const size_t keylen)
++{
++	WARN_ON(IS_ENABLED(DEBUG) && (!outlen || outlen > BLAKE2S_HASH_SIZE ||
++		!key || !keylen || keylen > BLAKE2S_KEY_SIZE));
++
++	blake2s_init_param(state, 0x01010000 | keylen << 8 | outlen);
++	memcpy(state->buf, key, keylen);
++	state->buflen = BLAKE2S_BLOCK_SIZE;
++	state->outlen = outlen;
++}
++
++static inline void blake2s(u8 *out, const u8 *in, const u8 *key,
++			   const size_t outlen, const size_t inlen,
++			   const size_t keylen)
++{
++	struct blake2s_state state;
++
++	WARN_ON(IS_ENABLED(DEBUG) && ((!in && inlen > 0) || !out || !outlen ||
++		outlen > BLAKE2S_HASH_SIZE || keylen > BLAKE2S_KEY_SIZE ||
++		(!key && keylen)));
++
++	if (keylen)
++		blake2s_init_key(&state, outlen, key, keylen);
++	else
++		blake2s_init(&state, outlen);
++
++	blake2s_update(&state, in, inlen);
++	blake2s_final(&state, out);
++}
++
++#endif /* _CRYPTO_BLAKE2S_H */
+diff --git a/include/crypto/chacha20.h b/include/crypto/chacha20.h
+index 20d20f681a72c..0b8deb5e82915 100644
+--- a/include/crypto/chacha20.h
++++ b/include/crypto/chacha20.h
+@@ -16,11 +16,26 @@ struct chacha20_ctx {
+ 	u32 key[8];
+ };
+ 
+-void chacha20_block(u32 *state, void *stream);
++void chacha20_block(u32 *state, u8 *stream);
+ void crypto_chacha20_init(u32 *state, struct chacha20_ctx *ctx, u8 *iv);
+ int crypto_chacha20_setkey(struct crypto_tfm *tfm, const u8 *key,
+ 			   unsigned int keysize);
+ int crypto_chacha20_crypt(struct blkcipher_desc *desc, struct scatterlist *dst,
+ 			  struct scatterlist *src, unsigned int nbytes);
+ 
++enum chacha_constants { /* expand 32-byte k */
++	CHACHA_CONSTANT_EXPA = 0x61707865U,
++	CHACHA_CONSTANT_ND_3 = 0x3320646eU,
++	CHACHA_CONSTANT_2_BY = 0x79622d32U,
++	CHACHA_CONSTANT_TE_K = 0x6b206574U
++};
++
++static inline void chacha_init_consts(u32 *state)
++{
++	state[0]  = CHACHA_CONSTANT_EXPA;
++	state[1]  = CHACHA_CONSTANT_ND_3;
++	state[2]  = CHACHA_CONSTANT_2_BY;
++	state[3]  = CHACHA_CONSTANT_TE_K;
++}
++
+ #endif
+diff --git a/include/crypto/drbg.h b/include/crypto/drbg.h
+index 22f884c97387e..19b44179bb7c7 100644
+--- a/include/crypto/drbg.h
++++ b/include/crypto/drbg.h
+@@ -105,6 +105,12 @@ struct drbg_test_data {
+ 	struct drbg_string *testentropy; /* TEST PARAMETER: test entropy */
+ };
+ 
++enum drbg_seed_state {
++	DRBG_SEED_STATE_UNSEEDED,
++	DRBG_SEED_STATE_PARTIAL, /* Seeded with !rng_is_initialized() */
++	DRBG_SEED_STATE_FULL,
++};
++
+ struct drbg_state {
+ 	struct mutex drbg_mutex;	/* lock around DRBG */
+ 	unsigned char *V;	/* internal state 10.1.1.1 1a) */
+@@ -129,14 +135,14 @@ struct drbg_state {
+ 	struct completion ctr_completion;	/* CTR mode async handler */
+ 	int ctr_async_err;			/* CTR mode async error */
+ 
+-	bool seeded;		/* DRBG fully seeded? */
++	enum drbg_seed_state seeded;		/* DRBG fully seeded? */
+ 	bool pr;		/* Prediction resistance enabled? */
+-	struct work_struct seed_work;	/* asynchronous seeding support */
++	bool fips_primed;	/* Continuous test primed? */
++	unsigned char *prev;	/* FIPS 140-2 continuous test value */
+ 	struct crypto_rng *jent;
+ 	const struct drbg_state_ops *d_ops;
+ 	const struct drbg_core *core;
+ 	struct drbg_string test_data;
+-	struct random_ready_callback random_ready;
+ };
+ 
+ static inline __u8 drbg_statelen(struct drbg_state *drbg)
+@@ -184,11 +190,7 @@ static inline size_t drbg_max_addtl(struct drbg_state *drbg)
+ static inline size_t drbg_max_requests(struct drbg_state *drbg)
+ {
+ 	/* SP800-90A requires 2**48 maximum requests before reseeding */
+-#if (__BITS_PER_LONG == 32)
+-	return SIZE_MAX;
+-#else
+-	return (1UL<<48);
+-#endif
++	return (1<<20);
+ }
+ 
+ /*
+diff --git a/include/crypto/internal/blake2s.h b/include/crypto/internal/blake2s.h
+new file mode 100644
+index 0000000000000..3ba066845b699
+--- /dev/null
++++ b/include/crypto/internal/blake2s.h
+@@ -0,0 +1,19 @@
++/* SPDX-License-Identifier: GPL-2.0 OR MIT */
++
++#ifndef _CRYPTO_INTERNAL_BLAKE2S_H
++#define _CRYPTO_INTERNAL_BLAKE2S_H
++
++#include <crypto/blake2s.h>
++
++void blake2s_compress_generic(struct blake2s_state *state,const u8 *block,
++			      size_t nblocks, const u32 inc);
++
++void blake2s_compress_arch(struct blake2s_state *state,const u8 *block,
++			   size_t nblocks, const u32 inc);
++
++static inline void blake2s_set_lastblock(struct blake2s_state *state)
++{
++	state->f[0] = -1;
++}
++
++#endif /* _CRYPTO_INTERNAL_BLAKE2S_H */
+diff --git a/include/linux/byteorder/generic.h b/include/linux/byteorder/generic.h
+index 89f67c1c31606..9cf01d7bb7c0a 100644
+--- a/include/linux/byteorder/generic.h
++++ b/include/linux/byteorder/generic.h
+@@ -155,6 +155,23 @@ static inline void le64_add_cpu(__le64 *var, u64 val)
+ 	*var = cpu_to_le64(le64_to_cpu(*var) + val);
+ }
+ 
++/* XXX: this stuff can be optimized */
++static inline void le32_to_cpu_array(u32 *buf, unsigned int words)
++{
++	while (words--) {
++		__le32_to_cpus(buf);
++		buf++;
++	}
++}
++
++static inline void cpu_to_le32_array(u32 *buf, unsigned int words)
++{
++	while (words--) {
++		__cpu_to_le32s(buf);
++		buf++;
++	}
++}
++
+ static inline void be16_add_cpu(__be16 *var, u16 val)
+ {
+ 	*var = cpu_to_be16(be16_to_cpu(*var) + val);
+diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h
+index 1ab0273560aeb..8160ad1885dc2 100644
+--- a/include/linux/cpuhotplug.h
++++ b/include/linux/cpuhotplug.h
+@@ -29,6 +29,7 @@ enum cpuhp_state {
+ 	CPUHP_ACPI_CPUDRV_DEAD,
+ 	CPUHP_S390_PFAULT_DEAD,
+ 	CPUHP_BLK_MQ_DEAD,
++	CPUHP_RANDOM_PREPARE,
+ 	CPUHP_WORKQUEUE_PREP,
+ 	CPUHP_POWER_NUMA_PREPARE,
+ 	CPUHP_HRTIMERS_PREPARE,
+@@ -119,6 +120,7 @@ enum cpuhp_state {
+ 	CPUHP_AP_PERF_ARM_CCN_ONLINE,
+ 	CPUHP_AP_PERF_ARM_L2X0_ONLINE,
+ 	CPUHP_AP_WORKQUEUE_ONLINE,
++	CPUHP_AP_RANDOM_ONLINE,
+ 	CPUHP_AP_RCUTREE_ONLINE,
+ 	CPUHP_AP_NOTIFY_ONLINE,
+ 	CPUHP_AP_ONLINE_DYN,
+diff --git a/include/linux/hw_random.h b/include/linux/hw_random.h
+index 34a0dc18f3271..48e28f7844fe9 100644
+--- a/include/linux/hw_random.h
++++ b/include/linux/hw_random.h
+@@ -60,7 +60,5 @@ extern int devm_hwrng_register(struct device *dev, struct hwrng *rng);
+ /** Unregister a Hardware Random Number Generator driver. */
+ extern void hwrng_unregister(struct hwrng *rng);
+ extern void devm_hwrng_unregister(struct device *dve, struct hwrng *rng);
+-/** Feed random bits into the pool. */
+-extern void add_hwgenerator_randomness(const char *buffer, size_t count, size_t entropy);
+ 
+ #endif /* LINUX_HWRANDOM_H_ */
+diff --git a/include/linux/miscdevice.h b/include/linux/miscdevice.h
+index 722698a43d79c..659f58617b9e3 100644
+--- a/include/linux/miscdevice.h
++++ b/include/linux/miscdevice.h
+@@ -31,6 +31,7 @@
+ #define SGI_MMTIMER		153
+ #define STORE_QUEUE_MINOR	155	/* unused */
+ #define I2O_MINOR		166
++#define HWRNG_MINOR		183
+ #define MICROCODE_MINOR		184
+ #define VFIO_MINOR		196
+ #define TUN_MINOR		200
+diff --git a/include/linux/mm.h b/include/linux/mm.h
+index 81ee5d0b26424..ebfe5b7711531 100644
+--- a/include/linux/mm.h
++++ b/include/linux/mm.h
+@@ -2059,6 +2059,8 @@ extern int install_special_mapping(struct mm_struct *mm,
+ 				   unsigned long addr, unsigned long len,
+ 				   unsigned long flags, struct page **pages);
+ 
++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);
+ 
+ extern unsigned long mmap_region(struct file *file, unsigned long addr,
+diff --git a/include/linux/net.h b/include/linux/net.h
+index 54270c4707cf2..455aa9c1247ca 100644
+--- a/include/linux/net.h
++++ b/include/linux/net.h
+@@ -274,6 +274,8 @@ do {									\
+ 
+ #define net_get_random_once(buf, nbytes)			\
+ 	get_random_once((buf), (nbytes))
++#define net_get_random_once_wait(buf, nbytes)			\
++	get_random_once_wait((buf), (nbytes))
+ 
+ int kernel_sendmsg(struct socket *sock, struct msghdr *msg, struct kvec *vec,
+ 		   size_t num, size_t len);
+diff --git a/include/linux/once.h b/include/linux/once.h
+index 285f12cb40e6a..9c98aaa87cbcd 100644
+--- a/include/linux/once.h
++++ b/include/linux/once.h
+@@ -53,5 +53,7 @@ void __do_once_done(bool *done, struct static_key *once_key,
+ 
+ #define get_random_once(buf, nbytes)					     \
+ 	DO_ONCE(get_random_bytes, (buf), (nbytes))
++#define get_random_once_wait(buf, nbytes)                                    \
++	DO_ONCE(get_random_bytes_wait, (buf), (nbytes))                      \
+ 
+ #endif /* _LINUX_ONCE_H */
+diff --git a/include/linux/prandom.h b/include/linux/prandom.h
+index e20339c78a84c..709e8e69fb39b 100644
+--- a/include/linux/prandom.h
++++ b/include/linux/prandom.h
+@@ -10,6 +10,7 @@
+ 
+ #include <linux/types.h>
+ #include <linux/percpu.h>
++#include <linux/siphash.h>
+ 
+ u32 prandom_u32(void);
+ void prandom_bytes(void *buf, size_t nbytes);
+@@ -21,15 +22,10 @@ void prandom_reseed_late(void);
+  * The core SipHash round function.  Each line can be executed in
+  * parallel given enough CPU resources.
+  */
+-#define PRND_SIPROUND(v0, v1, v2, v3) ( \
+-	v0 += v1, v1 = rol64(v1, 13),  v2 += v3, v3 = rol64(v3, 16), \
+-	v1 ^= v0, v0 = rol64(v0, 32),  v3 ^= v2,                     \
+-	v0 += v3, v3 = rol64(v3, 21),  v2 += v1, v1 = rol64(v1, 17), \
+-	v3 ^= v0,                      v1 ^= v2, v2 = rol64(v2, 32)  \
+-)
++#define PRND_SIPROUND(v0, v1, v2, v3) SIPHASH_PERMUTATION(v0, v1, v2, v3)
+ 
+-#define PRND_K0 (0x736f6d6570736575 ^ 0x6c7967656e657261)
+-#define PRND_K1 (0x646f72616e646f6d ^ 0x7465646279746573)
++#define PRND_K0 (SIPHASH_CONST_0 ^ SIPHASH_CONST_2)
++#define PRND_K1 (SIPHASH_CONST_1 ^ SIPHASH_CONST_3)
+ 
+ #elif BITS_PER_LONG == 32
+ /*
+@@ -37,14 +33,9 @@ void prandom_reseed_late(void);
+  * This is weaker, but 32-bit machines are not used for high-traffic
+  * applications, so there is less output for an attacker to analyze.
+  */
+-#define PRND_SIPROUND(v0, v1, v2, v3) ( \
+-	v0 += v1, v1 = rol32(v1,  5),  v2 += v3, v3 = rol32(v3,  8), \
+-	v1 ^= v0, v0 = rol32(v0, 16),  v3 ^= v2,                     \
+-	v0 += v3, v3 = rol32(v3,  7),  v2 += v1, v1 = rol32(v1, 13), \
+-	v3 ^= v0,                      v1 ^= v2, v2 = rol32(v2, 16)  \
+-)
+-#define PRND_K0 0x6c796765
+-#define PRND_K1 0x74656462
++#define PRND_SIPROUND(v0, v1, v2, v3) HSIPHASH_PERMUTATION(v0, v1, v2, v3)
++#define PRND_K0 (HSIPHASH_CONST_0 ^ HSIPHASH_CONST_2)
++#define PRND_K1 (HSIPHASH_CONST_1 ^ HSIPHASH_CONST_3)
+ 
+ #else
+ #error Unsupported BITS_PER_LONG
+diff --git a/include/linux/random.h b/include/linux/random.h
+index 15cd754544686..291b493fd2e7d 100644
+--- a/include/linux/random.h
++++ b/include/linux/random.h
+@@ -1,50 +1,78 @@
+-/*
+- * include/linux/random.h
+- *
+- * Include file for the random number generator.
+- */
++/* SPDX-License-Identifier: GPL-2.0 */
++
+ #ifndef _LINUX_RANDOM_H
+ #define _LINUX_RANDOM_H
+ 
++#include <linux/bug.h>
++#include <linux/kernel.h>
+ #include <linux/list.h>
+ #include <linux/once.h>
+ 
+ #include <uapi/linux/random.h>
+ 
+-struct random_ready_callback {
+-	struct list_head list;
+-	void (*func)(struct random_ready_callback *rdy);
+-	struct module *owner;
+-};
++struct notifier_block;
+ 
+-extern void add_device_randomness(const void *, unsigned int);
++void add_device_randomness(const void *buf, size_t len);
++void __init 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 *buf, size_t len, size_t entropy);
+ 
+-#if defined(CONFIG_GCC_PLUGIN_LATENT_ENTROPY) && !defined(__CHECKER__)
++#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) {}
++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, int irq_flags) __latent_entropy;
++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)
++{
++	return get_random_u32();
++}
++static inline unsigned long get_random_long(void)
++{
++#if BITS_PER_LONG == 64
++	return get_random_u64();
++#else
++	return get_random_u32();
++#endif
++}
+ 
+-extern void get_random_bytes(void *buf, int nbytes);
+-extern int add_random_ready_callback(struct random_ready_callback *rdy);
+-extern void del_random_ready_callback(struct random_ready_callback *rdy);
+-extern void get_random_bytes_arch(void *buf, int nbytes);
++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);
+ 
+-#ifndef MODULE
+-extern const struct file_operations random_fops, urandom_fops;
+-#endif
++/* 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)
++{
++	int ret = wait_for_random_bytes();
++	get_random_bytes(buf, nbytes);
++	return ret;
++}
+ 
+-unsigned int get_random_int(void);
+-unsigned long get_random_long(void);
+-unsigned long randomize_page(unsigned long start, unsigned long range);
++#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_ ## name(); \
++		return 0; \
++	}
++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
+ 
+ /*
+  * This is designed to be standalone for just prandom
+@@ -56,30 +84,39 @@ unsigned long randomize_page(unsigned long start, unsigned long range);
+ #ifdef CONFIG_ARCH_RANDOM
+ # include <asm/archrandom.h>
+ #else
+-static inline bool arch_get_random_long(unsigned long *v)
+-{
+-	return 0;
+-}
+-static inline bool arch_get_random_int(unsigned int *v)
+-{
+-	return 0;
+-}
+-static inline bool arch_has_random(void)
+-{
+-	return 0;
+-}
+-static inline bool arch_get_random_seed_long(unsigned long *v)
+-{
+-	return 0;
+-}
+-static inline bool arch_get_random_seed_int(unsigned int *v)
++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
++
++/*
++ * Called from the boot CPU during startup; not valid to call once
++ * secondary CPUs are up and preemption is possible.
++ */
++#ifndef arch_get_random_seed_long_early
++static inline bool __init arch_get_random_seed_long_early(unsigned long *v)
+ {
+-	return 0;
++	WARN_ON(system_state != SYSTEM_BOOTING);
++	return arch_get_random_seed_long(v);
+ }
+-static inline bool arch_has_random_seed(void)
++#endif
++
++#ifndef arch_get_random_long_early
++static inline bool __init arch_get_random_long_early(unsigned long *v)
+ {
+-	return 0;
++	WARN_ON(system_state != SYSTEM_BOOTING);
++	return arch_get_random_long(v);
+ }
+ #endif
+ 
++#ifdef CONFIG_SMP
++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 */
+diff --git a/include/linux/siphash.h b/include/linux/siphash.h
+index 0cda61855d907..0bb5ecd507bef 100644
+--- a/include/linux/siphash.h
++++ b/include/linux/siphash.h
+@@ -136,4 +136,32 @@ static inline u32 hsiphash(const void *data, size_t len,
+ 	return ___hsiphash_aligned(data, len, key);
+ }
+ 
++/*
++ * These macros expose the raw SipHash and HalfSipHash permutations.
++ * Do not use them directly! If you think you have a use for them,
++ * be sure to CC the maintainer of this file explaining why.
++ */
++
++#define SIPHASH_PERMUTATION(a, b, c, d) ( \
++	(a) += (b), (b) = rol64((b), 13), (b) ^= (a), (a) = rol64((a), 32), \
++	(c) += (d), (d) = rol64((d), 16), (d) ^= (c), \
++	(a) += (d), (d) = rol64((d), 21), (d) ^= (a), \
++	(c) += (b), (b) = rol64((b), 17), (b) ^= (c), (c) = rol64((c), 32))
++
++#define SIPHASH_CONST_0 0x736f6d6570736575ULL
++#define SIPHASH_CONST_1 0x646f72616e646f6dULL
++#define SIPHASH_CONST_2 0x6c7967656e657261ULL
++#define SIPHASH_CONST_3 0x7465646279746573ULL
++
++#define HSIPHASH_PERMUTATION(a, b, c, d) ( \
++	(a) += (b), (b) = rol32((b), 5), (b) ^= (a), (a) = rol32((a), 16), \
++	(c) += (d), (d) = rol32((d), 8), (d) ^= (c), \
++	(a) += (d), (d) = rol32((d), 7), (d) ^= (a), \
++	(c) += (b), (b) = rol32((b), 13), (b) ^= (c), (c) = rol32((c), 16))
++
++#define HSIPHASH_CONST_0 0U
++#define HSIPHASH_CONST_1 0U
++#define HSIPHASH_CONST_2 0x6c796765U
++#define HSIPHASH_CONST_3 0x74656462U
++
+ #endif /* _LINUX_SIPHASH_H */
+diff --git a/include/linux/swab.h b/include/linux/swab.h
+index 9ad3c60f6cae7..f66e6f8bf049d 100644
+--- a/include/linux/swab.h
++++ b/include/linux/swab.h
+@@ -6,6 +6,7 @@
+ # define swab16 __swab16
+ # define swab32 __swab32
+ # define swab64 __swab64
++# define swab __swab
+ # define swahw32 __swahw32
+ # define swahb32 __swahb32
+ # define swab16p __swab16p
+diff --git a/include/linux/timex.h b/include/linux/timex.h
+index 39c25dbebfe80..c7616cfb48d20 100644
+--- a/include/linux/timex.h
++++ b/include/linux/timex.h
+@@ -62,6 +62,8 @@
+ #include <linux/types.h>
+ #include <linux/param.h>
+ 
++unsigned long random_get_entropy_fallback(void);
++
+ #include <asm/timex.h>
+ 
+ #ifndef random_get_entropy
+@@ -74,8 +76,14 @@
+  *
+  * By default we use get_cycles() for this purpose, but individual
+  * architectures may override this in their asm/timex.h header file.
++ * If a given arch does not have get_cycles(), then we fallback to
++ * using random_get_entropy_fallback().
+  */
+-#define random_get_entropy()	get_cycles()
++#ifdef get_cycles
++#define random_get_entropy()	((unsigned long)get_cycles())
++#else
++#define random_get_entropy()	random_get_entropy_fallback()
++#endif
+ #endif
+ 
+ /*
+diff --git a/include/linux/uuid.h b/include/linux/uuid.h
+index 2d095fc602045..c77fb14868b70 100644
+--- a/include/linux/uuid.h
++++ b/include/linux/uuid.h
+@@ -23,6 +23,7 @@
+  * not including trailing NUL.
+  */
+ #define	UUID_STRING_LEN		36
++#define	UUID_SIZE		16
+ 
+ static inline int uuid_le_cmp(const uuid_le u1, const uuid_le u2)
+ {
+diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h
+index 8e880f7f67b24..b95c511139b9d 100644
+--- a/include/linux/workqueue.h
++++ b/include/linux/workqueue.h
+@@ -359,6 +359,8 @@ extern struct workqueue_struct *system_freezable_wq;
+ extern struct workqueue_struct *system_power_efficient_wq;
+ extern struct workqueue_struct *system_freezable_power_efficient_wq;
+ 
++extern bool wq_online;
++
+ extern struct workqueue_struct *
+ __alloc_workqueue_key(const char *fmt, unsigned int flags, int max_active,
+ 	struct lock_class_key *key, const char *lock_name, ...) __printf(1, 6);
+@@ -598,7 +600,7 @@ static inline bool schedule_delayed_work(struct delayed_work *dwork,
+  */
+ static inline bool keventd_up(void)
+ {
+-	return system_wq != NULL;
++	return wq_online;
+ }
+ 
+ #ifndef CONFIG_SMP
+@@ -635,4 +637,7 @@ int workqueue_online_cpu(unsigned int cpu);
+ int workqueue_offline_cpu(unsigned int cpu);
+ #endif
+ 
++int __init workqueue_init_early(void);
++int __init workqueue_init(void);
++
+ #endif
+diff --git a/include/net/inet_hashtables.h b/include/net/inet_hashtables.h
+index fc445e7ccadf4..c3cf2021bb3b3 100644
+--- a/include/net/inet_hashtables.h
++++ b/include/net/inet_hashtables.h
+@@ -382,7 +382,7 @@ static inline void sk_rcv_saddr_set(struct sock *sk, __be32 addr)
+ }
+ 
+ int __inet_hash_connect(struct inet_timewait_death_row *death_row,
+-			struct sock *sk, u32 port_offset,
++			struct sock *sk, u64 port_offset,
+ 			int (*check_established)(struct inet_timewait_death_row *,
+ 						 struct sock *, __u16,
+ 						 struct inet_timewait_sock **));
+diff --git a/include/net/secure_seq.h b/include/net/secure_seq.h
+index 3f36d45b714a4..542a80c051074 100644
+--- a/include/net/secure_seq.h
++++ b/include/net/secure_seq.h
+@@ -3,8 +3,8 @@
+ 
+ #include <linux/types.h>
+ 
+-u32 secure_ipv4_port_ephemeral(__be32 saddr, __be32 daddr, __be16 dport);
+-u32 secure_ipv6_port_ephemeral(const __be32 *saddr, const __be32 *daddr,
++u64 secure_ipv4_port_ephemeral(__be32 saddr, __be32 daddr, __be16 dport);
++u64 secure_ipv6_port_ephemeral(const __be32 *saddr, const __be32 *daddr,
+ 			       __be16 dport);
+ __u32 secure_tcp_sequence_number(__be32 saddr, __be32 daddr,
+ 				 __be16 sport, __be16 dport);
+diff --git a/include/trace/events/random.h b/include/trace/events/random.h
+deleted file mode 100644
+index 4684de344c5d9..0000000000000
+--- a/include/trace/events/random.h
++++ /dev/null
+@@ -1,315 +0,0 @@
+-#undef TRACE_SYSTEM
+-#define TRACE_SYSTEM random
+-
+-#if !defined(_TRACE_RANDOM_H) || defined(TRACE_HEADER_MULTI_READ)
+-#define _TRACE_RANDOM_H
+-
+-#include <linux/writeback.h>
+-#include <linux/tracepoint.h>
+-
+-TRACE_EVENT(add_device_randomness,
+-	TP_PROTO(int bytes, unsigned long IP),
+-
+-	TP_ARGS(bytes, IP),
+-
+-	TP_STRUCT__entry(
+-		__field(	  int,	bytes			)
+-		__field(unsigned long,	IP			)
+-	),
+-
+-	TP_fast_assign(
+-		__entry->bytes		= bytes;
+-		__entry->IP		= IP;
+-	),
+-
+-	TP_printk("bytes %d caller %pS",
+-		__entry->bytes, (void *)__entry->IP)
+-);
+-
+-DECLARE_EVENT_CLASS(random__mix_pool_bytes,
+-	TP_PROTO(const char *pool_name, int bytes, unsigned long IP),
+-
+-	TP_ARGS(pool_name, bytes, IP),
+-
+-	TP_STRUCT__entry(
+-		__field( const char *,	pool_name		)
+-		__field(	  int,	bytes			)
+-		__field(unsigned long,	IP			)
+-	),
+-
+-	TP_fast_assign(
+-		__entry->pool_name	= pool_name;
+-		__entry->bytes		= bytes;
+-		__entry->IP		= IP;
+-	),
+-
+-	TP_printk("%s pool: bytes %d caller %pS",
+-		  __entry->pool_name, __entry->bytes, (void *)__entry->IP)
+-);
+-
+-DEFINE_EVENT(random__mix_pool_bytes, mix_pool_bytes,
+-	TP_PROTO(const char *pool_name, int bytes, unsigned long IP),
+-
+-	TP_ARGS(pool_name, bytes, IP)
+-);
+-
+-DEFINE_EVENT(random__mix_pool_bytes, mix_pool_bytes_nolock,
+-	TP_PROTO(const char *pool_name, int bytes, unsigned long IP),
+-
+-	TP_ARGS(pool_name, bytes, IP)
+-);
+-
+-TRACE_EVENT(credit_entropy_bits,
+-	TP_PROTO(const char *pool_name, int bits, int entropy_count,
+-		 int entropy_total, unsigned long IP),
+-
+-	TP_ARGS(pool_name, bits, entropy_count, entropy_total, IP),
+-
+-	TP_STRUCT__entry(
+-		__field( const char *,	pool_name		)
+-		__field(	  int,	bits			)
+-		__field(	  int,	entropy_count		)
+-		__field(	  int,	entropy_total		)
+-		__field(unsigned long,	IP			)
+-	),
+-
+-	TP_fast_assign(
+-		__entry->pool_name	= pool_name;
+-		__entry->bits		= bits;
+-		__entry->entropy_count	= entropy_count;
+-		__entry->entropy_total	= entropy_total;
+-		__entry->IP		= IP;
+-	),
+-
+-	TP_printk("%s pool: bits %d entropy_count %d entropy_total %d "
+-		  "caller %pS", __entry->pool_name, __entry->bits,
+-		  __entry->entropy_count, __entry->entropy_total,
+-		  (void *)__entry->IP)
+-);
+-
+-TRACE_EVENT(push_to_pool,
+-	TP_PROTO(const char *pool_name, int pool_bits, int input_bits),
+-
+-	TP_ARGS(pool_name, pool_bits, input_bits),
+-
+-	TP_STRUCT__entry(
+-		__field( const char *,	pool_name		)
+-		__field(	  int,	pool_bits		)
+-		__field(	  int,	input_bits		)
+-	),
+-
+-	TP_fast_assign(
+-		__entry->pool_name	= pool_name;
+-		__entry->pool_bits	= pool_bits;
+-		__entry->input_bits	= input_bits;
+-	),
+-
+-	TP_printk("%s: pool_bits %d input_pool_bits %d",
+-		  __entry->pool_name, __entry->pool_bits,
+-		  __entry->input_bits)
+-);
+-
+-TRACE_EVENT(debit_entropy,
+-	TP_PROTO(const char *pool_name, int debit_bits),
+-
+-	TP_ARGS(pool_name, debit_bits),
+-
+-	TP_STRUCT__entry(
+-		__field( const char *,	pool_name		)
+-		__field(	  int,	debit_bits		)
+-	),
+-
+-	TP_fast_assign(
+-		__entry->pool_name	= pool_name;
+-		__entry->debit_bits	= debit_bits;
+-	),
+-
+-	TP_printk("%s: debit_bits %d", __entry->pool_name,
+-		  __entry->debit_bits)
+-);
+-
+-TRACE_EVENT(add_input_randomness,
+-	TP_PROTO(int input_bits),
+-
+-	TP_ARGS(input_bits),
+-
+-	TP_STRUCT__entry(
+-		__field(	  int,	input_bits		)
+-	),
+-
+-	TP_fast_assign(
+-		__entry->input_bits	= input_bits;
+-	),
+-
+-	TP_printk("input_pool_bits %d", __entry->input_bits)
+-);
+-
+-TRACE_EVENT(add_disk_randomness,
+-	TP_PROTO(dev_t dev, int input_bits),
+-
+-	TP_ARGS(dev, input_bits),
+-
+-	TP_STRUCT__entry(
+-		__field(	dev_t,	dev			)
+-		__field(	  int,	input_bits		)
+-	),
+-
+-	TP_fast_assign(
+-		__entry->dev		= dev;
+-		__entry->input_bits	= input_bits;
+-	),
+-
+-	TP_printk("dev %d,%d input_pool_bits %d", MAJOR(__entry->dev),
+-		  MINOR(__entry->dev), __entry->input_bits)
+-);
+-
+-TRACE_EVENT(xfer_secondary_pool,
+-	TP_PROTO(const char *pool_name, int xfer_bits, int request_bits,
+-		 int pool_entropy, int input_entropy),
+-
+-	TP_ARGS(pool_name, xfer_bits, request_bits, pool_entropy,
+-		input_entropy),
+-
+-	TP_STRUCT__entry(
+-		__field( const char *,	pool_name		)
+-		__field(	  int,	xfer_bits		)
+-		__field(	  int,	request_bits		)
+-		__field(	  int,	pool_entropy		)
+-		__field(	  int,	input_entropy		)
+-	),
+-
+-	TP_fast_assign(
+-		__entry->pool_name	= pool_name;
+-		__entry->xfer_bits	= xfer_bits;
+-		__entry->request_bits	= request_bits;
+-		__entry->pool_entropy	= pool_entropy;
+-		__entry->input_entropy	= input_entropy;
+-	),
+-
+-	TP_printk("pool %s xfer_bits %d request_bits %d pool_entropy %d "
+-		  "input_entropy %d", __entry->pool_name, __entry->xfer_bits,
+-		  __entry->request_bits, __entry->pool_entropy,
+-		  __entry->input_entropy)
+-);
+-
+-DECLARE_EVENT_CLASS(random__get_random_bytes,
+-	TP_PROTO(int nbytes, unsigned long IP),
+-
+-	TP_ARGS(nbytes, IP),
+-
+-	TP_STRUCT__entry(
+-		__field(	  int,	nbytes			)
+-		__field(unsigned long,	IP			)
+-	),
+-
+-	TP_fast_assign(
+-		__entry->nbytes		= nbytes;
+-		__entry->IP		= IP;
+-	),
+-
+-	TP_printk("nbytes %d caller %pS", __entry->nbytes, (void *)__entry->IP)
+-);
+-
+-DEFINE_EVENT(random__get_random_bytes, get_random_bytes,
+-	TP_PROTO(int nbytes, unsigned long IP),
+-
+-	TP_ARGS(nbytes, IP)
+-);
+-
+-DEFINE_EVENT(random__get_random_bytes, get_random_bytes_arch,
+-	TP_PROTO(int nbytes, unsigned long IP),
+-
+-	TP_ARGS(nbytes, IP)
+-);
+-
+-DECLARE_EVENT_CLASS(random__extract_entropy,
+-	TP_PROTO(const char *pool_name, int nbytes, int entropy_count,
+-		 unsigned long IP),
+-
+-	TP_ARGS(pool_name, nbytes, entropy_count, IP),
+-
+-	TP_STRUCT__entry(
+-		__field( const char *,	pool_name		)
+-		__field(	  int,	nbytes			)
+-		__field(	  int,	entropy_count		)
+-		__field(unsigned long,	IP			)
+-	),
+-
+-	TP_fast_assign(
+-		__entry->pool_name	= pool_name;
+-		__entry->nbytes		= nbytes;
+-		__entry->entropy_count	= entropy_count;
+-		__entry->IP		= IP;
+-	),
+-
+-	TP_printk("%s pool: nbytes %d entropy_count %d caller %pS",
+-		  __entry->pool_name, __entry->nbytes, __entry->entropy_count,
+-		  (void *)__entry->IP)
+-);
+-
+-
+-DEFINE_EVENT(random__extract_entropy, extract_entropy,
+-	TP_PROTO(const char *pool_name, int nbytes, int entropy_count,
+-		 unsigned long IP),
+-
+-	TP_ARGS(pool_name, nbytes, entropy_count, IP)
+-);
+-
+-DEFINE_EVENT(random__extract_entropy, extract_entropy_user,
+-	TP_PROTO(const char *pool_name, int nbytes, int entropy_count,
+-		 unsigned long IP),
+-
+-	TP_ARGS(pool_name, nbytes, entropy_count, IP)
+-);
+-
+-TRACE_EVENT(random_read,
+-	TP_PROTO(int got_bits, int need_bits, int pool_left, int input_left),
+-
+-	TP_ARGS(got_bits, need_bits, pool_left, input_left),
+-
+-	TP_STRUCT__entry(
+-		__field(	  int,	got_bits		)
+-		__field(	  int,	need_bits		)
+-		__field(	  int,	pool_left		)
+-		__field(	  int,	input_left		)
+-	),
+-
+-	TP_fast_assign(
+-		__entry->got_bits	= got_bits;
+-		__entry->need_bits	= need_bits;
+-		__entry->pool_left	= pool_left;
+-		__entry->input_left	= input_left;
+-	),
+-
+-	TP_printk("got_bits %d still_needed_bits %d "
+-		  "blocking_pool_entropy_left %d input_entropy_left %d",
+-		  __entry->got_bits, __entry->got_bits, __entry->pool_left,
+-		  __entry->input_left)
+-);
+-
+-TRACE_EVENT(urandom_read,
+-	TP_PROTO(int got_bits, int pool_left, int input_left),
+-
+-	TP_ARGS(got_bits, pool_left, input_left),
+-
+-	TP_STRUCT__entry(
+-		__field(	  int,	got_bits		)
+-		__field(	  int,	pool_left		)
+-		__field(	  int,	input_left		)
+-	),
+-
+-	TP_fast_assign(
+-		__entry->got_bits	= got_bits;
+-		__entry->pool_left	= pool_left;
+-		__entry->input_left	= input_left;
+-	),
+-
+-	TP_printk("got_bits %d nonblocking_pool_entropy_left %d "
+-		  "input_entropy_left %d", __entry->got_bits,
+-		  __entry->pool_left, __entry->input_left)
+-);
+-
+-#endif /* _TRACE_RANDOM_H */
+-
+-/* This part must be outside protection */
+-#include <trace/define_trace.h>
+diff --git a/include/uapi/linux/random.h b/include/uapi/linux/random.h
+index b455b0d86f269..b01d118750ab2 100644
+--- a/include/uapi/linux/random.h
++++ b/include/uapi/linux/random.h
+@@ -47,9 +47,11 @@ struct rand_pool_info {
+  * Flags for getrandom(2)
+  *
+  * GRND_NONBLOCK	Don't block and return EAGAIN instead
+- * GRND_RANDOM		Use the /dev/random pool instead of /dev/urandom
++ * GRND_RANDOM		No effect
++ * GRND_INSECURE	Return non-cryptographic random bytes
+  */
+ #define GRND_NONBLOCK	0x0001
+ #define GRND_RANDOM	0x0002
++#define GRND_INSECURE	0x0004
+ 
+ #endif /* _UAPI_LINUX_RANDOM_H */
+diff --git a/include/uapi/linux/swab.h b/include/uapi/linux/swab.h
+index 8f3a8f606fd95..1f42d110987a4 100644
+--- a/include/uapi/linux/swab.h
++++ b/include/uapi/linux/swab.h
+@@ -3,6 +3,7 @@
+ 
+ #include <linux/types.h>
+ #include <linux/compiler.h>
++#include <asm/bitsperlong.h>
+ #include <asm/swab.h>
+ 
+ /*
+@@ -131,6 +132,15 @@ static inline __attribute_const__ __u32 __fswahb32(__u32 val)
+ 	__fswab64(x))
+ #endif
+ 
++static __always_inline unsigned long __swab(const unsigned long y)
++{
++#if BITS_PER_LONG == 64
++	return __swab64(y);
++#else /* BITS_PER_LONG == 32 */
++	return __swab32(y);
++#endif
++}
++
+ /**
+  * __swahw32 - return a word-swapped 32-bit value
+  * @x: value to wordswap
+diff --git a/init/main.c b/init/main.c
+index 0c01d4e10d2f3..30226a836c8b5 100644
+--- a/init/main.c
++++ b/init/main.c
+@@ -490,6 +490,7 @@ asmlinkage __visible void __init start_kernel(void)
+ 	/*
+ 	 * Set up the the initial canary ASAP:
+ 	 */
++	add_latent_entropy();
+ 	boot_init_stack_canary();
+ 
+ 	cgroup_init_early();
+@@ -553,6 +554,14 @@ asmlinkage __visible void __init start_kernel(void)
+ 		 "Interrupts were enabled *very* early, fixing it\n"))
+ 		local_irq_disable();
+ 	idr_init_cache();
++
++	/*
++	 * Allow workqueue creation and work item queueing/cancelling
++	 * early.  Work item execution depends on kthreads and starts after
++	 * workqueue_init().
++	 */
++	workqueue_init_early();
++
+ 	rcu_init();
+ 
+ 	/* trace_printk() and trace points may be used after this */
+@@ -570,6 +579,17 @@ asmlinkage __visible void __init start_kernel(void)
+ 	softirq_init();
+ 	timekeeping_init();
+ 	time_init();
++
++	/*
++	 * 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 random_init()
++	 * - time_init() for making random_get_entropy() work on some platforms
++	 * - random_init() to initialize the RNG from from early entropy sources
++	 */
++	random_init(command_line);
++	boot_init_stack_canary();
++
+ 	sched_clock_postinit();
+ 	printk_nmi_init();
+ 	perf_event_init();
+@@ -1011,6 +1031,8 @@ static noinline void __init kernel_init_freeable(void)
+ 
+ 	smp_prepare_cpus(setup_max_cpus);
+ 
++	workqueue_init();
++
+ 	do_pre_smp_initcalls();
+ 	lockup_detector_init();
+ 
+diff --git a/kernel/cpu.c b/kernel/cpu.c
+index e005209f279e1..5ddac8914515a 100644
+--- a/kernel/cpu.c
++++ b/kernel/cpu.c
+@@ -26,6 +26,7 @@
+ #include <linux/smpboot.h>
+ #include <linux/relay.h>
+ #include <linux/slab.h>
++#include <linux/random.h>
+ 
+ #include <trace/events/power.h>
+ #define CREATE_TRACE_POINTS
+@@ -1404,6 +1405,11 @@ static struct cpuhp_step cpuhp_bp_states[] = {
+ 		.startup.single		= perf_event_init_cpu,
+ 		.teardown.single	= perf_event_exit_cpu,
+ 	},
++	[CPUHP_RANDOM_PREPARE] = {
++		.name			= "random:prepare",
++		.startup.single		= random_prepare_cpu,
++		.teardown.single	= NULL,
++	},
+ 	[CPUHP_WORKQUEUE_PREP] = {
+ 		.name			= "workqueue:prepare",
+ 		.startup.single		= workqueue_prepare_cpu,
+@@ -1529,6 +1535,11 @@ static struct cpuhp_step cpuhp_ap_states[] = {
+ 		.startup.single		= workqueue_online_cpu,
+ 		.teardown.single	= workqueue_offline_cpu,
+ 	},
++	[CPUHP_AP_RANDOM_ONLINE] = {
++		.name			= "random:online",
++		.startup.single		= random_online_cpu,
++		.teardown.single	= NULL,
++	},
+ 	[CPUHP_AP_RCUTREE_ONLINE] = {
+ 		.name			= "RCU/tree:online",
+ 		.startup.single		= rcutree_online_cpu,
+diff --git a/kernel/irq/handle.c b/kernel/irq/handle.c
+index d3f24905852c9..374c45fbe3db6 100644
+--- a/kernel/irq/handle.c
++++ b/kernel/irq/handle.c
+@@ -184,7 +184,7 @@ irqreturn_t handle_irq_event_percpu(struct irq_desc *desc)
+ 
+ 	retval = __handle_irq_event_percpu(desc, &flags);
+ 
+-	add_interrupt_randomness(desc->irq_data.irq, flags);
++	add_interrupt_randomness(desc->irq_data.irq);
+ 
+ 	if (!noirqdebug)
+ 		note_interrupt(desc, retval);
+diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
+index bcba817f7af20..828728639e0dd 100644
+--- a/kernel/time/timekeeping.c
++++ b/kernel/time/timekeeping.c
+@@ -19,6 +19,7 @@
+ #include <linux/clocksource.h>
+ #include <linux/jiffies.h>
+ #include <linux/time.h>
++#include <linux/timex.h>
+ #include <linux/tick.h>
+ #include <linux/stop_machine.h>
+ #include <linux/pvclock_gtod.h>
+@@ -2269,6 +2270,21 @@ ktime_t ktime_get_update_offsets_now(unsigned int *cwsseq, ktime_t *offs_real,
+ 	return base;
+ }
+ 
++/**
++ * random_get_entropy_fallback - Returns the raw clock source value,
++ * used by random.c for platforms with no valid random_get_entropy().
++ */
++unsigned long random_get_entropy_fallback(void)
++{
++	struct tk_read_base *tkr = &tk_core.timekeeper.tkr_mono;
++	struct clocksource *clock = READ_ONCE(tkr->clock);
++
++	if (unlikely(timekeeping_suspended || !clock))
++		return 0;
++	return clock->read(clock);
++}
++EXPORT_SYMBOL_GPL(random_get_entropy_fallback);
++
+ /**
+  * do_adjtimex() - Accessor function to NTP __do_adjtimex function
+  */
+diff --git a/kernel/workqueue.c b/kernel/workqueue.c
+index b3476a21a7b31..df96f797939e4 100644
+--- a/kernel/workqueue.c
++++ b/kernel/workqueue.c
+@@ -292,6 +292,8 @@ module_param_named(disable_numa, wq_disable_numa, bool, 0444);
+ static bool wq_power_efficient = IS_ENABLED(CONFIG_WQ_POWER_EFFICIENT_DEFAULT);
+ module_param_named(power_efficient, wq_power_efficient, bool, 0444);
+ 
++bool wq_online;				/* can kworkers be created yet? */
++
+ static bool wq_numa_enabled;		/* unbound NUMA affinity enabled */
+ 
+ /* buf for wq_update_unbound_numa_attrs(), protected by CPU hotplug exclusion */
+@@ -2588,6 +2590,9 @@ void flush_workqueue(struct workqueue_struct *wq)
+ 	};
+ 	int next_color;
+ 
++	if (WARN_ON(!wq_online))
++		return;
++
+ 	lock_map_acquire(&wq->lockdep_map);
+ 	lock_map_release(&wq->lockdep_map);
+ 
+@@ -2848,6 +2853,9 @@ bool flush_work(struct work_struct *work)
+ {
+ 	struct wq_barrier barr;
+ 
++	if (WARN_ON(!wq_online))
++		return false;
++
+ 	lock_map_acquire(&work->lockdep_map);
+ 	lock_map_release(&work->lockdep_map);
+ 
+@@ -2918,7 +2926,13 @@ static bool __cancel_work_timer(struct work_struct *work, bool is_dwork)
+ 	mark_work_canceling(work);
+ 	local_irq_restore(flags);
+ 
+-	flush_work(work);
++	/*
++	 * This allows canceling during early boot.  We know that @work
++	 * isn't executing.
++	 */
++	if (wq_online)
++		flush_work(work);
++
+ 	clear_work_data(work);
+ 
+ 	/*
+@@ -3368,7 +3382,7 @@ static struct worker_pool *get_unbound_pool(const struct workqueue_attrs *attrs)
+ 		goto fail;
+ 
+ 	/* create and start the initial worker */
+-	if (!create_worker(pool))
++	if (wq_online && !create_worker(pool))
+ 		goto fail;
+ 
+ 	/* install */
+@@ -3439,6 +3453,7 @@ static void pwq_adjust_max_active(struct pool_workqueue *pwq)
+ {
+ 	struct workqueue_struct *wq = pwq->wq;
+ 	bool freezable = wq->flags & WQ_FREEZABLE;
++	unsigned long flags;
+ 
+ 	/* for @wq->saved_max_active */
+ 	lockdep_assert_held(&wq->mutex);
+@@ -3447,7 +3462,8 @@ static void pwq_adjust_max_active(struct pool_workqueue *pwq)
+ 	if (!freezable && pwq->max_active == wq->saved_max_active)
+ 		return;
+ 
+-	spin_lock_irq(&pwq->pool->lock);
++	/* this function can be called during early boot w/ irq disabled */
++	spin_lock_irqsave(&pwq->pool->lock, flags);
+ 
+ 	/*
+ 	 * During [un]freezing, the caller is responsible for ensuring that
+@@ -3477,7 +3493,7 @@ static void pwq_adjust_max_active(struct pool_workqueue *pwq)
+ 		pwq->max_active = 0;
+ 	}
+ 
+-	spin_unlock_irq(&pwq->pool->lock);
++	spin_unlock_irqrestore(&pwq->pool->lock, flags);
+ }
+ 
+ /* initialize newly alloced @pwq which is associated with @wq and @pool */
+@@ -5550,7 +5566,17 @@ static void __init wq_numa_init(void)
+ 	wq_numa_enabled = true;
+ }
+ 
+-static int __init init_workqueues(void)
++/**
++ * workqueue_init_early - early init for workqueue subsystem
++ *
++ * This is the first half of two-staged workqueue subsystem initialization
++ * and invoked as soon as the bare basics - memory allocation, cpumasks and
++ * idr are up.  It sets up all the data structures and system workqueues
++ * and allows early boot code to create workqueues and queue/cancel work
++ * items.  Actual work item execution starts only after kthreads can be
++ * created and scheduled right before early initcalls.
++ */
++int __init workqueue_init_early(void)
+ {
+ 	int std_nice[NR_STD_WORKER_POOLS] = { 0, HIGHPRI_NICE_LEVEL };
+ 	int i, cpu;
+@@ -5583,16 +5609,6 @@ static int __init init_workqueues(void)
+ 		}
+ 	}
+ 
+-	/* create the initial worker */
+-	for_each_online_cpu(cpu) {
+-		struct worker_pool *pool;
+-
+-		for_each_cpu_worker_pool(pool, cpu) {
+-			pool->flags &= ~POOL_DISASSOCIATED;
+-			BUG_ON(!create_worker(pool));
+-		}
+-	}
+-
+ 	/* create default unbound and ordered wq attrs */
+ 	for (i = 0; i < NR_STD_WORKER_POOLS; i++) {
+ 		struct workqueue_attrs *attrs;
+@@ -5629,8 +5645,36 @@ static int __init init_workqueues(void)
+ 	       !system_power_efficient_wq ||
+ 	       !system_freezable_power_efficient_wq);
+ 
++	return 0;
++}
++
++/**
++ * workqueue_init - bring workqueue subsystem fully online
++ *
++ * This is the latter half of two-staged workqueue subsystem initialization
++ * and invoked as soon as kthreads can be created and scheduled.
++ * Workqueues have been created and work items queued on them, but there
++ * are no kworkers executing the work items yet.  Populate the worker pools
++ * with the initial workers and enable future kworker creations.
++ */
++int __init workqueue_init(void)
++{
++	struct worker_pool *pool;
++	int cpu, bkt;
++
++	/* create the initial workers */
++	for_each_online_cpu(cpu) {
++		for_each_cpu_worker_pool(pool, cpu) {
++			pool->flags &= ~POOL_DISASSOCIATED;
++			BUG_ON(!create_worker(pool));
++		}
++	}
++
++	hash_for_each(unbound_pool_hash, bkt, pool, hash_node)
++		BUG_ON(!create_worker(pool));
++
++	wq_online = true;
+ 	wq_watchdog_init();
+ 
+ 	return 0;
+ }
+-early_initcall(init_workqueues);
+diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
+index e7addfcd302f4..95be8e1b12f60 100644
+--- a/lib/Kconfig.debug
++++ b/lib/Kconfig.debug
+@@ -1177,6 +1177,33 @@ config STACKTRACE
+ 	  It is also used by various kernel debugging features that require
+ 	  stack trace generation.
+ 
++config WARN_ALL_UNSEEDED_RANDOM
++	bool "Warn for all uses of unseeded randomness"
++	default n
++	help
++	  Some parts of the kernel contain bugs relating to their use of
++	  cryptographically secure random numbers before it's actually possible
++	  to generate those numbers securely. This setting ensures that these
++	  flaws don't go unnoticed, by enabling a message, should this ever
++	  occur. This will allow people with obscure setups to know when things
++	  are going wrong, so that they might contact developers about fixing
++	  it.
++
++	  Unfortunately, on some models of some architectures getting
++	  a fully seeded CRNG is extremely difficult, and so this can
++	  result in dmesg getting spammed for a surprisingly long
++	  time.  This is really bad from a security perspective, and
++	  so architecture maintainers really need to do what they can
++	  to get the CRNG seeded sooner after the system is booted.
++	  However, since users cannot do anything actionable to
++	  address this, by default this option is disabled.
++
++	  Say Y here if you want to receive warnings for all uses of
++	  unseeded randomness.  This will be of use primarily for
++	  those developers interersted in improving the security of
++	  Linux kernels running on their architecture (or
++	  subarchitecture).
++
+ config DEBUG_KOBJECT
+ 	bool "kobject debugging"
+ 	depends on DEBUG_KERNEL
+diff --git a/lib/Makefile b/lib/Makefile
+index 7a55c52052810..775d6ef6d2eff 100644
+--- a/lib/Makefile
++++ b/lib/Makefile
+@@ -234,3 +234,5 @@ KASAN_SANITIZE_ubsan.o := n
+ CFLAGS_ubsan.o := $(call cc-option, -fno-stack-protector) $(DISABLE_STACKLEAK_PLUGIN)
+ 
+ obj-$(CONFIG_SBITMAP) += sbitmap.o
++
++obj-y += crypto/
+diff --git a/lib/chacha20.c b/lib/chacha20.c
+index 250ceed9ec9a8..5f6c222e939a9 100644
+--- a/lib/chacha20.c
++++ b/lib/chacha20.c
+@@ -21,9 +21,9 @@ static inline u32 rotl32(u32 v, u8 n)
+ 	return (v << n) | (v >> (sizeof(v) * 8 - n));
+ }
+ 
+-extern void chacha20_block(u32 *state, void *stream)
++void chacha20_block(u32 *state, u8 *stream)
+ {
+-	u32 x[16], *out = stream;
++	u32 x[16];
+ 	int i;
+ 
+ 	for (i = 0; i < ARRAY_SIZE(x); i++)
+@@ -72,7 +72,7 @@ extern void chacha20_block(u32 *state, void *stream)
+ 	}
+ 
+ 	for (i = 0; i < ARRAY_SIZE(x); i++)
+-		out[i] = cpu_to_le32(x[i] + state[i]);
++		put_unaligned_le32(x[i] + state[i], &stream[i * sizeof(u32)]);
+ 
+ 	state[12]++;
+ }
+diff --git a/lib/crypto/Makefile b/lib/crypto/Makefile
+new file mode 100644
+index 0000000000000..d0bca68618f03
+--- /dev/null
++++ b/lib/crypto/Makefile
+@@ -0,0 +1,7 @@
++# SPDX-License-Identifier: GPL-2.0
++
++obj-y += libblake2s.o
++libblake2s-y += blake2s.o blake2s-generic.o
++ifneq ($(CONFIG_CRYPTO_MANAGER_DISABLE_TESTS),y)
++libblake2s-y += blake2s-selftest.o
++endif
+diff --git a/lib/crypto/blake2s-generic.c b/lib/crypto/blake2s-generic.c
+new file mode 100644
+index 0000000000000..04ff8df245136
+--- /dev/null
++++ b/lib/crypto/blake2s-generic.c
+@@ -0,0 +1,111 @@
++// SPDX-License-Identifier: GPL-2.0 OR MIT
++/*
++ * Copyright (C) 2015-2019 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
++ *
++ * This is an implementation of the BLAKE2s hash and PRF functions.
++ *
++ * Information: https://blake2.net/
++ *
++ */
++
++#include <crypto/internal/blake2s.h>
++#include <linux/types.h>
++#include <linux/string.h>
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/bug.h>
++#include <asm/unaligned.h>
++
++static const u8 blake2s_sigma[10][16] = {
++	{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 },
++	{ 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 },
++	{ 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 },
++	{ 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 },
++	{ 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 },
++	{ 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 },
++	{ 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 },
++	{ 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 },
++	{ 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 },
++	{ 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0 },
++};
++
++static inline void blake2s_increment_counter(struct blake2s_state *state,
++					     const u32 inc)
++{
++	state->t[0] += inc;
++	state->t[1] += (state->t[0] < inc);
++}
++
++void blake2s_compress_generic(struct blake2s_state *state,const u8 *block,
++			      size_t nblocks, const u32 inc)
++{
++	u32 m[16];
++	u32 v[16];
++	int i;
++
++	WARN_ON(IS_ENABLED(DEBUG) &&
++		(nblocks > 1 && inc != BLAKE2S_BLOCK_SIZE));
++
++	while (nblocks > 0) {
++		blake2s_increment_counter(state, inc);
++		memcpy(m, block, BLAKE2S_BLOCK_SIZE);
++		le32_to_cpu_array(m, ARRAY_SIZE(m));
++		memcpy(v, state->h, 32);
++		v[ 8] = BLAKE2S_IV0;
++		v[ 9] = BLAKE2S_IV1;
++		v[10] = BLAKE2S_IV2;
++		v[11] = BLAKE2S_IV3;
++		v[12] = BLAKE2S_IV4 ^ state->t[0];
++		v[13] = BLAKE2S_IV5 ^ state->t[1];
++		v[14] = BLAKE2S_IV6 ^ state->f[0];
++		v[15] = BLAKE2S_IV7 ^ state->f[1];
++
++#define G(r, i, a, b, c, d) do { \
++	a += b + m[blake2s_sigma[r][2 * i + 0]]; \
++	d = ror32(d ^ a, 16); \
++	c += d; \
++	b = ror32(b ^ c, 12); \
++	a += b + m[blake2s_sigma[r][2 * i + 1]]; \
++	d = ror32(d ^ a, 8); \
++	c += d; \
++	b = ror32(b ^ c, 7); \
++} while (0)
++
++#define ROUND(r) do { \
++	G(r, 0, v[0], v[ 4], v[ 8], v[12]); \
++	G(r, 1, v[1], v[ 5], v[ 9], v[13]); \
++	G(r, 2, v[2], v[ 6], v[10], v[14]); \
++	G(r, 3, v[3], v[ 7], v[11], v[15]); \
++	G(r, 4, v[0], v[ 5], v[10], v[15]); \
++	G(r, 5, v[1], v[ 6], v[11], v[12]); \
++	G(r, 6, v[2], v[ 7], v[ 8], v[13]); \
++	G(r, 7, v[3], v[ 4], v[ 9], v[14]); \
++} while (0)
++		ROUND(0);
++		ROUND(1);
++		ROUND(2);
++		ROUND(3);
++		ROUND(4);
++		ROUND(5);
++		ROUND(6);
++		ROUND(7);
++		ROUND(8);
++		ROUND(9);
++
++#undef G
++#undef ROUND
++
++		for (i = 0; i < 8; ++i)
++			state->h[i] ^= v[i] ^ v[i + 8];
++
++		block += BLAKE2S_BLOCK_SIZE;
++		--nblocks;
++	}
++}
++
++EXPORT_SYMBOL(blake2s_compress_generic);
++
++MODULE_LICENSE("GPL v2");
++MODULE_DESCRIPTION("BLAKE2s hash function");
++MODULE_AUTHOR("Jason A. Donenfeld <Jason@zx2c4.com>");
+diff --git a/lib/crypto/blake2s-selftest.c b/lib/crypto/blake2s-selftest.c
+new file mode 100644
+index 0000000000000..7a9edc96ddddf
+--- /dev/null
++++ b/lib/crypto/blake2s-selftest.c
+@@ -0,0 +1,591 @@
++// SPDX-License-Identifier: GPL-2.0 OR MIT
++/*
++ * Copyright (C) 2015-2019 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
++ */
++
++#include <crypto/blake2s.h>
++#include <linux/string.h>
++
++/*
++ * blake2s_testvecs[] generated with the program below (using libb2-dev and
++ * libssl-dev [OpenSSL])
++ *
++ * #include <blake2.h>
++ * #include <stdint.h>
++ * #include <stdio.h>
++ *
++ * #include <openssl/evp.h>
++ *
++ * #define BLAKE2S_TESTVEC_COUNT	256
++ *
++ * static void print_vec(const uint8_t vec[], int len)
++ * {
++ *	int i;
++ *
++ *	printf("  { ");
++ *	for (i = 0; i < len; i++) {
++ *		if (i && (i % 12) == 0)
++ *			printf("\n    ");
++ *		printf("0x%02x, ", vec[i]);
++ *	}
++ *	printf("},\n");
++ * }
++ *
++ * int main(void)
++ * {
++ *	uint8_t key[BLAKE2S_KEYBYTES];
++ *	uint8_t buf[BLAKE2S_TESTVEC_COUNT];
++ *	uint8_t hash[BLAKE2S_OUTBYTES];
++ *	int i, j;
++ *
++ *	key[0] = key[1] = 1;
++ *	for (i = 2; i < BLAKE2S_KEYBYTES; ++i)
++ *		key[i] = key[i - 2] + key[i - 1];
++ *
++ *	for (i = 0; i < BLAKE2S_TESTVEC_COUNT; ++i)
++ *		buf[i] = (uint8_t)i;
++ *
++ *	printf("static const u8 blake2s_testvecs[][BLAKE2S_HASH_SIZE] __initconst = {\n");
++ *
++ *	for (i = 0; i < BLAKE2S_TESTVEC_COUNT; ++i) {
++ *		int outlen = 1 + i % BLAKE2S_OUTBYTES;
++ *		int keylen = (13 * i) % (BLAKE2S_KEYBYTES + 1);
++ *
++ *		blake2s(hash, buf, key + BLAKE2S_KEYBYTES - keylen, outlen, i,
++ *			keylen);
++ *		print_vec(hash, outlen);
++ *	}
++ *	printf("};\n\n");
++ *
++ *	return 0;
++ *}
++ */
++static const u8 blake2s_testvecs[][BLAKE2S_HASH_SIZE] __initconst = {
++  { 0xa1, },
++  { 0x7c, 0x89, },
++  { 0x74, 0x0e, 0xd4, },
++  { 0x47, 0x0c, 0x21, 0x15, },
++  { 0x18, 0xd6, 0x9c, 0xa6, 0xc4, },
++  { 0x13, 0x5d, 0x16, 0x63, 0x2e, 0xf9, },
++  { 0x2c, 0xb5, 0x04, 0xb7, 0x99, 0xe2, 0x73, },
++  { 0x9a, 0x0f, 0xd2, 0x39, 0xd6, 0x68, 0x1b, 0x92, },
++  { 0xc8, 0xde, 0x7a, 0xea, 0x2f, 0xf4, 0xd2, 0xe3, 0x2b, },
++  { 0x5b, 0xf9, 0x43, 0x52, 0x0c, 0x12, 0xba, 0xb5, 0x93, 0x9f, },
++  { 0xc6, 0x2c, 0x4e, 0x80, 0xfc, 0x32, 0x5b, 0x33, 0xb8, 0xb8, 0x0a, },
++  { 0xa7, 0x5c, 0xfd, 0x3a, 0xcc, 0xbf, 0x90, 0xca, 0xb7, 0x97, 0xde, 0xd8, },
++  { 0x66, 0xca, 0x3c, 0xc4, 0x19, 0xef, 0x92, 0x66, 0x3f, 0x21, 0x8f, 0xda,
++    0xb7, },
++  { 0xba, 0xe5, 0xbb, 0x30, 0x25, 0x94, 0x6d, 0xc3, 0x89, 0x09, 0xc4, 0x25,
++    0x52, 0x3e, },
++  { 0xa2, 0xef, 0x0e, 0x52, 0x0b, 0x5f, 0xa2, 0x01, 0x6d, 0x0a, 0x25, 0xbc,
++    0x57, 0xe2, 0x27, },
++  { 0x4f, 0xe0, 0xf9, 0x52, 0x12, 0xda, 0x84, 0xb7, 0xab, 0xae, 0xb0, 0xa6,
++    0x47, 0x2a, 0xc7, 0xf5, },
++  { 0x56, 0xe7, 0xa8, 0x1c, 0x4c, 0xca, 0xed, 0x90, 0x31, 0xec, 0x87, 0x43,
++    0xe7, 0x72, 0x08, 0xec, 0xbe, },
++  { 0x7e, 0xdf, 0x80, 0x1c, 0x93, 0x33, 0xfd, 0x53, 0x44, 0xba, 0xfd, 0x96,
++    0xe1, 0xbb, 0xb5, 0x65, 0xa5, 0x00, },
++  { 0xec, 0x6b, 0xed, 0xf7, 0x7b, 0x62, 0x1d, 0x7d, 0xf4, 0x82, 0xf3, 0x1e,
++    0x18, 0xff, 0x2b, 0xc4, 0x06, 0x20, 0x2a, },
++  { 0x74, 0x98, 0xd7, 0x68, 0x63, 0xed, 0x87, 0xe4, 0x5d, 0x8d, 0x9e, 0x1d,
++    0xfd, 0x2a, 0xbb, 0x86, 0xac, 0xe9, 0x2a, 0x89, },
++  { 0x89, 0xc3, 0x88, 0xce, 0x2b, 0x33, 0x1e, 0x10, 0xd1, 0x37, 0x20, 0x86,
++    0x28, 0x43, 0x70, 0xd9, 0xfb, 0x96, 0xd9, 0xb5, 0xd3, },
++  { 0xcb, 0x56, 0x74, 0x41, 0x8d, 0x80, 0x01, 0x9a, 0x6b, 0x38, 0xe1, 0x41,
++    0xad, 0x9c, 0x62, 0x74, 0xce, 0x35, 0xd5, 0x6c, 0x89, 0x6e, },
++  { 0x79, 0xaf, 0x94, 0x59, 0x99, 0x26, 0xe1, 0xc9, 0x34, 0xfe, 0x7c, 0x22,
++    0xf7, 0x43, 0xd7, 0x65, 0xd4, 0x48, 0x18, 0xac, 0x3d, 0xfd, 0x93, },
++  { 0x85, 0x0d, 0xff, 0xb8, 0x3e, 0x87, 0x41, 0xb0, 0x95, 0xd3, 0x3d, 0x00,
++    0x47, 0x55, 0x9e, 0xd2, 0x69, 0xea, 0xbf, 0xe9, 0x7a, 0x2d, 0x61, 0x45, },
++  { 0x03, 0xe0, 0x85, 0xec, 0x54, 0xb5, 0x16, 0x53, 0xa8, 0xc4, 0x71, 0xe9,
++    0x6a, 0xe7, 0xcb, 0xc4, 0x15, 0x02, 0xfc, 0x34, 0xa4, 0xa4, 0x28, 0x13,
++    0xd1, },
++  { 0xe3, 0x34, 0x4b, 0xe1, 0xd0, 0x4b, 0x55, 0x61, 0x8f, 0xc0, 0x24, 0x05,
++    0xe6, 0xe0, 0x3d, 0x70, 0x24, 0x4d, 0xda, 0xb8, 0x91, 0x05, 0x29, 0x07,
++    0x01, 0x3e, },
++  { 0x61, 0xff, 0x01, 0x72, 0xb1, 0x4d, 0xf6, 0xfe, 0xd1, 0xd1, 0x08, 0x74,
++    0xe6, 0x91, 0x44, 0xeb, 0x61, 0xda, 0x40, 0xaf, 0xfc, 0x8c, 0x91, 0x6b,
++    0xec, 0x13, 0xed, },
++  { 0xd4, 0x40, 0xd2, 0xa0, 0x7f, 0xc1, 0x58, 0x0c, 0x85, 0xa0, 0x86, 0xc7,
++    0x86, 0xb9, 0x61, 0xc9, 0xea, 0x19, 0x86, 0x1f, 0xab, 0x07, 0xce, 0x37,
++    0x72, 0x67, 0x09, 0xfc, },
++  { 0x9e, 0xf8, 0x18, 0x67, 0x93, 0x10, 0x9b, 0x39, 0x75, 0xe8, 0x8b, 0x38,
++    0x82, 0x7d, 0xb8, 0xb7, 0xa5, 0xaf, 0xe6, 0x6a, 0x22, 0x5e, 0x1f, 0x9c,
++    0x95, 0x29, 0x19, 0xf2, 0x4b, },
++  { 0xc8, 0x62, 0x25, 0xf5, 0x98, 0xc9, 0xea, 0xe5, 0x29, 0x3a, 0xd3, 0x22,
++    0xeb, 0xeb, 0x07, 0x7c, 0x15, 0x07, 0xee, 0x15, 0x61, 0xbb, 0x05, 0x30,
++    0x99, 0x7f, 0x11, 0xf6, 0x0a, 0x1d, },
++  { 0x68, 0x70, 0xf7, 0x90, 0xa1, 0x8b, 0x1f, 0x0f, 0xbb, 0xce, 0xd2, 0x0e,
++    0x33, 0x1f, 0x7f, 0xa9, 0x78, 0xa8, 0xa6, 0x81, 0x66, 0xab, 0x8d, 0xcd,
++    0x58, 0x55, 0x3a, 0x0b, 0x7a, 0xdb, 0xb5, },
++  { 0xdd, 0x35, 0xd2, 0xb4, 0xf6, 0xc7, 0xea, 0xab, 0x64, 0x24, 0x4e, 0xfe,
++    0xe5, 0x3d, 0x4e, 0x95, 0x8b, 0x6d, 0x6c, 0xbc, 0xb0, 0xf8, 0x88, 0x61,
++    0x09, 0xb7, 0x78, 0xa3, 0x31, 0xfe, 0xd9, 0x2f, },
++  { 0x0a, },
++  { 0x6e, 0xd4, },
++  { 0x64, 0xe9, 0xd1, },
++  { 0x30, 0xdd, 0x71, 0xef, },
++  { 0x11, 0xb5, 0x0c, 0x87, 0xc9, },
++  { 0x06, 0x1c, 0x6d, 0x04, 0x82, 0xd0, },
++  { 0x5c, 0x42, 0x0b, 0xee, 0xc5, 0x9c, 0xb2, },
++  { 0xe8, 0x29, 0xd6, 0xb4, 0x5d, 0xf7, 0x2b, 0x93, },
++  { 0x18, 0xca, 0x27, 0x72, 0x43, 0x39, 0x16, 0xbc, 0x6a, },
++  { 0x39, 0x8f, 0xfd, 0x64, 0xf5, 0x57, 0x23, 0xb0, 0x45, 0xf8, },
++  { 0xbb, 0x3a, 0x78, 0x6b, 0x02, 0x1d, 0x0b, 0x16, 0xe3, 0xb2, 0x9a, },
++  { 0xb8, 0xb4, 0x0b, 0xe5, 0xd4, 0x1d, 0x0d, 0x85, 0x49, 0x91, 0x35, 0xfa, },
++  { 0x6d, 0x48, 0x2a, 0x0c, 0x42, 0x08, 0xbd, 0xa9, 0x78, 0x6f, 0x18, 0xaf,
++    0xe2, },
++  { 0x10, 0x45, 0xd4, 0x58, 0x88, 0xec, 0x4e, 0x1e, 0xf6, 0x14, 0x92, 0x64,
++    0x7e, 0xb0, },
++  { 0x8b, 0x0b, 0x95, 0xee, 0x92, 0xc6, 0x3b, 0x91, 0xf1, 0x1e, 0xeb, 0x51,
++    0x98, 0x0a, 0x8d, },
++  { 0xa3, 0x50, 0x4d, 0xa5, 0x1d, 0x03, 0x68, 0xe9, 0x57, 0x78, 0xd6, 0x04,
++    0xf1, 0xc3, 0x94, 0xd8, },
++  { 0xb8, 0x66, 0x6e, 0xdd, 0x46, 0x15, 0xae, 0x3d, 0x83, 0x7e, 0xcf, 0xe7,
++    0x2c, 0xe8, 0x8f, 0xc7, 0x34, },
++  { 0x2e, 0xc0, 0x1f, 0x29, 0xea, 0xf6, 0xb9, 0xe2, 0xc2, 0x93, 0xeb, 0x41,
++    0x0d, 0xf0, 0x0a, 0x13, 0x0e, 0xa2, },
++  { 0x71, 0xb8, 0x33, 0xa9, 0x1b, 0xac, 0xf1, 0xb5, 0x42, 0x8f, 0x5e, 0x81,
++    0x34, 0x43, 0xb7, 0xa4, 0x18, 0x5c, 0x47, },
++  { 0xda, 0x45, 0xb8, 0x2e, 0x82, 0x1e, 0xc0, 0x59, 0x77, 0x9d, 0xfa, 0xb4,
++    0x1c, 0x5e, 0xa0, 0x2b, 0x33, 0x96, 0x5a, 0x58, },
++  { 0xe3, 0x09, 0x05, 0xa9, 0xeb, 0x48, 0x13, 0xad, 0x71, 0x88, 0x81, 0x9a,
++    0x3e, 0x2c, 0xe1, 0x23, 0x99, 0x13, 0x35, 0x9f, 0xb5, },
++  { 0xb7, 0x86, 0x2d, 0x16, 0xe1, 0x04, 0x00, 0x47, 0x47, 0x61, 0x31, 0xfb,
++    0x14, 0xac, 0xd8, 0xe9, 0xe3, 0x49, 0xbd, 0xf7, 0x9c, 0x3f, },
++  { 0x7f, 0xd9, 0x95, 0xa8, 0xa7, 0xa0, 0xcc, 0xba, 0xef, 0xb1, 0x0a, 0xa9,
++    0x21, 0x62, 0x08, 0x0f, 0x1b, 0xff, 0x7b, 0x9d, 0xae, 0xb2, 0x95, },
++  { 0x85, 0x99, 0xea, 0x33, 0xe0, 0x56, 0xff, 0x13, 0xc6, 0x61, 0x8c, 0xf9,
++    0x57, 0x05, 0x03, 0x11, 0xf9, 0xfb, 0x3a, 0xf7, 0xce, 0xbb, 0x52, 0x30, },
++  { 0xb2, 0x72, 0x9c, 0xf8, 0x77, 0x4e, 0x8f, 0x6b, 0x01, 0x6c, 0xff, 0x4e,
++    0x4f, 0x02, 0xd2, 0xbc, 0xeb, 0x51, 0x28, 0x99, 0x50, 0xab, 0xc4, 0x42,
++    0xe3, },
++  { 0x8b, 0x0a, 0xb5, 0x90, 0x8f, 0xf5, 0x7b, 0xdd, 0xba, 0x47, 0x37, 0xc9,
++    0x2a, 0xd5, 0x4b, 0x25, 0x08, 0x8b, 0x02, 0x17, 0xa7, 0x9e, 0x6b, 0x6e,
++    0xe3, 0x90, },
++  { 0x90, 0xdd, 0xf7, 0x75, 0xa7, 0xa3, 0x99, 0x5e, 0x5b, 0x7d, 0x75, 0xc3,
++    0x39, 0x6b, 0xa0, 0xe2, 0x44, 0x53, 0xb1, 0x9e, 0xc8, 0xf1, 0x77, 0x10,
++    0x58, 0x06, 0x9a, },
++  { 0x99, 0x52, 0xf0, 0x49, 0xa8, 0x8c, 0xec, 0xa6, 0x97, 0x32, 0x13, 0xb5,
++    0xf7, 0xa3, 0x8e, 0xfb, 0x4b, 0x59, 0x31, 0x3d, 0x01, 0x59, 0x98, 0x5d,
++    0x53, 0x03, 0x1a, 0x39, },
++  { 0x9f, 0xe0, 0xc2, 0xe5, 0x5d, 0x93, 0xd6, 0x9b, 0x47, 0x8f, 0x9b, 0xe0,
++    0x26, 0x35, 0x84, 0x20, 0x1d, 0xc5, 0x53, 0x10, 0x0f, 0x22, 0xb9, 0xb5,
++    0xd4, 0x36, 0xb1, 0xac, 0x73, },
++  { 0x30, 0x32, 0x20, 0x3b, 0x10, 0x28, 0xec, 0x1f, 0x4f, 0x9b, 0x47, 0x59,
++    0xeb, 0x7b, 0xee, 0x45, 0xfb, 0x0c, 0x49, 0xd8, 0x3d, 0x69, 0xbd, 0x90,
++    0x2c, 0xf0, 0x9e, 0x8d, 0xbf, 0xd5, },
++  { 0x2a, 0x37, 0x73, 0x7f, 0xf9, 0x96, 0x19, 0xaa, 0x25, 0xd8, 0x13, 0x28,
++    0x01, 0x29, 0x89, 0xdf, 0x6e, 0x0c, 0x9b, 0x43, 0x44, 0x51, 0xe9, 0x75,
++    0x26, 0x0c, 0xb7, 0x87, 0x66, 0x0b, 0x5f, },
++  { 0x23, 0xdf, 0x96, 0x68, 0x91, 0x86, 0xd0, 0x93, 0x55, 0x33, 0x24, 0xf6,
++    0xba, 0x08, 0x75, 0x5b, 0x59, 0x11, 0x69, 0xb8, 0xb9, 0xe5, 0x2c, 0x77,
++    0x02, 0xf6, 0x47, 0xee, 0x81, 0xdd, 0xb9, 0x06, },
++  { 0x9d, },
++  { 0x9d, 0x7d, },
++  { 0xfd, 0xc3, 0xda, },
++  { 0xe8, 0x82, 0xcd, 0x21, },
++  { 0xc3, 0x1d, 0x42, 0x4c, 0x74, },
++  { 0xe9, 0xda, 0xf1, 0xa2, 0xe5, 0x7c, },
++  { 0x52, 0xb8, 0x6f, 0x81, 0x5c, 0x3a, 0x4c, },
++  { 0x5b, 0x39, 0x26, 0xfc, 0x92, 0x5e, 0xe0, 0x49, },
++  { 0x59, 0xe4, 0x7c, 0x93, 0x1c, 0xf9, 0x28, 0x93, 0xde, },
++  { 0xde, 0xdf, 0xb2, 0x43, 0x61, 0x0b, 0x86, 0x16, 0x4c, 0x2e, },
++  { 0x14, 0x8f, 0x75, 0x51, 0xaf, 0xb9, 0xee, 0x51, 0x5a, 0xae, 0x23, },
++  { 0x43, 0x5f, 0x50, 0xd5, 0x70, 0xb0, 0x5b, 0x87, 0xf5, 0xd9, 0xb3, 0x6d, },
++  { 0x66, 0x0a, 0x64, 0x93, 0x79, 0x71, 0x94, 0x40, 0xb7, 0x68, 0x2d, 0xd3,
++    0x63, },
++  { 0x15, 0x00, 0xc4, 0x0c, 0x7d, 0x1b, 0x10, 0xa9, 0x73, 0x1b, 0x90, 0x6f,
++    0xe6, 0xa9, },
++  { 0x34, 0x75, 0xf3, 0x86, 0x8f, 0x56, 0xcf, 0x2a, 0x0a, 0xf2, 0x62, 0x0a,
++    0xf6, 0x0e, 0x20, },
++  { 0xb1, 0xde, 0xc9, 0xf5, 0xdb, 0xf3, 0x2f, 0x4c, 0xd6, 0x41, 0x7d, 0x39,
++    0x18, 0x3e, 0xc7, 0xc3, },
++  { 0xc5, 0x89, 0xb2, 0xf8, 0xb8, 0xc0, 0xa3, 0xb9, 0x3b, 0x10, 0x6d, 0x7c,
++    0x92, 0xfc, 0x7f, 0x34, 0x41, },
++  { 0xc4, 0xd8, 0xef, 0xba, 0xef, 0xd2, 0xaa, 0xc5, 0x6c, 0x8e, 0x3e, 0xbb,
++    0x12, 0xfc, 0x0f, 0x72, 0xbf, 0x0f, },
++  { 0xdd, 0x91, 0xd1, 0x15, 0x9e, 0x7d, 0xf8, 0xc1, 0xb9, 0x14, 0x63, 0x96,
++    0xb5, 0xcb, 0x83, 0x1d, 0x35, 0x1c, 0xec, },
++  { 0xa9, 0xf8, 0x52, 0xc9, 0x67, 0x76, 0x2b, 0xad, 0xfb, 0xd8, 0x3a, 0xa6,
++    0x74, 0x02, 0xae, 0xb8, 0x25, 0x2c, 0x63, 0x49, },
++  { 0x77, 0x1f, 0x66, 0x70, 0xfd, 0x50, 0x29, 0xaa, 0xeb, 0xdc, 0xee, 0xba,
++    0x75, 0x98, 0xdc, 0x93, 0x12, 0x3f, 0xdc, 0x7c, 0x38, },
++  { 0xe2, 0xe1, 0x89, 0x5c, 0x37, 0x38, 0x6a, 0xa3, 0x40, 0xac, 0x3f, 0xb0,
++    0xca, 0xfc, 0xa7, 0xf3, 0xea, 0xf9, 0x0f, 0x5d, 0x8e, 0x39, },
++  { 0x0f, 0x67, 0xc8, 0x38, 0x01, 0xb1, 0xb7, 0xb8, 0xa2, 0xe7, 0x0a, 0x6d,
++    0xd2, 0x63, 0x69, 0x9e, 0xcc, 0xf0, 0xf2, 0xbe, 0x9b, 0x98, 0xdd, },
++  { 0x13, 0xe1, 0x36, 0x30, 0xfe, 0xc6, 0x01, 0x8a, 0xa1, 0x63, 0x96, 0x59,
++    0xc2, 0xa9, 0x68, 0x3f, 0x58, 0xd4, 0x19, 0x0c, 0x40, 0xf3, 0xde, 0x02, },
++  { 0xa3, 0x9e, 0xce, 0xda, 0x42, 0xee, 0x8c, 0x6c, 0x5a, 0x7d, 0xdc, 0x89,
++    0x02, 0x77, 0xdd, 0xe7, 0x95, 0xbb, 0xff, 0x0d, 0xa4, 0xb5, 0x38, 0x1e,
++    0xaf, },
++  { 0x9a, 0xf6, 0xb5, 0x9a, 0x4f, 0xa9, 0x4f, 0x2c, 0x35, 0x3c, 0x24, 0xdc,
++    0x97, 0x6f, 0xd9, 0xa1, 0x7d, 0x1a, 0x85, 0x0b, 0xf5, 0xda, 0x2e, 0xe7,
++    0xb1, 0x1d, },
++  { 0x84, 0x1e, 0x8e, 0x3d, 0x45, 0xa5, 0xf2, 0x27, 0xf3, 0x31, 0xfe, 0xb9,
++    0xfb, 0xc5, 0x45, 0x99, 0x99, 0xdd, 0x93, 0x43, 0x02, 0xee, 0x58, 0xaf,
++    0xee, 0x6a, 0xbe, },
++  { 0x07, 0x2f, 0xc0, 0xa2, 0x04, 0xc4, 0xab, 0x7c, 0x26, 0xbb, 0xa8, 0xd8,
++    0xe3, 0x1c, 0x75, 0x15, 0x64, 0x5d, 0x02, 0x6a, 0xf0, 0x86, 0xe9, 0xcd,
++    0x5c, 0xef, 0xa3, 0x25, },
++  { 0x2f, 0x3b, 0x1f, 0xb5, 0x91, 0x8f, 0x86, 0xe0, 0xdc, 0x31, 0x48, 0xb6,
++    0xa1, 0x8c, 0xfd, 0x75, 0xbb, 0x7d, 0x3d, 0xc1, 0xf0, 0x10, 0x9a, 0xd8,
++    0x4b, 0x0e, 0xe3, 0x94, 0x9f, },
++  { 0x29, 0xbb, 0x8f, 0x6c, 0xd1, 0xf2, 0xb6, 0xaf, 0xe5, 0xe3, 0x2d, 0xdc,
++    0x6f, 0xa4, 0x53, 0x88, 0xd8, 0xcf, 0x4d, 0x45, 0x42, 0x62, 0xdb, 0xdf,
++    0xf8, 0x45, 0xc2, 0x13, 0xec, 0x35, },
++  { 0x06, 0x3c, 0xe3, 0x2c, 0x15, 0xc6, 0x43, 0x03, 0x81, 0xfb, 0x08, 0x76,
++    0x33, 0xcb, 0x02, 0xc1, 0xba, 0x33, 0xe5, 0xe0, 0xd1, 0x92, 0xa8, 0x46,
++    0x28, 0x3f, 0x3e, 0x9d, 0x2c, 0x44, 0x54, },
++  { 0xea, 0xbb, 0x96, 0xf8, 0xd1, 0x8b, 0x04, 0x11, 0x40, 0x78, 0x42, 0x02,
++    0x19, 0xd1, 0xbc, 0x65, 0x92, 0xd3, 0xc3, 0xd6, 0xd9, 0x19, 0xe7, 0xc3,
++    0x40, 0x97, 0xbd, 0xd4, 0xed, 0xfa, 0x5e, 0x28, },
++  { 0x02, },
++  { 0x52, 0xa8, },
++  { 0x38, 0x25, 0x0d, },
++  { 0xe3, 0x04, 0xd4, 0x92, },
++  { 0x97, 0xdb, 0xf7, 0x81, 0xca, },
++  { 0x8a, 0x56, 0x9d, 0x62, 0x56, 0xcc, },
++  { 0xa1, 0x8e, 0x3c, 0x72, 0x8f, 0x63, 0x03, },
++  { 0xf7, 0xf3, 0x39, 0x09, 0x0a, 0xa1, 0xbb, 0x23, },
++  { 0x6b, 0x03, 0xc0, 0xe9, 0xd9, 0x83, 0x05, 0x22, 0x01, },
++  { 0x1b, 0x4b, 0xf5, 0xd6, 0x4f, 0x05, 0x75, 0x91, 0x4c, 0x7f, },
++  { 0x4c, 0x8c, 0x25, 0x20, 0x21, 0xcb, 0xc2, 0x4b, 0x3a, 0x5b, 0x8d, },
++  { 0x56, 0xe2, 0x77, 0xa0, 0xb6, 0x9f, 0x81, 0xec, 0x83, 0x75, 0xc4, 0xf9, },
++  { 0x71, 0x70, 0x0f, 0xad, 0x4d, 0x35, 0x81, 0x9d, 0x88, 0x69, 0xf9, 0xaa,
++    0xd3, },
++  { 0x50, 0x6e, 0x86, 0x6e, 0x43, 0xc0, 0xc2, 0x44, 0xc2, 0xe2, 0xa0, 0x1c,
++    0xb7, 0x9a, },
++  { 0xe4, 0x7e, 0x72, 0xc6, 0x12, 0x8e, 0x7c, 0xfc, 0xbd, 0xe2, 0x08, 0x31,
++    0x3d, 0x47, 0x3d, },
++  { 0x08, 0x97, 0x5b, 0x80, 0xae, 0xc4, 0x1d, 0x50, 0x77, 0xdf, 0x1f, 0xd0,
++    0x24, 0xf0, 0x17, 0xc0, },
++  { 0x01, 0xb6, 0x29, 0xf4, 0xaf, 0x78, 0x5f, 0xb6, 0x91, 0xdd, 0x76, 0x76,
++    0xd2, 0xfd, 0x0c, 0x47, 0x40, },
++  { 0xa1, 0xd8, 0x09, 0x97, 0x7a, 0xa6, 0xc8, 0x94, 0xf6, 0x91, 0x7b, 0xae,
++    0x2b, 0x9f, 0x0d, 0x83, 0x48, 0xf7, },
++  { 0x12, 0xd5, 0x53, 0x7d, 0x9a, 0xb0, 0xbe, 0xd9, 0xed, 0xe9, 0x9e, 0xee,
++    0x61, 0x5b, 0x42, 0xf2, 0xc0, 0x73, 0xc0, },
++  { 0xd5, 0x77, 0xd6, 0x5c, 0x6e, 0xa5, 0x69, 0x2b, 0x3b, 0x8c, 0xd6, 0x7d,
++    0x1d, 0xbe, 0x2c, 0xa1, 0x02, 0x21, 0xcd, 0x29, },
++  { 0xa4, 0x98, 0x80, 0xca, 0x22, 0xcf, 0x6a, 0xab, 0x5e, 0x40, 0x0d, 0x61,
++    0x08, 0x21, 0xef, 0xc0, 0x6c, 0x52, 0xb4, 0xb0, 0x53, },
++  { 0xbf, 0xaf, 0x8f, 0x3b, 0x7a, 0x97, 0x33, 0xe5, 0xca, 0x07, 0x37, 0xfd,
++    0x15, 0xdf, 0xce, 0x26, 0x2a, 0xb1, 0xa7, 0x0b, 0xb3, 0xac, },
++  { 0x16, 0x22, 0xe1, 0xbc, 0x99, 0x4e, 0x01, 0xf0, 0xfa, 0xff, 0x8f, 0xa5,
++    0x0c, 0x61, 0xb0, 0xad, 0xcc, 0xb1, 0xe1, 0x21, 0x46, 0xfa, 0x2e, },
++  { 0x11, 0x5b, 0x0b, 0x2b, 0xe6, 0x14, 0xc1, 0xd5, 0x4d, 0x71, 0x5e, 0x17,
++    0xea, 0x23, 0xdd, 0x6c, 0xbd, 0x1d, 0xbe, 0x12, 0x1b, 0xee, 0x4c, 0x1a, },
++  { 0x40, 0x88, 0x22, 0xf3, 0x20, 0x6c, 0xed, 0xe1, 0x36, 0x34, 0x62, 0x2c,
++    0x98, 0x83, 0x52, 0xe2, 0x25, 0xee, 0xe9, 0xf5, 0xe1, 0x17, 0xf0, 0x5c,
++    0xae, },
++  { 0xc3, 0x76, 0x37, 0xde, 0x95, 0x8c, 0xca, 0x2b, 0x0c, 0x23, 0xe7, 0xb5,
++    0x38, 0x70, 0x61, 0xcc, 0xff, 0xd3, 0x95, 0x7b, 0xf3, 0xff, 0x1f, 0x9d,
++    0x59, 0x00, },
++  { 0x0c, 0x19, 0x52, 0x05, 0x22, 0x53, 0xcb, 0x48, 0xd7, 0x10, 0x0e, 0x7e,
++    0x14, 0x69, 0xb5, 0xa2, 0x92, 0x43, 0xa3, 0x9e, 0x4b, 0x8f, 0x51, 0x2c,
++    0x5a, 0x2c, 0x3b, },
++  { 0xe1, 0x9d, 0x70, 0x70, 0x28, 0xec, 0x86, 0x40, 0x55, 0x33, 0x56, 0xda,
++    0x88, 0xca, 0xee, 0xc8, 0x6a, 0x20, 0xb1, 0xe5, 0x3d, 0x57, 0xf8, 0x3c,
++    0x10, 0x07, 0x2a, 0xc4, },
++  { 0x0b, 0xae, 0xf1, 0xc4, 0x79, 0xee, 0x1b, 0x3d, 0x27, 0x35, 0x8d, 0x14,
++    0xd6, 0xae, 0x4e, 0x3c, 0xe9, 0x53, 0x50, 0xb5, 0xcc, 0x0c, 0xf7, 0xdf,
++    0xee, 0xa1, 0x74, 0xd6, 0x71, },
++  { 0xe6, 0xa4, 0xf4, 0x99, 0x98, 0xb9, 0x80, 0xea, 0x96, 0x7f, 0x4f, 0x33,
++    0xcf, 0x74, 0x25, 0x6f, 0x17, 0x6c, 0xbf, 0xf5, 0x5c, 0x38, 0xd0, 0xff,
++    0x96, 0xcb, 0x13, 0xf9, 0xdf, 0xfd, },
++  { 0xbe, 0x92, 0xeb, 0xba, 0x44, 0x2c, 0x24, 0x74, 0xd4, 0x03, 0x27, 0x3c,
++    0x5d, 0x5b, 0x03, 0x30, 0x87, 0x63, 0x69, 0xe0, 0xb8, 0x94, 0xf4, 0x44,
++    0x7e, 0xad, 0xcd, 0x20, 0x12, 0x16, 0x79, },
++  { 0x30, 0xf1, 0xc4, 0x8e, 0x05, 0x90, 0x2a, 0x97, 0x63, 0x94, 0x46, 0xff,
++    0xce, 0xd8, 0x67, 0xa7, 0xac, 0x33, 0x8c, 0x95, 0xb7, 0xcd, 0xa3, 0x23,
++    0x98, 0x9d, 0x76, 0x6c, 0x9d, 0xa8, 0xd6, 0x8a, },
++  { 0xbe, },
++  { 0x17, 0x6c, },
++  { 0x1a, 0x42, 0x4f, },
++  { 0xba, 0xaf, 0xb7, 0x65, },
++  { 0xc2, 0x63, 0x43, 0x6a, 0xea, },
++  { 0xe4, 0x4d, 0xad, 0xf2, 0x0b, 0x02, },
++  { 0x04, 0xc7, 0xc4, 0x7f, 0xa9, 0x2b, 0xce, },
++  { 0x66, 0xf6, 0x67, 0xcb, 0x03, 0x53, 0xc8, 0xf1, },
++  { 0x56, 0xa3, 0x60, 0x78, 0xc9, 0x5f, 0x70, 0x1b, 0x5e, },
++  { 0x99, 0xff, 0x81, 0x7c, 0x13, 0x3c, 0x29, 0x79, 0x4b, 0x65, },
++  { 0x51, 0x10, 0x50, 0x93, 0x01, 0x93, 0xb7, 0x01, 0xc9, 0x18, 0xb7, },
++  { 0x8e, 0x3c, 0x42, 0x1e, 0x5e, 0x7d, 0xc1, 0x50, 0x70, 0x1f, 0x00, 0x98, },
++  { 0x5f, 0xd9, 0x9b, 0xc8, 0xd7, 0xb2, 0x72, 0x62, 0x1a, 0x1e, 0xba, 0x92,
++    0xe9, },
++  { 0x70, 0x2b, 0xba, 0xfe, 0xad, 0x5d, 0x96, 0x3f, 0x27, 0xc2, 0x41, 0x6d,
++    0xc4, 0xb3, },
++  { 0xae, 0xe0, 0xd5, 0xd4, 0xc7, 0xae, 0x15, 0x5e, 0xdc, 0xdd, 0x33, 0x60,
++    0xd7, 0xd3, 0x5e, },
++  { 0x79, 0x8e, 0xbc, 0x9e, 0x20, 0xb9, 0x19, 0x4b, 0x63, 0x80, 0xf3, 0x16,
++    0xaf, 0x39, 0xbd, 0x92, },
++  { 0xc2, 0x0e, 0x85, 0xa0, 0x0b, 0x9a, 0xb0, 0xec, 0xde, 0x38, 0xd3, 0x10,
++    0xd9, 0xa7, 0x66, 0x27, 0xcf, },
++  { 0x0e, 0x3b, 0x75, 0x80, 0x67, 0x14, 0x0c, 0x02, 0x90, 0xd6, 0xb3, 0x02,
++    0x81, 0xf6, 0xa6, 0x87, 0xce, 0x58, },
++  { 0x79, 0xb5, 0xe9, 0x5d, 0x52, 0x4d, 0xf7, 0x59, 0xf4, 0x2e, 0x27, 0xdd,
++    0xb3, 0xed, 0x57, 0x5b, 0x82, 0xea, 0x6f, },
++  { 0xa2, 0x97, 0xf5, 0x80, 0x02, 0x3d, 0xde, 0xa3, 0xf9, 0xf6, 0xab, 0xe3,
++    0x57, 0x63, 0x7b, 0x9b, 0x10, 0x42, 0x6f, 0xf2, },
++  { 0x12, 0x7a, 0xfc, 0xb7, 0x67, 0x06, 0x0c, 0x78, 0x1a, 0xfe, 0x88, 0x4f,
++    0xc6, 0xac, 0x52, 0x96, 0x64, 0x28, 0x97, 0x84, 0x06, },
++  { 0xc5, 0x04, 0x44, 0x6b, 0xb2, 0xa5, 0xa4, 0x66, 0xe1, 0x76, 0xa2, 0x51,
++    0xf9, 0x59, 0x69, 0x97, 0x56, 0x0b, 0xbf, 0x50, 0xb3, 0x34, },
++  { 0x21, 0x32, 0x6b, 0x42, 0xb5, 0xed, 0x71, 0x8d, 0xf7, 0x5a, 0x35, 0xe3,
++    0x90, 0xe2, 0xee, 0xaa, 0x89, 0xf6, 0xc9, 0x9c, 0x4d, 0x73, 0xf4, },
++  { 0x4c, 0xa6, 0x09, 0xf4, 0x48, 0xe7, 0x46, 0xbc, 0x49, 0xfc, 0xe5, 0xda,
++    0xd1, 0x87, 0x13, 0x17, 0x4c, 0x59, 0x71, 0x26, 0x5b, 0x2c, 0x42, 0xb7, },
++  { 0x13, 0x63, 0xf3, 0x40, 0x02, 0xe5, 0xa3, 0x3a, 0x5e, 0x8e, 0xf8, 0xb6,
++    0x8a, 0x49, 0x60, 0x76, 0x34, 0x72, 0x94, 0x73, 0xf6, 0xd9, 0x21, 0x6a,
++    0x26, },
++  { 0xdf, 0x75, 0x16, 0x10, 0x1b, 0x5e, 0x81, 0xc3, 0xc8, 0xde, 0x34, 0x24,
++    0xb0, 0x98, 0xeb, 0x1b, 0x8f, 0xa1, 0x9b, 0x05, 0xee, 0xa5, 0xe9, 0x35,
++    0xf4, 0x1d, },
++  { 0xcd, 0x21, 0x93, 0x6e, 0x5b, 0xa0, 0x26, 0x2b, 0x21, 0x0e, 0xa0, 0xb9,
++    0x1c, 0xb5, 0xbb, 0xb8, 0xf8, 0x1e, 0xff, 0x5c, 0xa8, 0xf9, 0x39, 0x46,
++    0x4e, 0x29, 0x26, },
++  { 0x73, 0x7f, 0x0e, 0x3b, 0x0b, 0x5c, 0xf9, 0x60, 0xaa, 0x88, 0xa1, 0x09,
++    0xb1, 0x5d, 0x38, 0x7b, 0x86, 0x8f, 0x13, 0x7a, 0x8d, 0x72, 0x7a, 0x98,
++    0x1a, 0x5b, 0xff, 0xc9, },
++  { 0xd3, 0x3c, 0x61, 0x71, 0x44, 0x7e, 0x31, 0x74, 0x98, 0x9d, 0x9a, 0xd2,
++    0x27, 0xf3, 0x46, 0x43, 0x42, 0x51, 0xd0, 0x5f, 0xe9, 0x1c, 0x5c, 0x69,
++    0xbf, 0xf6, 0xbe, 0x3c, 0x40, },
++  { 0x31, 0x99, 0x31, 0x9f, 0xaa, 0x43, 0x2e, 0x77, 0x3e, 0x74, 0x26, 0x31,
++    0x5e, 0x61, 0xf1, 0x87, 0xe2, 0xeb, 0x9b, 0xcd, 0xd0, 0x3a, 0xee, 0x20,
++    0x7e, 0x10, 0x0a, 0x0b, 0x7e, 0xfa, },
++  { 0xa4, 0x27, 0x80, 0x67, 0x81, 0x2a, 0xa7, 0x62, 0xf7, 0x6e, 0xda, 0xd4,
++    0x5c, 0x39, 0x74, 0xad, 0x7e, 0xbe, 0xad, 0xa5, 0x84, 0x7f, 0xa9, 0x30,
++    0x5d, 0xdb, 0xe2, 0x05, 0x43, 0xf7, 0x1b, },
++  { 0x0b, 0x37, 0xd8, 0x02, 0xe1, 0x83, 0xd6, 0x80, 0xf2, 0x35, 0xc2, 0xb0,
++    0x37, 0xef, 0xef, 0x5e, 0x43, 0x93, 0xf0, 0x49, 0x45, 0x0a, 0xef, 0xb5,
++    0x76, 0x70, 0x12, 0x44, 0xc4, 0xdb, 0xf5, 0x7a, },
++  { 0x1f, },
++  { 0x82, 0x60, },
++  { 0xcc, 0xe3, 0x08, },
++  { 0x56, 0x17, 0xe4, 0x59, },
++  { 0xe2, 0xd7, 0x9e, 0xc4, 0x4c, },
++  { 0xb2, 0xad, 0xd3, 0x78, 0x58, 0x5a, },
++  { 0xce, 0x43, 0xb4, 0x02, 0x96, 0xab, 0x3c, },
++  { 0xe6, 0x05, 0x1a, 0x73, 0x22, 0x32, 0xbb, 0x77, },
++  { 0x23, 0xe7, 0xda, 0xfe, 0x2c, 0xef, 0x8c, 0x22, 0xec, },
++  { 0xe9, 0x8e, 0x55, 0x38, 0xd1, 0xd7, 0x35, 0x23, 0x98, 0xc7, },
++  { 0xb5, 0x81, 0x1a, 0xe5, 0xb5, 0xa5, 0xd9, 0x4d, 0xca, 0x41, 0xe7, },
++  { 0x41, 0x16, 0x16, 0x95, 0x8d, 0x9e, 0x0c, 0xea, 0x8c, 0x71, 0x9a, 0xc1, },
++  { 0x7c, 0x33, 0xc0, 0xa4, 0x00, 0x62, 0xea, 0x60, 0x67, 0xe4, 0x20, 0xbc,
++    0x5b, },
++  { 0xdb, 0xb1, 0xdc, 0xfd, 0x08, 0xc0, 0xde, 0x82, 0xd1, 0xde, 0x38, 0xc0,
++    0x90, 0x48, },
++  { 0x37, 0x18, 0x2e, 0x0d, 0x61, 0xaa, 0x61, 0xd7, 0x86, 0x20, 0x16, 0x60,
++    0x04, 0xd9, 0xd5, },
++  { 0xb0, 0xcf, 0x2c, 0x4c, 0x5e, 0x5b, 0x4f, 0x2a, 0x23, 0x25, 0x58, 0x47,
++    0xe5, 0x31, 0x06, 0x70, },
++  { 0x91, 0xa0, 0xa3, 0x86, 0x4e, 0xe0, 0x72, 0x38, 0x06, 0x67, 0x59, 0x5c,
++    0x70, 0x25, 0xdb, 0x33, 0x27, },
++  { 0x44, 0x58, 0x66, 0xb8, 0x58, 0xc7, 0x13, 0xed, 0x4c, 0xc0, 0xf4, 0x9a,
++    0x1e, 0x67, 0x75, 0x33, 0xb6, 0xb8, },
++  { 0x7f, 0x98, 0x4a, 0x8e, 0x50, 0xa2, 0x5c, 0xcd, 0x59, 0xde, 0x72, 0xb3,
++    0x9d, 0xc3, 0x09, 0x8a, 0xab, 0x56, 0xf1, },
++  { 0x80, 0x96, 0x49, 0x1a, 0x59, 0xa2, 0xc5, 0xd5, 0xa7, 0x20, 0x8a, 0xb7,
++    0x27, 0x62, 0x84, 0x43, 0xc6, 0xe1, 0x1b, 0x5d, },
++  { 0x6b, 0xb7, 0x2b, 0x26, 0x62, 0x14, 0x70, 0x19, 0x3d, 0x4d, 0xac, 0xac,
++    0x63, 0x58, 0x5e, 0x94, 0xb5, 0xb7, 0xe8, 0xe8, 0xa2, },
++  { 0x20, 0xa8, 0xc0, 0xfd, 0x63, 0x3d, 0x6e, 0x98, 0xcf, 0x0c, 0x49, 0x98,
++    0xe4, 0x5a, 0xfe, 0x8c, 0xaa, 0x70, 0x82, 0x1c, 0x7b, 0x74, },
++  { 0xc8, 0xe8, 0xdd, 0xdf, 0x69, 0x30, 0x01, 0xc2, 0x0f, 0x7e, 0x2f, 0x11,
++    0xcc, 0x3e, 0x17, 0xa5, 0x69, 0x40, 0x3f, 0x0e, 0x79, 0x7f, 0xcf, },
++  { 0xdb, 0x61, 0xc0, 0xe2, 0x2e, 0x49, 0x07, 0x31, 0x1d, 0x91, 0x42, 0x8a,
++    0xfc, 0x5e, 0xd3, 0xf8, 0x56, 0x1f, 0x2b, 0x73, 0xfd, 0x9f, 0xb2, 0x8e, },
++  { 0x0c, 0x89, 0x55, 0x0c, 0x1f, 0x59, 0x2c, 0x9d, 0x1b, 0x29, 0x1d, 0x41,
++    0x1d, 0xe6, 0x47, 0x8f, 0x8c, 0x2b, 0xea, 0x8f, 0xf0, 0xff, 0x21, 0x70,
++    0x88, },
++  { 0x12, 0x18, 0x95, 0xa6, 0x59, 0xb1, 0x31, 0x24, 0x45, 0x67, 0x55, 0xa4,
++    0x1a, 0x2d, 0x48, 0x67, 0x1b, 0x43, 0x88, 0x2d, 0x8e, 0xa0, 0x70, 0xb3,
++    0xc6, 0xbb, },
++  { 0xe7, 0xb1, 0x1d, 0xb2, 0x76, 0x4d, 0x68, 0x68, 0x68, 0x23, 0x02, 0x55,
++    0x3a, 0xe2, 0xe5, 0xd5, 0x4b, 0x43, 0xf9, 0x34, 0x77, 0x5c, 0xa1, 0xf5,
++    0x55, 0xfd, 0x4f, },
++  { 0x8c, 0x87, 0x5a, 0x08, 0x3a, 0x73, 0xad, 0x61, 0xe1, 0xe7, 0x99, 0x7e,
++    0xf0, 0x5d, 0xe9, 0x5d, 0x16, 0x43, 0x80, 0x2f, 0xd0, 0x66, 0x34, 0xe2,
++    0x42, 0x64, 0x3b, 0x1a, },
++  { 0x39, 0xc1, 0x99, 0xcf, 0x22, 0xbf, 0x16, 0x8f, 0x9f, 0x80, 0x7f, 0x95,
++    0x0a, 0x05, 0x67, 0x27, 0xe7, 0x15, 0xdf, 0x9d, 0xb2, 0xfe, 0x1c, 0xb5,
++    0x1d, 0x60, 0x8f, 0x8a, 0x1d, },
++  { 0x9b, 0x6e, 0x08, 0x09, 0x06, 0x73, 0xab, 0x68, 0x02, 0x62, 0x1a, 0xe4,
++    0xd4, 0xdf, 0xc7, 0x02, 0x4c, 0x6a, 0x5f, 0xfd, 0x23, 0xac, 0xae, 0x6d,
++    0x43, 0xa4, 0x7a, 0x50, 0x60, 0x3c, },
++  { 0x1d, 0xb4, 0xc6, 0xe1, 0xb1, 0x4b, 0xe3, 0xf2, 0xe2, 0x1a, 0x73, 0x1b,
++    0xa0, 0x92, 0xa7, 0xf5, 0xff, 0x8f, 0x8b, 0x5d, 0xdf, 0xa8, 0x04, 0xb3,
++    0xb0, 0xf7, 0xcc, 0x12, 0xfa, 0x35, 0x46, },
++  { 0x49, 0x45, 0x97, 0x11, 0x0f, 0x1c, 0x60, 0x8e, 0xe8, 0x47, 0x30, 0xcf,
++    0x60, 0xa8, 0x71, 0xc5, 0x1b, 0xe9, 0x39, 0x4d, 0x49, 0xb6, 0x12, 0x1f,
++    0x24, 0xab, 0x37, 0xff, 0x83, 0xc2, 0xe1, 0x3a, },
++  { 0x60, },
++  { 0x24, 0x26, },
++  { 0x47, 0xeb, 0xc9, },
++  { 0x4a, 0xd0, 0xbc, 0xf0, },
++  { 0x8e, 0x2b, 0xc9, 0x85, 0x3c, },
++  { 0xa2, 0x07, 0x15, 0xb8, 0x12, 0x74, },
++  { 0x0f, 0xdb, 0x5b, 0x33, 0x69, 0xfe, 0x4b, },
++  { 0xa2, 0x86, 0x54, 0xf4, 0xfd, 0xb2, 0xd4, 0xe6, },
++  { 0xbb, 0x84, 0x78, 0x49, 0x27, 0x8e, 0x61, 0xda, 0x60, },
++  { 0x04, 0xc3, 0xcd, 0xaa, 0x8f, 0xa7, 0x03, 0xc9, 0xf9, 0xb6, },
++  { 0xf8, 0x27, 0x1d, 0x61, 0xdc, 0x21, 0x42, 0xdd, 0xad, 0x92, 0x40, },
++  { 0x12, 0x87, 0xdf, 0xc2, 0x41, 0x45, 0x5a, 0x36, 0x48, 0x5b, 0x51, 0x2b, },
++  { 0xbb, 0x37, 0x5d, 0x1f, 0xf1, 0x68, 0x7a, 0xc4, 0xa5, 0xd2, 0xa4, 0x91,
++    0x8d, },
++  { 0x5b, 0x27, 0xd1, 0x04, 0x54, 0x52, 0x9f, 0xa3, 0x47, 0x86, 0x33, 0x33,
++    0xbf, 0xa0, },
++  { 0xcf, 0x04, 0xea, 0xf8, 0x03, 0x2a, 0x43, 0xff, 0xa6, 0x68, 0x21, 0x4c,
++    0xd5, 0x4b, 0xed, },
++  { 0xaf, 0xb8, 0xbc, 0x63, 0x0f, 0x18, 0x4d, 0xe2, 0x7a, 0xdd, 0x46, 0x44,
++    0xc8, 0x24, 0x0a, 0xb7, },
++  { 0x3e, 0xdc, 0x36, 0xe4, 0x89, 0xb1, 0xfa, 0xc6, 0x40, 0x93, 0x2e, 0x75,
++    0xb2, 0x15, 0xd1, 0xb1, 0x10, },
++  { 0x6c, 0xd8, 0x20, 0x3b, 0x82, 0x79, 0xf9, 0xc8, 0xbc, 0x9d, 0xe0, 0x35,
++    0xbe, 0x1b, 0x49, 0x1a, 0xbc, 0x3a, },
++  { 0x78, 0x65, 0x2c, 0xbe, 0x35, 0x67, 0xdc, 0x78, 0xd4, 0x41, 0xf6, 0xc9,
++    0xde, 0xde, 0x1f, 0x18, 0x13, 0x31, 0x11, },
++  { 0x8a, 0x7f, 0xb1, 0x33, 0x8f, 0x0c, 0x3c, 0x0a, 0x06, 0x61, 0xf0, 0x47,
++    0x29, 0x1b, 0x29, 0xbc, 0x1c, 0x47, 0xef, 0x7a, },
++  { 0x65, 0x91, 0xf1, 0xe6, 0xb3, 0x96, 0xd3, 0x8c, 0xc2, 0x4a, 0x59, 0x35,
++    0x72, 0x8e, 0x0b, 0x9a, 0x87, 0xca, 0x34, 0x7b, 0x63, },
++  { 0x5f, 0x08, 0x87, 0x80, 0x56, 0x25, 0x89, 0x77, 0x61, 0x8c, 0x64, 0xa1,
++    0x59, 0x6d, 0x59, 0x62, 0xe8, 0x4a, 0xc8, 0x58, 0x99, 0xd1, },
++  { 0x23, 0x87, 0x1d, 0xed, 0x6f, 0xf2, 0x91, 0x90, 0xe2, 0xfe, 0x43, 0x21,
++    0xaf, 0x97, 0xc6, 0xbc, 0xd7, 0x15, 0xc7, 0x2d, 0x08, 0x77, 0x91, },
++  { 0x90, 0x47, 0x9a, 0x9e, 0x3a, 0xdf, 0xf3, 0xc9, 0x4c, 0x1e, 0xa7, 0xd4,
++    0x6a, 0x32, 0x90, 0xfe, 0xb7, 0xb6, 0x7b, 0xfa, 0x96, 0x61, 0xfb, 0xa4, },
++  { 0xb1, 0x67, 0x60, 0x45, 0xb0, 0x96, 0xc5, 0x15, 0x9f, 0x4d, 0x26, 0xd7,
++    0x9d, 0xf1, 0xf5, 0x6d, 0x21, 0x00, 0x94, 0x31, 0x64, 0x94, 0xd3, 0xa7,
++    0xd3, },
++  { 0x02, 0x3e, 0xaf, 0xf3, 0x79, 0x73, 0xa5, 0xf5, 0xcc, 0x7a, 0x7f, 0xfb,
++    0x79, 0x2b, 0x85, 0x8c, 0x88, 0x72, 0x06, 0xbe, 0xfe, 0xaf, 0xc1, 0x16,
++    0xa6, 0xd6, },
++  { 0x2a, 0xb0, 0x1a, 0xe5, 0xaa, 0x6e, 0xb3, 0xae, 0x53, 0x85, 0x33, 0x80,
++    0x75, 0xae, 0x30, 0xe6, 0xb8, 0x72, 0x42, 0xf6, 0x25, 0x4f, 0x38, 0x88,
++    0x55, 0xd1, 0xa9, },
++  { 0x90, 0xd8, 0x0c, 0xc0, 0x93, 0x4b, 0x4f, 0x9e, 0x65, 0x6c, 0xa1, 0x54,
++    0xa6, 0xf6, 0x6e, 0xca, 0xd2, 0xbb, 0x7e, 0x6a, 0x1c, 0xd3, 0xce, 0x46,
++    0xef, 0xb0, 0x00, 0x8d, },
++  { 0xed, 0x9c, 0x49, 0xcd, 0xc2, 0xde, 0x38, 0x0e, 0xe9, 0x98, 0x6c, 0xc8,
++    0x90, 0x9e, 0x3c, 0xd4, 0xd3, 0xeb, 0x88, 0x32, 0xc7, 0x28, 0xe3, 0x94,
++    0x1c, 0x9f, 0x8b, 0xf3, 0xcb, },
++  { 0xac, 0xe7, 0x92, 0x16, 0xb4, 0x14, 0xa0, 0xe4, 0x04, 0x79, 0xa2, 0xf4,
++    0x31, 0xe6, 0x0c, 0x26, 0xdc, 0xbf, 0x2f, 0x69, 0x1b, 0x55, 0x94, 0x67,
++    0xda, 0x0c, 0xd7, 0x32, 0x1f, 0xef, },
++  { 0x68, 0x63, 0x85, 0x57, 0x95, 0x9e, 0x42, 0x27, 0x41, 0x43, 0x42, 0x02,
++    0xa5, 0x78, 0xa7, 0xc6, 0x43, 0xc1, 0x6a, 0xba, 0x70, 0x80, 0xcd, 0x04,
++    0xb6, 0x78, 0x76, 0x29, 0xf3, 0xe8, 0xa0, },
++  { 0xe6, 0xac, 0x8d, 0x9d, 0xf0, 0xc0, 0xf7, 0xf7, 0xe3, 0x3e, 0x4e, 0x28,
++    0x0f, 0x59, 0xb2, 0x67, 0x9e, 0x84, 0x34, 0x42, 0x96, 0x30, 0x2b, 0xca,
++    0x49, 0xb6, 0xc5, 0x9a, 0x84, 0x59, 0xa7, 0x81, },
++  { 0x7e, },
++  { 0x1e, 0x21, },
++  { 0x26, 0xd3, 0xdd, },
++  { 0x2c, 0xd4, 0xb3, 0x3d, },
++  { 0x86, 0x7b, 0x76, 0x3c, 0xf0, },
++  { 0x12, 0xc3, 0x70, 0x1d, 0x55, 0x18, },
++  { 0x96, 0xc2, 0xbd, 0x61, 0x55, 0xf4, 0x24, },
++  { 0x20, 0x51, 0xf7, 0x86, 0x58, 0x8f, 0x07, 0x2a, },
++  { 0x93, 0x15, 0xa8, 0x1d, 0xda, 0x97, 0xee, 0x0e, 0x6c, },
++  { 0x39, 0x93, 0xdf, 0xd5, 0x0e, 0xca, 0xdc, 0x7a, 0x92, 0xce, },
++  { 0x60, 0xd5, 0xfd, 0xf5, 0x1b, 0x26, 0x82, 0x26, 0x73, 0x02, 0xbc, },
++  { 0x98, 0xf2, 0x34, 0xe1, 0xf5, 0xfb, 0x00, 0xac, 0x10, 0x4a, 0x38, 0x9f, },
++  { 0xda, 0x3a, 0x92, 0x8a, 0xd0, 0xcd, 0x12, 0xcd, 0x15, 0xbb, 0xab, 0x77,
++    0x66, },
++  { 0xa2, 0x92, 0x1a, 0xe5, 0xca, 0x0c, 0x30, 0x75, 0xeb, 0xaf, 0x00, 0x31,
++    0x55, 0x66, },
++  { 0x06, 0xea, 0xfd, 0x3e, 0x86, 0x38, 0x62, 0x4e, 0xa9, 0x12, 0xa4, 0x12,
++    0x43, 0xbf, 0xa1, },
++  { 0xe4, 0x71, 0x7b, 0x94, 0xdb, 0xa0, 0xd2, 0xff, 0x9b, 0xeb, 0xad, 0x8e,
++    0x95, 0x8a, 0xc5, 0xed, },
++  { 0x25, 0x5a, 0x77, 0x71, 0x41, 0x0e, 0x7a, 0xe9, 0xed, 0x0c, 0x10, 0xef,
++    0xf6, 0x2b, 0x3a, 0xba, 0x60, },
++  { 0xee, 0xe2, 0xa3, 0x67, 0x64, 0x1d, 0xc6, 0x04, 0xc4, 0xe1, 0x68, 0xd2,
++    0x6e, 0xd2, 0x91, 0x75, 0x53, 0x07, },
++  { 0xe0, 0xf6, 0x4d, 0x8f, 0x68, 0xfc, 0x06, 0x7e, 0x18, 0x79, 0x7f, 0x2b,
++    0x6d, 0xef, 0x46, 0x7f, 0xab, 0xb2, 0xad, },
++  { 0x3d, 0x35, 0x88, 0x9f, 0x2e, 0xcf, 0x96, 0x45, 0x07, 0x60, 0x71, 0x94,
++    0x00, 0x8d, 0xbf, 0xf4, 0xef, 0x46, 0x2e, 0x3c, },
++  { 0x43, 0xcf, 0x98, 0xf7, 0x2d, 0xf4, 0x17, 0xe7, 0x8c, 0x05, 0x2d, 0x9b,
++    0x24, 0xfb, 0x4d, 0xea, 0x4a, 0xec, 0x01, 0x25, 0x29, },
++  { 0x8e, 0x73, 0x9a, 0x78, 0x11, 0xfe, 0x48, 0xa0, 0x3b, 0x1a, 0x26, 0xdf,
++    0x25, 0xe9, 0x59, 0x1c, 0x70, 0x07, 0x9f, 0xdc, 0xa0, 0xa6, },
++  { 0xe8, 0x47, 0x71, 0xc7, 0x3e, 0xdf, 0xb5, 0x13, 0xb9, 0x85, 0x13, 0xa8,
++    0x54, 0x47, 0x6e, 0x59, 0x96, 0x09, 0x13, 0x5f, 0x82, 0x16, 0x0b, },
++  { 0xfb, 0xc0, 0x8c, 0x03, 0x21, 0xb3, 0xc4, 0xb5, 0x43, 0x32, 0x6c, 0xea,
++    0x7f, 0xa8, 0x43, 0x91, 0xe8, 0x4e, 0x3f, 0xbf, 0x45, 0x58, 0x6a, 0xa3, },
++  { 0x55, 0xf8, 0xf3, 0x00, 0x76, 0x09, 0xef, 0x69, 0x5d, 0xd2, 0x8a, 0xf2,
++    0x65, 0xc3, 0xcb, 0x9b, 0x43, 0xfd, 0xb1, 0x7e, 0x7f, 0xa1, 0x94, 0xb0,
++    0xd7, },
++  { 0xaa, 0x13, 0xc1, 0x51, 0x40, 0x6d, 0x8d, 0x4c, 0x0a, 0x95, 0x64, 0x7b,
++    0xd1, 0x96, 0xb6, 0x56, 0xb4, 0x5b, 0xcf, 0xd6, 0xd9, 0x15, 0x97, 0xdd,
++    0xb6, 0xef, },
++  { 0xaf, 0xb7, 0x36, 0xb0, 0x04, 0xdb, 0xd7, 0x9c, 0x9a, 0x44, 0xc4, 0xf6,
++    0x1f, 0x12, 0x21, 0x2d, 0x59, 0x30, 0x54, 0xab, 0x27, 0x61, 0xa3, 0x57,
++    0xef, 0xf8, 0x53, },
++  { 0x97, 0x34, 0x45, 0x3e, 0xce, 0x7c, 0x35, 0xa2, 0xda, 0x9f, 0x4b, 0x46,
++    0x6c, 0x11, 0x67, 0xff, 0x2f, 0x76, 0x58, 0x15, 0x71, 0xfa, 0x44, 0x89,
++    0x89, 0xfd, 0xf7, 0x99, },
++  { 0x1f, 0xb1, 0x62, 0xeb, 0x83, 0xc5, 0x9c, 0x89, 0xf9, 0x2c, 0xd2, 0x03,
++    0x61, 0xbc, 0xbb, 0xa5, 0x74, 0x0e, 0x9b, 0x7e, 0x82, 0x3e, 0x70, 0x0a,
++    0xa9, 0x8f, 0x2b, 0x59, 0xfb, },
++  { 0xf8, 0xca, 0x5e, 0x3a, 0x4f, 0x9e, 0x10, 0x69, 0x10, 0xd5, 0x4c, 0xeb,
++    0x1a, 0x0f, 0x3c, 0x6a, 0x98, 0xf5, 0xb0, 0x97, 0x5b, 0x37, 0x2f, 0x0d,
++    0xbd, 0x42, 0x4b, 0x69, 0xa1, 0x82, },
++  { 0x12, 0x8c, 0x6d, 0x52, 0x08, 0xef, 0x74, 0xb2, 0xe6, 0xaa, 0xd3, 0xb0,
++    0x26, 0xb0, 0xd9, 0x94, 0xb6, 0x11, 0x45, 0x0e, 0x36, 0x71, 0x14, 0x2d,
++    0x41, 0x8c, 0x21, 0x53, 0x31, 0xe9, 0x68, },
++  { 0xee, 0xea, 0x0d, 0x89, 0x47, 0x7e, 0x72, 0xd1, 0xd8, 0xce, 0x58, 0x4c,
++    0x94, 0x1f, 0x0d, 0x51, 0x08, 0xa3, 0xb6, 0x3d, 0xe7, 0x82, 0x46, 0x92,
++    0xd6, 0x98, 0x6b, 0x07, 0x10, 0x65, 0x52, 0x65, },
++};
++
++bool __init blake2s_selftest(void)
++{
++	u8 key[BLAKE2S_KEY_SIZE];
++	u8 buf[ARRAY_SIZE(blake2s_testvecs)];
++	u8 hash[BLAKE2S_HASH_SIZE];
++	struct blake2s_state state;
++	bool success = true;
++	int i, l;
++
++	key[0] = key[1] = 1;
++	for (i = 2; i < sizeof(key); ++i)
++		key[i] = key[i - 2] + key[i - 1];
++
++	for (i = 0; i < sizeof(buf); ++i)
++		buf[i] = (u8)i;
++
++	for (i = l = 0; i < ARRAY_SIZE(blake2s_testvecs); l = (l + 37) % ++i) {
++		int outlen = 1 + i % BLAKE2S_HASH_SIZE;
++		int keylen = (13 * i) % (BLAKE2S_KEY_SIZE + 1);
++
++		blake2s(hash, buf, key + BLAKE2S_KEY_SIZE - keylen, outlen, i,
++			keylen);
++		if (memcmp(hash, blake2s_testvecs[i], outlen)) {
++			pr_err("blake2s self-test %d: FAIL\n", i + 1);
++			success = false;
++		}
++
++		if (!keylen)
++			blake2s_init(&state, outlen);
++		else
++			blake2s_init_key(&state, outlen,
++					 key + BLAKE2S_KEY_SIZE - keylen,
++					 keylen);
++
++		blake2s_update(&state, buf, l);
++		blake2s_update(&state, buf + l, i - l);
++		blake2s_final(&state, hash);
++		if (memcmp(hash, blake2s_testvecs[i], outlen)) {
++			pr_err("blake2s init/update/final self-test %d: FAIL\n",
++			       i + 1);
++			success = false;
++		}
++	}
++
++	return success;
++}
+diff --git a/lib/crypto/blake2s.c b/lib/crypto/blake2s.c
+new file mode 100644
+index 0000000000000..536fce87555b3
+--- /dev/null
++++ b/lib/crypto/blake2s.c
+@@ -0,0 +1,78 @@
++// SPDX-License-Identifier: GPL-2.0 OR MIT
++/*
++ * Copyright (C) 2015-2019 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
++ *
++ * This is an implementation of the BLAKE2s hash and PRF functions.
++ *
++ * Information: https://blake2.net/
++ *
++ */
++
++#include <crypto/internal/blake2s.h>
++#include <linux/types.h>
++#include <linux/string.h>
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/bug.h>
++#include <asm/unaligned.h>
++
++bool blake2s_selftest(void);
++
++void blake2s_update(struct blake2s_state *state, const u8 *in, size_t inlen)
++{
++	const size_t fill = BLAKE2S_BLOCK_SIZE - state->buflen;
++
++	if (unlikely(!inlen))
++		return;
++	if (inlen > fill) {
++		memcpy(state->buf + state->buflen, in, fill);
++		blake2s_compress_generic(state, state->buf, 1,
++					 BLAKE2S_BLOCK_SIZE);
++		state->buflen = 0;
++		in += fill;
++		inlen -= fill;
++	}
++	if (inlen > BLAKE2S_BLOCK_SIZE) {
++		const size_t nblocks = DIV_ROUND_UP(inlen, BLAKE2S_BLOCK_SIZE);
++		/* Hash one less (full) block than strictly possible */
++		blake2s_compress_generic(state, in, nblocks - 1,
++					 BLAKE2S_BLOCK_SIZE);
++		in += BLAKE2S_BLOCK_SIZE * (nblocks - 1);
++		inlen -= BLAKE2S_BLOCK_SIZE * (nblocks - 1);
++	}
++	memcpy(state->buf + state->buflen, in, inlen);
++	state->buflen += inlen;
++}
++EXPORT_SYMBOL(blake2s_update);
++
++void blake2s_final(struct blake2s_state *state, u8 *out)
++{
++	WARN_ON(IS_ENABLED(DEBUG) && !out);
++	blake2s_set_lastblock(state);
++	memset(state->buf + state->buflen, 0,
++	       BLAKE2S_BLOCK_SIZE - state->buflen); /* Padding */
++	blake2s_compress_generic(state, state->buf, 1, state->buflen);
++	cpu_to_le32_array(state->h, ARRAY_SIZE(state->h));
++	memcpy(out, state->h, state->outlen);
++	memzero_explicit(state, sizeof(*state));
++}
++EXPORT_SYMBOL(blake2s_final);
++
++static int __init mod_init(void)
++{
++	if (!IS_ENABLED(CONFIG_CRYPTO_MANAGER_DISABLE_TESTS) &&
++	    WARN_ON(!blake2s_selftest()))
++		return -ENODEV;
++	return 0;
++}
++
++static void __exit mod_exit(void)
++{
++}
++
++module_init(mod_init);
++module_exit(mod_exit);
++MODULE_LICENSE("GPL v2");
++MODULE_DESCRIPTION("BLAKE2s hash function");
++MODULE_AUTHOR("Jason A. Donenfeld <Jason@zx2c4.com>");
+diff --git a/lib/find_bit.c b/lib/find_bit.c
+index 18072ea9c20eb..479d0a9cf69fc 100644
+--- a/lib/find_bit.c
++++ b/lib/find_bit.c
+@@ -133,18 +133,6 @@ EXPORT_SYMBOL(find_last_bit);
+ 
+ #ifdef __BIG_ENDIAN
+ 
+-/* include/linux/byteorder does not support "unsigned long" type */
+-static inline unsigned long ext2_swab(const unsigned long y)
+-{
+-#if BITS_PER_LONG == 64
+-	return (unsigned long) __swab64((u64) y);
+-#elif BITS_PER_LONG == 32
+-	return (unsigned long) __swab32((u32) y);
+-#else
+-#error BITS_PER_LONG not defined
+-#endif
+-}
+-
+ #if !defined(find_next_bit_le) || !defined(find_next_zero_bit_le)
+ static unsigned long _find_next_bit_le(const unsigned long *addr,
+ 		unsigned long nbits, unsigned long start, unsigned long invert)
+@@ -157,7 +145,7 @@ static unsigned long _find_next_bit_le(const unsigned long *addr,
+ 	tmp = addr[start / BITS_PER_LONG] ^ invert;
+ 
+ 	/* Handle 1st word. */
+-	tmp &= ext2_swab(BITMAP_FIRST_WORD_MASK(start));
++	tmp &= swab(BITMAP_FIRST_WORD_MASK(start));
+ 	start = round_down(start, BITS_PER_LONG);
+ 
+ 	while (!tmp) {
+@@ -168,7 +156,7 @@ static unsigned long _find_next_bit_le(const unsigned long *addr,
+ 		tmp = addr[start / BITS_PER_LONG] ^ invert;
+ 	}
+ 
+-	return min(start + __ffs(ext2_swab(tmp)), nbits);
++	return min(start + __ffs(swab(tmp)), nbits);
+ }
+ #endif
+ 
+diff --git a/lib/random32.c b/lib/random32.c
+index 3c5b67b69cbaa..7e630025cbc3b 100644
+--- a/lib/random32.c
++++ b/lib/random32.c
+@@ -37,6 +37,9 @@
+ #include <linux/jiffies.h>
+ #include <linux/random.h>
+ #include <linux/sched.h>
++#include <linux/bitops.h>
++#include <linux/slab.h>
++#include <linux/notifier.h>
+ #include <asm/unaligned.h>
+ 
+ /**
+@@ -543,9 +546,11 @@ static void prandom_reseed(unsigned long dontcare)
+  * To avoid worrying about whether it's safe to delay that interrupt
+  * long enough to seed all CPUs, just schedule an immediate timer event.
+  */
+-static void prandom_timer_start(struct random_ready_callback *unused)
++static int prandom_timer_start(struct notifier_block *nb,
++			       unsigned long action, void *data)
+ {
+ 	mod_timer(&seed_timer, jiffies);
++	return 0;
+ }
+ 
+ /*
+@@ -554,13 +559,13 @@ static void prandom_timer_start(struct random_ready_callback *unused)
+  */
+ static int __init prandom_init_late(void)
+ {
+-	static struct random_ready_callback random_ready = {
+-		.func = prandom_timer_start
++	static struct notifier_block random_ready = {
++		.notifier_call = prandom_timer_start
+ 	};
+-	int ret = add_random_ready_callback(&random_ready);
++	int ret = register_random_ready_notifier(&random_ready);
+ 
+ 	if (ret == -EALREADY) {
+-		prandom_timer_start(&random_ready);
++		prandom_timer_start(&random_ready, 0, NULL);
+ 		ret = 0;
+ 	}
+ 	return ret;
+diff --git a/lib/sha1.c b/lib/sha1.c
+index 5a56dfd7b99de..8aa4ee352ad58 100644
+--- a/lib/sha1.c
++++ b/lib/sha1.c
+@@ -9,6 +9,7 @@
+ #include <linux/export.h>
+ #include <linux/bitops.h>
+ #include <linux/cryptohash.h>
++#include <linux/string.h>
+ #include <asm/unaligned.h>
+ 
+ /*
+@@ -54,7 +55,8 @@
+ #define SHA_ROUND(t, input, fn, constant, A, B, C, D, E) do { \
+ 	__u32 TEMP = input(t); setW(t, TEMP); \
+ 	E += TEMP + rol32(A,5) + (fn) + (constant); \
+-	B = ror32(B, 2); } while (0)
++	B = ror32(B, 2); \
++	TEMP = E; E = D; D = C; C = B; B = A; A = TEMP; } while (0)
+ 
+ #define T_0_15(t, A, B, C, D, E)  SHA_ROUND(t, SHA_SRC, (((C^D)&B)^D) , 0x5a827999, A, B, C, D, E )
+ #define T_16_19(t, A, B, C, D, E) SHA_ROUND(t, SHA_MIX, (((C^D)&B)^D) , 0x5a827999, A, B, C, D, E )
+@@ -81,6 +83,7 @@
+ void sha_transform(__u32 *digest, const char *data, __u32 *array)
+ {
+ 	__u32 A, B, C, D, E;
++	unsigned int i = 0;
+ 
+ 	A = digest[0];
+ 	B = digest[1];
+@@ -89,94 +92,24 @@ void sha_transform(__u32 *digest, const char *data, __u32 *array)
+ 	E = digest[4];
+ 
+ 	/* Round 1 - iterations 0-16 take their input from 'data' */
+-	T_0_15( 0, A, B, C, D, E);
+-	T_0_15( 1, E, A, B, C, D);
+-	T_0_15( 2, D, E, A, B, C);
+-	T_0_15( 3, C, D, E, A, B);
+-	T_0_15( 4, B, C, D, E, A);
+-	T_0_15( 5, A, B, C, D, E);
+-	T_0_15( 6, E, A, B, C, D);
+-	T_0_15( 7, D, E, A, B, C);
+-	T_0_15( 8, C, D, E, A, B);
+-	T_0_15( 9, B, C, D, E, A);
+-	T_0_15(10, A, B, C, D, E);
+-	T_0_15(11, E, A, B, C, D);
+-	T_0_15(12, D, E, A, B, C);
+-	T_0_15(13, C, D, E, A, B);
+-	T_0_15(14, B, C, D, E, A);
+-	T_0_15(15, A, B, C, D, E);
++	for (; i < 16; ++i)
++		T_0_15(i, A, B, C, D, E);
+ 
+ 	/* Round 1 - tail. Input from 512-bit mixing array */
+-	T_16_19(16, E, A, B, C, D);
+-	T_16_19(17, D, E, A, B, C);
+-	T_16_19(18, C, D, E, A, B);
+-	T_16_19(19, B, C, D, E, A);
++	for (; i < 20; ++i)
++		T_16_19(i, A, B, C, D, E);
+ 
+ 	/* Round 2 */
+-	T_20_39(20, A, B, C, D, E);
+-	T_20_39(21, E, A, B, C, D);
+-	T_20_39(22, D, E, A, B, C);
+-	T_20_39(23, C, D, E, A, B);
+-	T_20_39(24, B, C, D, E, A);
+-	T_20_39(25, A, B, C, D, E);
+-	T_20_39(26, E, A, B, C, D);
+-	T_20_39(27, D, E, A, B, C);
+-	T_20_39(28, C, D, E, A, B);
+-	T_20_39(29, B, C, D, E, A);
+-	T_20_39(30, A, B, C, D, E);
+-	T_20_39(31, E, A, B, C, D);
+-	T_20_39(32, D, E, A, B, C);
+-	T_20_39(33, C, D, E, A, B);
+-	T_20_39(34, B, C, D, E, A);
+-	T_20_39(35, A, B, C, D, E);
+-	T_20_39(36, E, A, B, C, D);
+-	T_20_39(37, D, E, A, B, C);
+-	T_20_39(38, C, D, E, A, B);
+-	T_20_39(39, B, C, D, E, A);
++	for (; i < 40; ++i)
++		T_20_39(i, A, B, C, D, E);
+ 
+ 	/* Round 3 */
+-	T_40_59(40, A, B, C, D, E);
+-	T_40_59(41, E, A, B, C, D);
+-	T_40_59(42, D, E, A, B, C);
+-	T_40_59(43, C, D, E, A, B);
+-	T_40_59(44, B, C, D, E, A);
+-	T_40_59(45, A, B, C, D, E);
+-	T_40_59(46, E, A, B, C, D);
+-	T_40_59(47, D, E, A, B, C);
+-	T_40_59(48, C, D, E, A, B);
+-	T_40_59(49, B, C, D, E, A);
+-	T_40_59(50, A, B, C, D, E);
+-	T_40_59(51, E, A, B, C, D);
+-	T_40_59(52, D, E, A, B, C);
+-	T_40_59(53, C, D, E, A, B);
+-	T_40_59(54, B, C, D, E, A);
+-	T_40_59(55, A, B, C, D, E);
+-	T_40_59(56, E, A, B, C, D);
+-	T_40_59(57, D, E, A, B, C);
+-	T_40_59(58, C, D, E, A, B);
+-	T_40_59(59, B, C, D, E, A);
++	for (; i < 60; ++i)
++		T_40_59(i, A, B, C, D, E);
+ 
+ 	/* Round 4 */
+-	T_60_79(60, A, B, C, D, E);
+-	T_60_79(61, E, A, B, C, D);
+-	T_60_79(62, D, E, A, B, C);
+-	T_60_79(63, C, D, E, A, B);
+-	T_60_79(64, B, C, D, E, A);
+-	T_60_79(65, A, B, C, D, E);
+-	T_60_79(66, E, A, B, C, D);
+-	T_60_79(67, D, E, A, B, C);
+-	T_60_79(68, C, D, E, A, B);
+-	T_60_79(69, B, C, D, E, A);
+-	T_60_79(70, A, B, C, D, E);
+-	T_60_79(71, E, A, B, C, D);
+-	T_60_79(72, D, E, A, B, C);
+-	T_60_79(73, C, D, E, A, B);
+-	T_60_79(74, B, C, D, E, A);
+-	T_60_79(75, A, B, C, D, E);
+-	T_60_79(76, E, A, B, C, D);
+-	T_60_79(77, D, E, A, B, C);
+-	T_60_79(78, C, D, E, A, B);
+-	T_60_79(79, B, C, D, E, A);
++	for (; i < 80; ++i)
++		T_60_79(i, A, B, C, D, E);
+ 
+ 	digest[0] += A;
+ 	digest[1] += B;
+diff --git a/lib/siphash.c b/lib/siphash.c
+index e632ee40aac1a..5b34b5c839887 100644
+--- a/lib/siphash.c
++++ b/lib/siphash.c
+@@ -18,19 +18,13 @@
+ #include <asm/word-at-a-time.h>
+ #endif
+ 
+-#define SIPROUND \
+-	do { \
+-	v0 += v1; v1 = rol64(v1, 13); v1 ^= v0; v0 = rol64(v0, 32); \
+-	v2 += v3; v3 = rol64(v3, 16); v3 ^= v2; \
+-	v0 += v3; v3 = rol64(v3, 21); v3 ^= v0; \
+-	v2 += v1; v1 = rol64(v1, 17); v1 ^= v2; v2 = rol64(v2, 32); \
+-	} while (0)
++#define SIPROUND SIPHASH_PERMUTATION(v0, v1, v2, v3)
+ 
+ #define PREAMBLE(len) \
+-	u64 v0 = 0x736f6d6570736575ULL; \
+-	u64 v1 = 0x646f72616e646f6dULL; \
+-	u64 v2 = 0x6c7967656e657261ULL; \
+-	u64 v3 = 0x7465646279746573ULL; \
++	u64 v0 = SIPHASH_CONST_0; \
++	u64 v1 = SIPHASH_CONST_1; \
++	u64 v2 = SIPHASH_CONST_2; \
++	u64 v3 = SIPHASH_CONST_3; \
+ 	u64 b = ((u64)(len)) << 56; \
+ 	v3 ^= key->key[1]; \
+ 	v2 ^= key->key[0]; \
+@@ -389,19 +383,13 @@ u32 hsiphash_4u32(const u32 first, const u32 second, const u32 third,
+ }
+ EXPORT_SYMBOL(hsiphash_4u32);
+ #else
+-#define HSIPROUND \
+-	do { \
+-	v0 += v1; v1 = rol32(v1, 5); v1 ^= v0; v0 = rol32(v0, 16); \
+-	v2 += v3; v3 = rol32(v3, 8); v3 ^= v2; \
+-	v0 += v3; v3 = rol32(v3, 7); v3 ^= v0; \
+-	v2 += v1; v1 = rol32(v1, 13); v1 ^= v2; v2 = rol32(v2, 16); \
+-	} while (0)
++#define HSIPROUND HSIPHASH_PERMUTATION(v0, v1, v2, v3)
+ 
+ #define HPREAMBLE(len) \
+-	u32 v0 = 0; \
+-	u32 v1 = 0; \
+-	u32 v2 = 0x6c796765U; \
+-	u32 v3 = 0x74656462U; \
++	u32 v0 = HSIPHASH_CONST_0; \
++	u32 v1 = HSIPHASH_CONST_1; \
++	u32 v2 = HSIPHASH_CONST_2; \
++	u32 v3 = HSIPHASH_CONST_3; \
+ 	u32 b = ((u32)(len)) << 24; \
+ 	v3 ^= key->key[1]; \
+ 	v2 ^= key->key[0]; \
+diff --git a/lib/swiotlb.c b/lib/swiotlb.c
+index 74b5b88621989..277a2f6fde6b1 100644
+--- a/lib/swiotlb.c
++++ b/lib/swiotlb.c
+@@ -532,9 +532,14 @@ found:
+ 	 */
+ 	for (i = 0; i < nslots; i++)
+ 		io_tlb_orig_addr[index+i] = orig_addr + (i << IO_TLB_SHIFT);
+-	if (dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL)
+-		swiotlb_bounce(orig_addr, tlb_addr, size, DMA_TO_DEVICE);
+-
++	/*
++	 * When dir == DMA_FROM_DEVICE we could omit the copy from the orig
++	 * to the tlb buffer, if we knew for sure the device will
++	 * overwirte the entire current content. But we don't. Thus
++	 * unconditional bounce may prevent leaking swiotlb content (i.e.
++	 * kernel memory) to user-space.
++	 */
++	swiotlb_bounce(orig_addr, tlb_addr, size, DMA_TO_DEVICE);
+ 	return tlb_addr;
+ }
+ EXPORT_SYMBOL_GPL(swiotlb_tbl_map_single);
+diff --git a/mm/util.c b/mm/util.c
+index 07f4672061867..0559a1feec029 100644
+--- a/mm/util.c
++++ b/mm/util.c
+@@ -11,6 +11,7 @@
+ #include <linux/mman.h>
+ #include <linux/hugetlb.h>
+ #include <linux/vmalloc.h>
++#include <linux/random.h>
+ 
+ #include <asm/sections.h>
+ #include <asm/uaccess.h>
+@@ -261,6 +262,38 @@ int vma_is_stack_for_current(struct vm_area_struct *vma)
+ 	return (vma->vm_start <= KSTK_ESP(t) && vma->vm_end >= KSTK_ESP(t));
+ }
+ 
++/**
++ * 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);
++}
++
+ #if defined(CONFIG_MMU) && !defined(HAVE_ARCH_PICK_MMAP_LAYOUT)
+ void arch_pick_mmap_layout(struct mm_struct *mm)
+ {
+diff --git a/net/core/secure_seq.c b/net/core/secure_seq.c
+index fd3ce461fbe62..ed05b8277aa40 100644
+--- a/net/core/secure_seq.c
++++ b/net/core/secure_seq.c
+@@ -62,7 +62,7 @@ __u32 secure_tcpv6_sequence_number(const __be32 *saddr, const __be32 *daddr,
+ }
+ EXPORT_SYMBOL(secure_tcpv6_sequence_number);
+ 
+-u32 secure_ipv6_port_ephemeral(const __be32 *saddr, const __be32 *daddr,
++u64 secure_ipv6_port_ephemeral(const __be32 *saddr, const __be32 *daddr,
+ 			       __be16 dport)
+ {
+ 	u32 secret[MD5_MESSAGE_BYTES / 4];
+@@ -102,7 +102,7 @@ __u32 secure_tcp_sequence_number(__be32 saddr, __be32 daddr,
+ 	return seq_scale(hash[0]);
+ }
+ 
+-u32 secure_ipv4_port_ephemeral(__be32 saddr, __be32 daddr, __be16 dport)
++u64 secure_ipv4_port_ephemeral(__be32 saddr, __be32 daddr, __be16 dport)
+ {
+ 	u32 hash[MD5_DIGEST_WORDS];
+ 
+diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c
+index 8876338707636..db47e1c407d9a 100644
+--- a/net/ipv4/inet_hashtables.c
++++ b/net/ipv4/inet_hashtables.c
+@@ -382,7 +382,7 @@ not_unique:
+ 	return -EADDRNOTAVAIL;
+ }
+ 
+-static u32 inet_sk_port_offset(const struct sock *sk)
++static u64 inet_sk_port_offset(const struct sock *sk)
+ {
+ 	const struct inet_sock *inet = inet_sk(sk);
+ 
+@@ -537,8 +537,21 @@ void inet_unhash(struct sock *sk)
+ }
+ EXPORT_SYMBOL_GPL(inet_unhash);
+ 
++/* RFC 6056 3.3.4.  Algorithm 4: Double-Hash Port Selection Algorithm
++ * Note that we use 32bit integers (vs RFC 'short integers')
++ * because 2^16 is not a multiple of num_ephemeral and this
++ * property might be used by clever attacker.
++ * RFC claims using TABLE_LENGTH=10 buckets gives an improvement, though
++ * attacks were since demonstrated, thus we use 65536 instead to really
++ * give more isolation and privacy, at the expense of 256kB of kernel
++ * memory.
++ */
++#define INET_TABLE_PERTURB_SHIFT 16
++#define INET_TABLE_PERTURB_SIZE (1 << INET_TABLE_PERTURB_SHIFT)
++static u32 *table_perturb;
++
+ int __inet_hash_connect(struct inet_timewait_death_row *death_row,
+-		struct sock *sk, u32 port_offset,
++		struct sock *sk, u64 port_offset,
+ 		int (*check_established)(struct inet_timewait_death_row *,
+ 			struct sock *, __u16, struct inet_timewait_sock **))
+ {
+@@ -550,7 +563,7 @@ int __inet_hash_connect(struct inet_timewait_death_row *death_row,
+ 	struct inet_bind_bucket *tb;
+ 	u32 remaining, offset;
+ 	int ret, i, low, high;
+-	static u32 hint;
++	u32 index;
+ 
+ 	if (port) {
+ 		head = &hinfo->bhash[inet_bhashfn(net, port,
+@@ -575,7 +588,13 @@ int __inet_hash_connect(struct inet_timewait_death_row *death_row,
+ 	if (likely(remaining > 1))
+ 		remaining &= ~1U;
+ 
+-	offset = (hint + port_offset) % remaining;
++	net_get_random_once(table_perturb,
++			    INET_TABLE_PERTURB_SIZE * sizeof(*table_perturb));
++	index = port_offset & (INET_TABLE_PERTURB_SIZE - 1);
++
++	offset = READ_ONCE(table_perturb[index]) + (port_offset >> 32);
++	offset %= remaining;
++
+ 	/* In first pass we try ports of @low parity.
+ 	 * inet_csk_get_port() does the opposite choice.
+ 	 */
+@@ -628,7 +647,13 @@ next_port:
+ 	return -EADDRNOTAVAIL;
+ 
+ ok:
+-	hint += i + 2;
++	/* Here we want to add a little bit of randomness to the next source
++	 * port that will be chosen. We use a max() with a random here so that
++	 * on low contention the randomness is maximal and on high contention
++	 * it may be inexistent.
++	 */
++	i = max_t(int, i, (prandom_u32() & 7) * 2);
++	WRITE_ONCE(table_perturb[index], READ_ONCE(table_perturb[index]) + i + 2);
+ 
+ 	/* Head lock still held and bh's disabled */
+ 	inet_bind_hash(sk, tb, port);
+@@ -651,7 +676,7 @@ ok:
+ int inet_hash_connect(struct inet_timewait_death_row *death_row,
+ 		      struct sock *sk)
+ {
+-	u32 port_offset = 0;
++	u64 port_offset = 0;
+ 
+ 	if (!inet_sk(sk)->inet_num)
+ 		port_offset = inet_sk_port_offset(sk);
+@@ -669,6 +694,15 @@ void inet_hashinfo_init(struct inet_hashinfo *h)
+ 		INIT_HLIST_NULLS_HEAD(&h->listening_hash[i].nulls_head,
+ 				      i + LISTENING_NULLS_BASE);
+ 	}
++
++	if (h != &tcp_hashinfo)
++		return;
++
++	/* this one is used for source ports of outgoing connections */
++	table_perturb = kmalloc_array(INET_TABLE_PERTURB_SIZE,
++				      sizeof(*table_perturb), GFP_KERNEL);
++	if (!table_perturb)
++		panic("TCP: failed to alloc table_perturb");
+ }
+ EXPORT_SYMBOL_GPL(inet_hashinfo_init);
+ 
+diff --git a/net/ipv6/inet6_hashtables.c b/net/ipv6/inet6_hashtables.c
+index d47cab6d7c6de..8223ac61a9fd3 100644
+--- a/net/ipv6/inet6_hashtables.c
++++ b/net/ipv6/inet6_hashtables.c
+@@ -242,7 +242,7 @@ not_unique:
+ 	return -EADDRNOTAVAIL;
+ }
+ 
+-static u32 inet6_sk_port_offset(const struct sock *sk)
++static u64 inet6_sk_port_offset(const struct sock *sk)
+ {
+ 	const struct inet_sock *inet = inet_sk(sk);
+ 
+@@ -254,7 +254,7 @@ static u32 inet6_sk_port_offset(const struct sock *sk)
+ int inet6_hash_connect(struct inet_timewait_death_row *death_row,
+ 		       struct sock *sk)
+ {
+-	u32 port_offset = 0;
++	u64 port_offset = 0;
+ 
+ 	if (!inet_sk(sk)->inet_num)
+ 		port_offset = inet6_sk_port_offset(sk);
+diff --git a/net/l2tp/l2tp_ip6.c b/net/l2tp/l2tp_ip6.c
+index 76ef758db1124..e412020029dfb 100644
+--- a/net/l2tp/l2tp_ip6.c
++++ b/net/l2tp/l2tp_ip6.c
+@@ -518,14 +518,15 @@ static int l2tp_ip6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
+ 	struct ipcm6_cookie ipc6;
+ 	int addr_len = msg->msg_namelen;
+ 	int transhdrlen = 4; /* zero session-id */
+-	int ulen = len + transhdrlen;
++	int ulen;
+ 	int err;
+ 
+ 	/* Rough check on arithmetic overflow,
+ 	   better check is made in ip6_append_data().
+ 	 */
+-	if (len > INT_MAX)
++	if (len > INT_MAX - transhdrlen)
+ 		return -EMSGSIZE;
++	ulen = len + transhdrlen;
+ 
+ 	/* Mirror BSD error message compatibility */
+ 	if (msg->msg_flags & MSG_OOB)
+diff --git a/net/l2tp/l2tp_ppp.c b/net/l2tp/l2tp_ppp.c
+index 979fa868a4f1d..4673f6f489425 100644
+--- a/net/l2tp/l2tp_ppp.c
++++ b/net/l2tp/l2tp_ppp.c
+@@ -435,20 +435,28 @@ abort:
+  * Session (and tunnel control) socket create/destroy.
+  *****************************************************************************/
+ 
++static void pppol2tp_put_sk(struct rcu_head *head)
++{
++	struct pppol2tp_session *ps;
++
++	ps = container_of(head, typeof(*ps), rcu);
++	sock_put(ps->__sk);
++}
++
+ /* Called by l2tp_core when a session socket is being closed.
+  */
+ static void pppol2tp_session_close(struct l2tp_session *session)
+ {
+-	struct sock *sk;
+-
+-	BUG_ON(session->magic != L2TP_SESSION_MAGIC);
++	struct pppol2tp_session *ps;
+ 
+-	sk = pppol2tp_session_get_sock(session);
+-	if (sk) {
+-		if (sk->sk_socket)
+-			inet_shutdown(sk->sk_socket, SEND_SHUTDOWN);
+-		sock_put(sk);
+-	}
++	ps = l2tp_session_priv(session);
++	mutex_lock(&ps->sk_lock);
++	ps->__sk = rcu_dereference_protected(ps->sk,
++					     lockdep_is_held(&ps->sk_lock));
++	RCU_INIT_POINTER(ps->sk, NULL);
++	if (ps->__sk)
++		call_rcu(&ps->rcu, pppol2tp_put_sk);
++	mutex_unlock(&ps->sk_lock);
+ }
+ 
+ /* Really kill the session socket. (Called from sock_put() if
+@@ -468,14 +476,6 @@ static void pppol2tp_session_destruct(struct sock *sk)
+ 	}
+ }
+ 
+-static void pppol2tp_put_sk(struct rcu_head *head)
+-{
+-	struct pppol2tp_session *ps;
+-
+-	ps = container_of(head, typeof(*ps), rcu);
+-	sock_put(ps->__sk);
+-}
+-
+ /* Called when the PPPoX socket (session) is closed.
+  */
+ static int pppol2tp_release(struct socket *sock)
+@@ -499,26 +499,17 @@ static int pppol2tp_release(struct socket *sock)
+ 	sock_orphan(sk);
+ 	sock->sk = NULL;
+ 
++	/* If the socket is associated with a session,
++	 * l2tp_session_delete will call pppol2tp_session_close which
++	 * will drop the session's ref on the socket.
++	 */
+ 	session = pppol2tp_sock_to_session(sk);
+-
+-	if (session != NULL) {
+-		struct pppol2tp_session *ps;
+-
++	if (session) {
+ 		l2tp_session_delete(session);
+-
+-		ps = l2tp_session_priv(session);
+-		mutex_lock(&ps->sk_lock);
+-		ps->__sk = rcu_dereference_protected(ps->sk,
+-						     lockdep_is_held(&ps->sk_lock));
+-		RCU_INIT_POINTER(ps->sk, NULL);
+-		mutex_unlock(&ps->sk_lock);
+-		call_rcu(&ps->rcu, pppol2tp_put_sk);
+-
+-		/* Rely on the sock_put() call at the end of the function for
+-		 * dropping the reference held by pppol2tp_sock_to_session().
+-		 * The last reference will be dropped by pppol2tp_put_sk().
+-		 */
++		/* drop the ref obtained by pppol2tp_sock_to_session */
++		sock_put(sk);
+ 	}
++
+ 	release_sock(sk);
+ 
+ 	/* This will delete the session context via
+@@ -827,6 +818,7 @@ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr,
+ 
+ out_no_ppp:
+ 	/* This is how we get the session context from the socket. */
++	sock_hold(sk);
+ 	sk->sk_user_data = session;
+ 	rcu_assign_pointer(ps->sk, sk);
+ 	mutex_unlock(&ps->sk_lock);
+diff --git a/net/sunrpc/xprtrdma/rpc_rdma.c b/net/sunrpc/xprtrdma/rpc_rdma.c
+index 0287734f126f6..aec0113a88b08 100644
+--- a/net/sunrpc/xprtrdma/rpc_rdma.c
++++ b/net/sunrpc/xprtrdma/rpc_rdma.c
+@@ -75,7 +75,7 @@ static unsigned int rpcrdma_max_call_header_size(unsigned int maxsegs)
+ 
+ 	/* Maximum Read list size */
+ 	maxsegs += 2;	/* segment for head and tail buffers */
+-	size = maxsegs * sizeof(struct rpcrdma_read_chunk);
++	size += maxsegs * sizeof(struct rpcrdma_read_chunk);
+ 
+ 	/* Minimal Read chunk size */
+ 	size += sizeof(__be32);	/* segment count */
+@@ -101,7 +101,7 @@ static unsigned int rpcrdma_max_reply_header_size(unsigned int maxsegs)
+ 
+ 	/* Maximum Write list size */
+ 	maxsegs += 2;	/* segment for head and tail buffers */
+-	size = sizeof(__be32);		/* segment count */
++	size += sizeof(__be32);		/* segment count */
+ 	size += maxsegs * sizeof(struct rpcrdma_segment);
+ 	size += sizeof(__be32);	/* list discriminator */
+ 
+diff --git a/sound/soc/codecs/cs42l52.c b/sound/soc/codecs/cs42l52.c
+index 0d9c4a57301bb..47f2439fd7b08 100644
+--- a/sound/soc/codecs/cs42l52.c
++++ b/sound/soc/codecs/cs42l52.c
+@@ -141,7 +141,9 @@ static DECLARE_TLV_DB_SCALE(mic_tlv, 1600, 100, 0);
+ 
+ static DECLARE_TLV_DB_SCALE(pga_tlv, -600, 50, 0);
+ 
+-static DECLARE_TLV_DB_SCALE(mix_tlv, -50, 50, 0);
++static DECLARE_TLV_DB_SCALE(pass_tlv, -6000, 50, 0);
++
++static DECLARE_TLV_DB_SCALE(mix_tlv, -5150, 50, 0);
+ 
+ static DECLARE_TLV_DB_SCALE(beep_tlv, -56, 200, 0);
+ 
+@@ -355,7 +357,7 @@ static const struct snd_kcontrol_new cs42l52_snd_controls[] = {
+ 			      CS42L52_SPKB_VOL, 0, 0x40, 0xC0, hl_tlv),
+ 
+ 	SOC_DOUBLE_R_SX_TLV("Bypass Volume", CS42L52_PASSTHRUA_VOL,
+-			      CS42L52_PASSTHRUB_VOL, 0, 0x88, 0x90, pga_tlv),
++			      CS42L52_PASSTHRUB_VOL, 0, 0x88, 0x90, pass_tlv),
+ 
+ 	SOC_DOUBLE("Bypass Mute", CS42L52_MISC_CTL, 4, 5, 1, 0),
+ 
+@@ -368,7 +370,7 @@ static const struct snd_kcontrol_new cs42l52_snd_controls[] = {
+ 			      CS42L52_ADCB_VOL, 0, 0xA0, 0x78, ipd_tlv),
+ 	SOC_DOUBLE_R_SX_TLV("ADC Mixer Volume",
+ 			     CS42L52_ADCA_MIXER_VOL, CS42L52_ADCB_MIXER_VOL,
+-				0, 0x19, 0x7F, ipd_tlv),
++				0, 0x19, 0x7F, mix_tlv),
+ 
+ 	SOC_DOUBLE("ADC Switch", CS42L52_ADC_MISC_CTL, 0, 1, 1, 0),
+ 
+diff --git a/sound/soc/codecs/cs42l56.c b/sound/soc/codecs/cs42l56.c
+index a2535a7eb4bbd..f9f8a9112ff8d 100644
+--- a/sound/soc/codecs/cs42l56.c
++++ b/sound/soc/codecs/cs42l56.c
+@@ -405,9 +405,9 @@ static const struct snd_kcontrol_new cs42l56_snd_controls[] = {
+ 	SOC_DOUBLE("ADC Boost Switch", CS42L56_GAIN_BIAS_CTL, 3, 2, 1, 1),
+ 
+ 	SOC_DOUBLE_R_SX_TLV("Headphone Volume", CS42L56_HPA_VOLUME,
+-			      CS42L56_HPB_VOLUME, 0, 0x84, 0x48, hl_tlv),
++			      CS42L56_HPB_VOLUME, 0, 0x44, 0x48, hl_tlv),
+ 	SOC_DOUBLE_R_SX_TLV("LineOut Volume", CS42L56_LOA_VOLUME,
+-			      CS42L56_LOB_VOLUME, 0, 0x84, 0x48, hl_tlv),
++			      CS42L56_LOB_VOLUME, 0, 0x44, 0x48, hl_tlv),
+ 
+ 	SOC_SINGLE_TLV("Bass Shelving Volume", CS42L56_TONE_CTL,
+ 			0, 0x00, 1, tone_tlv),
+diff --git a/sound/soc/codecs/cs53l30.c b/sound/soc/codecs/cs53l30.c
+index cb47fb595ff41..5a16020423fe0 100644
+--- a/sound/soc/codecs/cs53l30.c
++++ b/sound/soc/codecs/cs53l30.c
+@@ -351,22 +351,22 @@ static const struct snd_kcontrol_new cs53l30_snd_controls[] = {
+ 	SOC_ENUM("ADC2 NG Delay", adc2_ng_delay_enum),
+ 
+ 	SOC_SINGLE_SX_TLV("ADC1A PGA Volume",
+-		    CS53L30_ADC1A_AFE_CTL, 0, 0x34, 0x18, pga_tlv),
++		    CS53L30_ADC1A_AFE_CTL, 0, 0x34, 0x24, pga_tlv),
+ 	SOC_SINGLE_SX_TLV("ADC1B PGA Volume",
+-		    CS53L30_ADC1B_AFE_CTL, 0, 0x34, 0x18, pga_tlv),
++		    CS53L30_ADC1B_AFE_CTL, 0, 0x34, 0x24, pga_tlv),
+ 	SOC_SINGLE_SX_TLV("ADC2A PGA Volume",
+-		    CS53L30_ADC2A_AFE_CTL, 0, 0x34, 0x18, pga_tlv),
++		    CS53L30_ADC2A_AFE_CTL, 0, 0x34, 0x24, pga_tlv),
+ 	SOC_SINGLE_SX_TLV("ADC2B PGA Volume",
+-		    CS53L30_ADC2B_AFE_CTL, 0, 0x34, 0x18, pga_tlv),
++		    CS53L30_ADC2B_AFE_CTL, 0, 0x34, 0x24, pga_tlv),
+ 
+ 	SOC_SINGLE_SX_TLV("ADC1A Digital Volume",
+-		    CS53L30_ADC1A_DIG_VOL, 0, 0xA0, 0x0C, dig_tlv),
++		    CS53L30_ADC1A_DIG_VOL, 0, 0xA0, 0x6C, dig_tlv),
+ 	SOC_SINGLE_SX_TLV("ADC1B Digital Volume",
+-		    CS53L30_ADC1B_DIG_VOL, 0, 0xA0, 0x0C, dig_tlv),
++		    CS53L30_ADC1B_DIG_VOL, 0, 0xA0, 0x6C, dig_tlv),
+ 	SOC_SINGLE_SX_TLV("ADC2A Digital Volume",
+-		    CS53L30_ADC2A_DIG_VOL, 0, 0xA0, 0x0C, dig_tlv),
++		    CS53L30_ADC2A_DIG_VOL, 0, 0xA0, 0x6C, dig_tlv),
+ 	SOC_SINGLE_SX_TLV("ADC2B Digital Volume",
+-		    CS53L30_ADC2B_DIG_VOL, 0, 0xA0, 0x0C, dig_tlv),
++		    CS53L30_ADC2B_DIG_VOL, 0, 0xA0, 0x6C, dig_tlv),
+ };
+ 
+ static const struct snd_soc_dapm_widget cs53l30_dapm_widgets[] = {
+diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c
+index 0e8008d381619..d46881f96c164 100644
+--- a/sound/soc/codecs/wm8962.c
++++ b/sound/soc/codecs/wm8962.c
+@@ -3861,6 +3861,7 @@ static int wm8962_runtime_suspend(struct device *dev)
+ #endif
+ 
+ static const struct dev_pm_ops wm8962_pm = {
++	SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume)
+ 	SET_RUNTIME_PM_OPS(wm8962_runtime_suspend, wm8962_runtime_resume, NULL)
+ };
+ 


             reply	other threads:[~2022-06-25 10:24 UTC|newest]

Thread overview: 393+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-06-25 10:24 Mike Pagano [this message]
  -- strict thread matches above, loose matches on Subject: below --
2023-01-07 11:37 [gentoo-commits] proj/linux-patches:4.9 commit in: / Mike Pagano
2022-12-14 12:24 Mike Pagano
2022-12-08 13:09 Alice Ferrazzi
2022-11-25 17:02 Mike Pagano
2022-11-10 15:14 Mike Pagano
2022-11-03 15:09 Mike Pagano
2022-10-26 11:43 Mike Pagano
2022-09-28  9:19 Mike Pagano
2022-09-20 12:04 Mike Pagano
2022-09-15 11:10 Mike Pagano
2022-09-05 12:08 Mike Pagano
2022-08-25 10:37 Mike Pagano
2022-07-29 15:25 Mike Pagano
2022-07-21 20:14 Mike Pagano
2022-07-12 16:03 Mike Pagano
2022-07-07 16:20 Mike Pagano
2022-07-02 16:04 Mike Pagano
2022-06-16 11:42 Mike Pagano
2022-06-14 15:49 Mike Pagano
2022-06-06 11:07 Mike Pagano
2022-05-27 12:41 Mike Pagano
2022-05-25 11:57 Mike Pagano
2022-05-18  9:52 Mike Pagano
2022-05-15 22:14 Mike Pagano
2022-05-12 11:32 Mike Pagano
2022-04-27 11:38 Mike Pagano
2022-04-20 12:12 Mike Pagano
2022-03-28 11:01 Mike Pagano
2022-03-23 11:59 Mike Pagano
2022-03-16 13:22 Mike Pagano
2022-03-11 10:57 Mike Pagano
2022-03-08 18:28 Mike Pagano
2022-03-02 13:09 Mike Pagano
2022-02-26 23:38 Mike Pagano
2022-02-23 12:40 Mike Pagano
2022-02-16 12:49 Mike Pagano
2022-02-11 12:38 Mike Pagano
2022-02-08 18:03 Mike Pagano
2022-01-29 17:46 Mike Pagano
2022-01-27 11:41 Mike Pagano
2022-01-11 12:59 Mike Pagano
2022-01-05 12:57 Mike Pagano
2021-12-29 13:13 Mike Pagano
2021-12-22 14:08 Mike Pagano
2021-12-14 10:37 Mike Pagano
2021-12-08 12:57 Mike Pagano
2021-11-26 12:01 Mike Pagano
2021-11-12 13:38 Mike Pagano
2021-11-02 17:06 Mike Pagano
2021-10-27 12:00 Mike Pagano
2021-10-17 13:14 Mike Pagano
2021-10-09 21:35 Mike Pagano
2021-10-06 11:32 Mike Pagano
2021-09-26 14:15 Mike Pagano
2021-09-22 11:42 Mike Pagano
2021-09-20 22:06 Mike Pagano
2021-09-03 11:24 Mike Pagano
2021-08-26 14:03 Mike Pagano
2021-08-25 23:14 Mike Pagano
2021-08-25 23:13 Mike Pagano
2021-08-15 20:10 Mike Pagano
2021-08-08 13:41 Mike Pagano
2021-08-04 11:55 Mike Pagano
2021-08-03 12:49 Mike Pagano
2021-07-28 12:39 Mike Pagano
2021-07-20 15:29 Alice Ferrazzi
2021-07-11 14:47 Mike Pagano
2021-06-30 14:28 Mike Pagano
2021-06-17 14:23 Alice Ferrazzi
2021-06-17 11:08 Alice Ferrazzi
2021-06-10 11:10 Mike Pagano
2021-06-03 10:41 Alice Ferrazzi
2021-05-26 12:03 Mike Pagano
2021-05-22 10:01 Mike Pagano
2021-04-28 11:03 Alice Ferrazzi
2021-04-16 11:19 Alice Ferrazzi
2021-04-10 13:22 Mike Pagano
2021-04-07 12:14 Mike Pagano
2021-03-30 14:14 Mike Pagano
2021-03-24 12:07 Mike Pagano
2021-03-17 15:58 Mike Pagano
2021-03-11 14:04 Mike Pagano
2021-03-07 15:13 Mike Pagano
2021-03-03 17:24 Alice Ferrazzi
2021-02-23 13:38 Alice Ferrazzi
2021-02-10 10:15 Alice Ferrazzi
2021-02-05 14:53 Alice Ferrazzi
2021-02-03 23:25 Mike Pagano
2021-01-30 13:18 Alice Ferrazzi
2021-01-23 16:34 Mike Pagano
2021-01-17 16:22 Mike Pagano
2021-01-12 20:08 Mike Pagano
2021-01-09 12:54 Mike Pagano
2020-12-29 14:18 Mike Pagano
2020-12-11 12:54 Mike Pagano
2020-12-02 12:48 Mike Pagano
2020-11-24 13:39 Mike Pagano
2020-11-22 19:12 Mike Pagano
2020-11-18 19:23 Mike Pagano
2020-11-11 15:32 Mike Pagano
2020-11-10 13:54 Mike Pagano
2020-10-29 11:17 Mike Pagano
2020-10-17 10:14 Mike Pagano
2020-10-14 20:34 Mike Pagano
2020-10-01 19:03 Mike Pagano
2020-10-01 18:59 Mike Pagano
2020-09-24 16:02 Mike Pagano
2020-09-23 11:59 Mike Pagano
2020-09-23 11:57 Mike Pagano
2020-09-12 17:31 Mike Pagano
2020-09-03 11:34 Mike Pagano
2020-08-26 11:13 Mike Pagano
2020-08-21 11:23 Alice Ferrazzi
2020-08-21 11:02 Alice Ferrazzi
2020-07-31 16:13 Mike Pagano
2020-07-22 12:30 Mike Pagano
2020-07-09 12:07 Mike Pagano
2020-07-01 12:10 Mike Pagano
2020-06-22 14:44 Mike Pagano
2020-06-11 11:28 Mike Pagano
2020-06-03 11:37 Mike Pagano
2020-05-27 15:26 Mike Pagano
2020-05-20 11:24 Mike Pagano
2020-05-13 12:50 Mike Pagano
2020-05-11 22:52 Mike Pagano
2020-05-05 17:39 Mike Pagano
2020-05-02 19:22 Mike Pagano
2020-04-24 12:01 Mike Pagano
2020-04-15 17:55 Mike Pagano
2020-04-13 11:15 Mike Pagano
2020-04-02 18:55 Mike Pagano
2020-03-20 11:54 Mike Pagano
2020-03-11 10:15 Mike Pagano
2020-02-28 15:29 Mike Pagano
2020-02-14 23:36 Mike Pagano
2020-02-05 14:48 Mike Pagano
2020-01-29 12:36 Mike Pagano
2020-01-23 11:02 Mike Pagano
2020-01-14 22:26 Mike Pagano
2020-01-12 14:52 Mike Pagano
2020-01-04 16:48 Mike Pagano
2019-12-21 14:54 Mike Pagano
2019-12-05 15:17 Alice Ferrazzi
2019-11-29 21:39 Thomas Deutschmann
2019-11-28 23:51 Mike Pagano
2019-11-25 12:08 Mike Pagano
2019-11-16 10:54 Mike Pagano
2019-11-12 20:58 Mike Pagano
2019-11-10 16:15 Mike Pagano
2019-11-06 14:24 Mike Pagano
2019-10-29 11:16 Mike Pagano
2019-10-17 22:21 Mike Pagano
2019-10-07 17:37 Mike Pagano
2019-10-05 11:39 Mike Pagano
2019-09-21 15:57 Mike Pagano
2019-09-19 23:16 Mike Pagano
2019-09-16 12:22 Mike Pagano
2019-09-10 11:10 Mike Pagano
2019-09-06 17:18 Mike Pagano
2019-08-25 17:34 Mike Pagano
2019-08-11 10:59 Mike Pagano
2019-08-06 19:16 Mike Pagano
2019-08-04 16:05 Mike Pagano
2019-07-21 14:38 Mike Pagano
2019-07-10 11:03 Mike Pagano
2019-06-27 11:10 Mike Pagano
2019-06-22 19:04 Mike Pagano
2019-06-17 19:19 Mike Pagano
2019-06-11 17:40 Mike Pagano
2019-06-11 12:39 Mike Pagano
2019-05-31 16:42 Mike Pagano
2019-05-26 17:12 Mike Pagano
2019-05-21 17:14 Mike Pagano
2019-05-16 22:59 Mike Pagano
2019-05-14 20:08 Mike Pagano
2019-05-10 19:38 Mike Pagano
2019-05-08 10:03 Mike Pagano
2019-05-04 18:26 Mike Pagano
2019-05-02 10:16 Mike Pagano
2019-04-27 17:29 Mike Pagano
2019-04-20 11:06 Mike Pagano
2019-04-19 19:54 Mike Pagano
2019-04-05 21:42 Mike Pagano
2019-04-03 10:48 Mike Pagano
2019-03-27 10:20 Mike Pagano
2019-03-23 14:57 Mike Pagano
2019-03-23 14:18 Mike Pagano
2019-03-19 16:56 Mike Pagano
2019-03-13 22:05 Mike Pagano
2019-03-06 19:12 Mike Pagano
2019-03-05 17:59 Mike Pagano
2019-02-27 11:20 Mike Pagano
2019-02-23 14:42 Mike Pagano
2019-02-20 11:16 Mike Pagano
2019-02-15 12:46 Mike Pagano
2019-02-12 20:51 Mike Pagano
2019-02-06 20:14 Mike Pagano
2019-01-31 11:22 Mike Pagano
2019-01-26 15:03 Mike Pagano
2019-01-23 11:29 Mike Pagano
2019-01-16 23:29 Mike Pagano
2019-01-13 19:26 Mike Pagano
2019-01-09 18:09 Mike Pagano
2019-01-09 17:52 Mike Pagano
2018-12-29 22:53 Mike Pagano
2018-12-29 18:51 Mike Pagano
2018-12-21 14:44 Mike Pagano
2018-12-17 11:39 Mike Pagano
2018-12-13 11:36 Mike Pagano
2018-12-08 13:25 Mike Pagano
2018-12-05 19:44 Mike Pagano
2018-12-01 18:00 Mike Pagano
2018-12-01 15:04 Mike Pagano
2018-11-27 16:22 Mike Pagano
2018-11-23 12:48 Mike Pagano
2018-11-23 12:45 Mike Pagano
2018-11-21 12:20 Mike Pagano
2018-11-14 14:37 Mike Pagano
2018-11-14 14:37 Mike Pagano
2018-11-14 14:37 Mike Pagano
2018-11-14 14:37 Mike Pagano
2018-11-14 14:37 Mike Pagano
2018-11-14 14:37 Mike Pagano
2018-11-14 14:37 Mike Pagano
2018-11-14 14:37 Mike Pagano
2018-11-14 14:37 Mike Pagano
2018-11-14 14:37 Mike Pagano
2018-11-14 14:37 Mike Pagano
2018-11-14 14:37 Mike Pagano
2018-11-14 14:37 Mike Pagano
2018-11-14 14:37 Mike Pagano
2018-11-14 14:37 Mike Pagano
2018-11-14 14:37 Mike Pagano
2018-11-14 14:37 Mike Pagano
2018-11-14 14:37 Mike Pagano
2018-11-14 14:37 Mike Pagano
2018-11-14 14:37 Mike Pagano
2018-11-14 14:37 Mike Pagano
2018-11-14 14:37 Mike Pagano
2018-11-14 14:37 Mike Pagano
2018-11-14 14:37 Mike Pagano
2018-11-14 14:37 Mike Pagano
2018-11-13 21:20 Mike Pagano
2018-11-11  1:44 Mike Pagano
2018-11-11  1:31 Mike Pagano
2018-11-10 21:30 Mike Pagano
2018-10-20 12:43 Mike Pagano
2018-10-18 10:25 Mike Pagano
2018-10-13 16:34 Mike Pagano
2018-10-10 11:19 Mike Pagano
2018-10-04 10:40 Mike Pagano
2018-09-29 13:33 Mike Pagano
2018-09-26 10:42 Mike Pagano
2018-09-19 22:38 Mike Pagano
2018-09-15 10:10 Mike Pagano
2018-09-09 23:27 Mike Pagano
2018-09-05 15:27 Mike Pagano
2018-08-24 11:43 Mike Pagano
2018-08-22 10:06 Alice Ferrazzi
2018-08-18 18:07 Mike Pagano
2018-08-17 19:32 Mike Pagano
2018-08-17 19:25 Mike Pagano
2018-08-16 11:51 Mike Pagano
2018-08-15 16:46 Mike Pagano
2018-08-09 10:52 Mike Pagano
2018-08-07 18:12 Mike Pagano
2018-08-03 12:25 Mike Pagano
2018-07-28 10:38 Mike Pagano
2018-07-25 10:26 Mike Pagano
2018-07-22 15:14 Mike Pagano
2018-07-17 10:25 Mike Pagano
2018-07-12 15:42 Alice Ferrazzi
2018-07-03 13:16 Mike Pagano
2018-06-26 16:34 Alice Ferrazzi
2018-06-16 15:42 Mike Pagano
2018-06-13 15:03 Mike Pagano
2018-06-06 18:04 Mike Pagano
2018-06-05 11:21 Mike Pagano
2018-05-30 22:34 Mike Pagano
2018-05-30 11:39 Mike Pagano
2018-05-25 14:54 Mike Pagano
2018-05-22 17:28 Mike Pagano
2018-05-20 22:20 Mike Pagano
2018-05-16 10:23 Mike Pagano
2018-05-09 10:54 Mike Pagano
2018-05-02 16:13 Mike Pagano
2018-04-30 10:29 Mike Pagano
2018-04-24 11:30 Mike Pagano
2018-04-20 11:12 Mike Pagano
2018-04-13 22:21 Mike Pagano
2018-04-08 14:26 Mike Pagano
2018-03-31 22:17 Mike Pagano
2018-03-28 17:42 Mike Pagano
2018-03-25 14:31 Mike Pagano
2018-03-25 13:39 Mike Pagano
2018-03-22 12:58 Mike Pagano
2018-03-18 22:15 Mike Pagano
2018-03-11 18:26 Mike Pagano
2018-03-05  2:38 Alice Ferrazzi
2018-02-28 18:46 Alice Ferrazzi
2018-02-28 15:02 Alice Ferrazzi
2018-02-25 15:47 Mike Pagano
2018-02-22 23:22 Mike Pagano
2018-02-17 15:02 Alice Ferrazzi
2018-02-13 13:25 Alice Ferrazzi
2018-02-03 21:22 Mike Pagano
2018-01-31 13:31 Alice Ferrazzi
2018-01-23 21:17 Mike Pagano
2018-01-17 10:18 Alice Ferrazzi
2018-01-17 10:18 Alice Ferrazzi
2018-01-17  9:16 Alice Ferrazzi
2018-01-15 14:57 Alice Ferrazzi
2018-01-10 12:21 Alice Ferrazzi
2018-01-10 11:47 Mike Pagano
2018-01-05 15:54 Alice Ferrazzi
2018-01-05 15:04 Alice Ferrazzi
2018-01-02 20:13 Mike Pagano
2017-12-29 17:20 Alice Ferrazzi
2017-12-25 14:36 Alice Ferrazzi
2017-12-20 12:44 Mike Pagano
2017-12-16 17:42 Alice Ferrazzi
2017-12-14  8:58 Alice Ferrazzi
2017-12-09 23:29 Mike Pagano
2017-12-05 11:38 Mike Pagano
2017-11-30 12:19 Alice Ferrazzi
2017-11-24  9:44 Alice Ferrazzi
2017-11-21  9:18 Alice Ferrazzi
2017-11-18 18:24 Mike Pagano
2017-11-15 15:44 Mike Pagano
2017-11-08 13:49 Mike Pagano
2017-11-02 10:03 Mike Pagano
2017-10-27 10:29 Mike Pagano
2017-10-21 20:15 Mike Pagano
2017-10-18 13:46 Mike Pagano
2017-10-12 22:26 Mike Pagano
2017-10-12 12:37 Mike Pagano
2017-10-08 14:23 Mike Pagano
2017-10-08 14:21 Mike Pagano
2017-10-08 14:13 Mike Pagano
2017-10-05 11:38 Mike Pagano
2017-09-27 16:38 Mike Pagano
2017-09-20 10:11 Mike Pagano
2017-09-14 11:39 Mike Pagano
2017-09-13 22:28 Mike Pagano
2017-09-13 16:25 Mike Pagano
2017-09-10 14:38 Mike Pagano
2017-09-07 22:43 Mike Pagano
2017-09-02 17:45 Mike Pagano
2017-08-30 10:06 Mike Pagano
2017-08-25 10:59 Mike Pagano
2017-08-16 22:29 Mike Pagano
2017-08-13 16:51 Mike Pagano
2017-08-11 17:41 Mike Pagano
2017-08-07 10:26 Mike Pagano
2017-05-14 13:31 Mike Pagano
2017-05-08 10:43 Mike Pagano
2017-05-03 17:45 Mike Pagano
2017-04-27  9:05 Alice Ferrazzi
2017-04-22 17:01 Mike Pagano
2017-04-18 10:23 Mike Pagano
2017-04-12 18:01 Mike Pagano
2017-04-08 13:53 Mike Pagano
2017-03-31 10:44 Mike Pagano
2017-03-30 18:15 Mike Pagano
2017-03-26 11:54 Mike Pagano
2017-03-23 18:38 Mike Pagano
2017-03-22 12:42 Mike Pagano
2017-03-18 14:34 Mike Pagano
2017-03-15 19:21 Mike Pagano
2017-03-12 12:22 Mike Pagano
2017-03-02 16:23 Mike Pagano
2017-02-26 20:38 Mike Pagano
2017-02-26 20:36 Mike Pagano
2017-02-23 20:34 Mike Pagano
2017-02-23 20:11 Mike Pagano
2017-02-18 20:37 Mike Pagano
2017-02-18 16:13 Alice Ferrazzi
2017-02-15 16:02 Alice Ferrazzi
2017-02-14 23:08 Mike Pagano
2017-02-09 11:11 Alice Ferrazzi
2017-02-04 11:34 Alice Ferrazzi
2017-02-01 13:07 Alice Ferrazzi
2017-01-29 23:08 Alice Ferrazzi
2017-01-26  8:51 Alice Ferrazzi
2017-01-20 11:33 Alice Ferrazzi
2017-01-15 22:59 Mike Pagano
2017-01-12 22:53 Mike Pagano
2017-01-09 12:41 Mike Pagano
2017-01-07  0:55 Mike Pagano
2017-01-06 23:09 Mike Pagano
2016-12-31 19:39 Mike Pagano
2016-12-11 23:20 Mike Pagano

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1656152642.bc9a85789c4e42d0ea50133da958b1a29e193493.mpagano@gentoo \
    --to=mpagano@gentoo.org \
    --cc=gentoo-commits@lists.gentoo.org \
    --cc=gentoo-dev@lists.gentoo.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox