--- /dev/null
+From 74e19ef0ff8061ef55957c3abd71614ef0f42f47 Mon Sep 17 00:00:00 2001
+From: Dave Hansen <dave.hansen@linux.intel.com>
+Date: Tue, 21 Feb 2023 12:30:15 -0800
+Subject: uaccess: Add speculation barrier to copy_from_user()
+
+From: Dave Hansen <dave.hansen@linux.intel.com>
+
+commit 74e19ef0ff8061ef55957c3abd71614ef0f42f47 upstream.
+
+The results of "access_ok()" can be mis-speculated. The result is that
+you can end speculatively:
+
+ if (access_ok(from, size))
+ // Right here
+
+even for bad from/size combinations. On first glance, it would be ideal
+to just add a speculation barrier to "access_ok()" so that its results
+can never be mis-speculated.
+
+But there are lots of system calls just doing access_ok() via
+"copy_to_user()" and friends (example: fstat() and friends). Those are
+generally not problematic because they do not _consume_ data from
+userspace other than the pointer. They are also very quick and common
+system calls that should not be needlessly slowed down.
+
+"copy_from_user()" on the other hand uses a user-controller pointer and
+is frequently followed up with code that might affect caches. Take
+something like this:
+
+ if (!copy_from_user(&kernelvar, uptr, size))
+ do_something_with(kernelvar);
+
+If userspace passes in an evil 'uptr' that *actually* points to a kernel
+addresses, and then do_something_with() has cache (or other)
+side-effects, it could allow userspace to infer kernel data values.
+
+Add a barrier to the common copy_from_user() code to prevent
+mis-speculated values which happen after the copy.
+
+Also add a stub for architectures that do not define barrier_nospec().
+This makes the macro usable in generic code.
+
+Since the barrier is now usable in generic code, the x86 #ifdef in the
+BPF code can also go away.
+
+Reported-by: Jordy Zomer <jordyzomer@google.com>
+Suggested-by: Linus Torvalds <torvalds@linuxfoundation.org>
+Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
+Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
+Acked-by: Daniel Borkmann <daniel@iogearbox.net> # BPF bits
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/linux/nospec.h | 4 ++++
+ kernel/bpf/core.c | 2 --
+ lib/usercopy.c | 7 +++++++
+ 3 files changed, 11 insertions(+), 2 deletions(-)
+
+--- a/include/linux/nospec.h
++++ b/include/linux/nospec.h
+@@ -9,6 +9,10 @@
+
+ struct task_struct;
+
++#ifndef barrier_nospec
++# define barrier_nospec() do { } while (0)
++#endif
++
+ /**
+ * array_index_mask_nospec() - generate a ~0 mask when index < size, 0 otherwise
+ * @index: array element index
+--- a/kernel/bpf/core.c
++++ b/kernel/bpf/core.c
+@@ -1567,9 +1567,7 @@ out:
+ * reuse preexisting logic from Spectre v1 mitigation that
+ * happens to produce the required code on x86 for v4 as well.
+ */
+-#ifdef CONFIG_X86
+ barrier_nospec();
+-#endif
+ CONT;
+ #define LDST(SIZEOP, SIZE) \
+ STX_MEM_##SIZEOP: \
+--- a/lib/usercopy.c
++++ b/lib/usercopy.c
+@@ -1,6 +1,7 @@
+ // SPDX-License-Identifier: GPL-2.0
+ #include <linux/uaccess.h>
+ #include <linux/bitops.h>
++#include <linux/nospec.h>
+
+ /* out-of-line parts */
+
+@@ -10,6 +11,12 @@ unsigned long _copy_from_user(void *to,
+ unsigned long res = n;
+ might_fault();
+ if (likely(access_ok(from, n))) {
++ /*
++ * Ensure that bad access_ok() speculation will not
++ * lead to nasty side effects *after* the copy is
++ * finished:
++ */
++ barrier_nospec();
+ kasan_check_write(to, n);
+ res = raw_copy_from_user(to, from, n);
+ }