]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
6.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 21 Jul 2023 04:45:52 +0000 (06:45 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 21 Jul 2023 04:45:52 +0000 (06:45 +0200)
added patches:
kasan-add-kasan_tag_mismatch-prototype.patch
kasan-fix-type-cast-in-memory_is_poisoned_n.patch
kasan-slub-fix-hw_tags-zeroing-with-slub_debug.patch
kasan-use-internal-prototypes-matching-gcc-13-builtins.patch
kbuild-make-modules_install-copy-modules.builtin-.modinfo.patch
mtd-rawnand-meson-fix-unaligned-dma-buffers-handling.patch
net-bcmgenet-ensure-mdio-unregistration-has-clocks-enabled.patch
net-phy-dp83td510-fix-kernel-stall-during-netboot-in-dp83td510e-phy-driver.patch
pinctrl-amd-detect-and-mask-spurious-interrupts.patch
pinctrl-amd-detect-internal-gpio0-debounce-handling.patch
pinctrl-amd-drop-pull-up-select-configuration.patch
pinctrl-amd-fix-mistake-in-handling-clearing-pins-at-startup.patch
pinctrl-amd-only-use-special-debounce-behavior-for-gpio-0.patch
pinctrl-amd-revert-pinctrl-amd-disable-and-mask-interrupts-on-probe.patch
pinctrl-amd-unify-debounce-handling-into-amd_pinconf_set.patch
pinctrl-amd-use-amd_pinconf_set-for-all-config-options.patch
tpm-do-not-remap-from-acpi-resources-again-for-pluton-tpm.patch
tpm-return-false-from-tpm_amd_is_rng_defective-on-non-x86-platforms.patch
tpm-tis_i2c-limit-read-bursts-to-i2c_smbus_block_max-32-bytes.patch
tpm-tis_i2c-limit-write-bursts-to-i2c_smbus_block_max-32-bytes.patch
tpm-tpm_tis-disable-interrupts-after-1000-unhandled-irqs.patch
tpm-tpm_tis-disable-interrupts-for-framework-laptop-intel-12th-gen.patch
tpm-tpm_tis-disable-interrupts-for-framework-laptop-intel-13th-gen.patch
tpm-tpm_tis-disable-interrupts-for-lenovo-l590-devices.patch
tpm-tpm_tis-disable-interrupts-only-for-aeon-upx-i11.patch
tpm-tpm_vtpm_proxy-fix-a-race-condition-in-dev-vtpmx-creation.patch
tracing-user_events-fix-incorrect-return-value-for-writing-operation-when-events-are-disabled.patch

28 files changed:
queue-6.4/kasan-add-kasan_tag_mismatch-prototype.patch [new file with mode: 0644]
queue-6.4/kasan-fix-type-cast-in-memory_is_poisoned_n.patch [new file with mode: 0644]
queue-6.4/kasan-slub-fix-hw_tags-zeroing-with-slub_debug.patch [new file with mode: 0644]
queue-6.4/kasan-use-internal-prototypes-matching-gcc-13-builtins.patch [new file with mode: 0644]
queue-6.4/kbuild-make-modules_install-copy-modules.builtin-.modinfo.patch [new file with mode: 0644]
queue-6.4/mtd-rawnand-meson-fix-unaligned-dma-buffers-handling.patch [new file with mode: 0644]
queue-6.4/net-bcmgenet-ensure-mdio-unregistration-has-clocks-enabled.patch [new file with mode: 0644]
queue-6.4/net-phy-dp83td510-fix-kernel-stall-during-netboot-in-dp83td510e-phy-driver.patch [new file with mode: 0644]
queue-6.4/pinctrl-amd-detect-and-mask-spurious-interrupts.patch [new file with mode: 0644]
queue-6.4/pinctrl-amd-detect-internal-gpio0-debounce-handling.patch [new file with mode: 0644]
queue-6.4/pinctrl-amd-drop-pull-up-select-configuration.patch [new file with mode: 0644]
queue-6.4/pinctrl-amd-fix-mistake-in-handling-clearing-pins-at-startup.patch [new file with mode: 0644]
queue-6.4/pinctrl-amd-only-use-special-debounce-behavior-for-gpio-0.patch [new file with mode: 0644]
queue-6.4/pinctrl-amd-revert-pinctrl-amd-disable-and-mask-interrupts-on-probe.patch [new file with mode: 0644]
queue-6.4/pinctrl-amd-unify-debounce-handling-into-amd_pinconf_set.patch [new file with mode: 0644]
queue-6.4/pinctrl-amd-use-amd_pinconf_set-for-all-config-options.patch [new file with mode: 0644]
queue-6.4/series
queue-6.4/tpm-do-not-remap-from-acpi-resources-again-for-pluton-tpm.patch [new file with mode: 0644]
queue-6.4/tpm-return-false-from-tpm_amd_is_rng_defective-on-non-x86-platforms.patch [new file with mode: 0644]
queue-6.4/tpm-tis_i2c-limit-read-bursts-to-i2c_smbus_block_max-32-bytes.patch [new file with mode: 0644]
queue-6.4/tpm-tis_i2c-limit-write-bursts-to-i2c_smbus_block_max-32-bytes.patch [new file with mode: 0644]
queue-6.4/tpm-tpm_tis-disable-interrupts-after-1000-unhandled-irqs.patch [new file with mode: 0644]
queue-6.4/tpm-tpm_tis-disable-interrupts-for-framework-laptop-intel-12th-gen.patch [new file with mode: 0644]
queue-6.4/tpm-tpm_tis-disable-interrupts-for-framework-laptop-intel-13th-gen.patch [new file with mode: 0644]
queue-6.4/tpm-tpm_tis-disable-interrupts-for-lenovo-l590-devices.patch [new file with mode: 0644]
queue-6.4/tpm-tpm_tis-disable-interrupts-only-for-aeon-upx-i11.patch [new file with mode: 0644]
queue-6.4/tpm-tpm_vtpm_proxy-fix-a-race-condition-in-dev-vtpmx-creation.patch [new file with mode: 0644]
queue-6.4/tracing-user_events-fix-incorrect-return-value-for-writing-operation-when-events-are-disabled.patch [new file with mode: 0644]

diff --git a/queue-6.4/kasan-add-kasan_tag_mismatch-prototype.patch b/queue-6.4/kasan-add-kasan_tag_mismatch-prototype.patch
new file mode 100644 (file)
index 0000000..2ef87c5
--- /dev/null
@@ -0,0 +1,43 @@
+From fb646a4cd3f0ff27d19911bef7b6622263723df6 Mon Sep 17 00:00:00 2001
+From: Arnd Bergmann <arnd@arndb.de>
+Date: Tue, 9 May 2023 16:57:20 +0200
+Subject: kasan: add kasan_tag_mismatch prototype
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+commit fb646a4cd3f0ff27d19911bef7b6622263723df6 upstream.
+
+The kasan sw-tags implementation contains one function that is only called
+from assembler and has no prototype in a header.  This causes a W=1
+warning:
+
+mm/kasan/sw_tags.c:171:6: warning: no previous prototype for 'kasan_tag_mismatch' [-Wmissing-prototypes]
+  171 | void kasan_tag_mismatch(unsigned long addr, unsigned long access_info,
+
+Add a prototype in the local header to get a clean build.
+
+Link: https://lkml.kernel.org/r/20230509145735.9263-1-arnd@kernel.org
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Cc: Alexander Potapenko <glider@google.com>
+Cc: Andrey Konovalov <andreyknvl@gmail.com>
+Cc: Andrey Ryabinin <ryabinin.a.a@gmail.com>
+Cc: Dmitry Vyukov <dvyukov@google.com>
+Cc: Marco Elver <elver@google.com>
+Cc: Vincenzo Frascino <vincenzo.frascino@arm.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ mm/kasan/kasan.h |    3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/mm/kasan/kasan.h
++++ b/mm/kasan/kasan.h
+@@ -646,4 +646,7 @@ void *__hwasan_memset(void *addr, int c,
+ void *__hwasan_memmove(void *dest, const void *src, size_t len);
+ void *__hwasan_memcpy(void *dest, const void *src, size_t len);
++void kasan_tag_mismatch(unsigned long addr, unsigned long access_info,
++                      unsigned long ret_ip);
++
+ #endif /* __MM_KASAN_KASAN_H */
diff --git a/queue-6.4/kasan-fix-type-cast-in-memory_is_poisoned_n.patch b/queue-6.4/kasan-fix-type-cast-in-memory_is_poisoned_n.patch
new file mode 100644 (file)
index 0000000..7e981ac
--- /dev/null
@@ -0,0 +1,49 @@
+From 05c56e7b4319d7f6352f27da876a1acdc8fa5cc4 Mon Sep 17 00:00:00 2001
+From: Andrey Konovalov <andreyknvl@google.com>
+Date: Tue, 4 Jul 2023 02:52:05 +0200
+Subject: kasan: fix type cast in memory_is_poisoned_n
+
+From: Andrey Konovalov <andreyknvl@google.com>
+
+commit 05c56e7b4319d7f6352f27da876a1acdc8fa5cc4 upstream.
+
+Commit bb6e04a173f0 ("kasan: use internal prototypes matching gcc-13
+builtins") introduced a bug into the memory_is_poisoned_n implementation:
+it effectively removed the cast to a signed integer type after applying
+KASAN_GRANULE_MASK.
+
+As a result, KASAN started failing to properly check memset, memcpy, and
+other similar functions.
+
+Fix the bug by adding the cast back (through an additional signed integer
+variable to make the code more readable).
+
+Link: https://lkml.kernel.org/r/8c9e0251c2b8b81016255709d4ec42942dcaf018.1688431866.git.andreyknvl@google.com
+Fixes: bb6e04a173f0 ("kasan: use internal prototypes matching gcc-13 builtins")
+Signed-off-by: Andrey Konovalov <andreyknvl@google.com>
+Cc: Alexander Potapenko <glider@google.com>
+Cc: Andrey Ryabinin <ryabinin.a.a@gmail.com>
+Cc: Arnd Bergmann <arnd@arndb.de>
+Cc: Dmitry Vyukov <dvyukov@google.com>
+Cc: Marco Elver <elver@google.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ mm/kasan/generic.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/mm/kasan/generic.c
++++ b/mm/kasan/generic.c
+@@ -130,9 +130,10 @@ static __always_inline bool memory_is_po
+       if (unlikely(ret)) {
+               const void *last_byte = addr + size - 1;
+               s8 *last_shadow = (s8 *)kasan_mem_to_shadow(last_byte);
++              s8 last_accessible_byte = (unsigned long)last_byte & KASAN_GRANULE_MASK;
+               if (unlikely(ret != (unsigned long)last_shadow ||
+-                      (((long)last_byte & KASAN_GRANULE_MASK) >= *last_shadow)))
++                           last_accessible_byte >= *last_shadow))
+                       return true;
+       }
+       return false;
diff --git a/queue-6.4/kasan-slub-fix-hw_tags-zeroing-with-slub_debug.patch b/queue-6.4/kasan-slub-fix-hw_tags-zeroing-with-slub_debug.patch
new file mode 100644 (file)
index 0000000..e1ffee2
--- /dev/null
@@ -0,0 +1,114 @@
+From fdb54d96600aafe45951f549866cd6fc1af59954 Mon Sep 17 00:00:00 2001
+From: Andrey Konovalov <andreyknvl@google.com>
+Date: Wed, 5 Jul 2023 14:44:02 +0200
+Subject: kasan, slub: fix HW_TAGS zeroing with slub_debug
+
+From: Andrey Konovalov <andreyknvl@google.com>
+
+commit fdb54d96600aafe45951f549866cd6fc1af59954 upstream.
+
+Commit 946fa0dbf2d8 ("mm/slub: extend redzone check to extra allocated
+kmalloc space than requested") added precise kmalloc redzone poisoning to
+the slub_debug functionality.
+
+However, this commit didn't account for HW_TAGS KASAN fully initializing
+the object via its built-in memory initialization feature.  Even though
+HW_TAGS KASAN memory initialization contains special memory initialization
+handling for when slub_debug is enabled, it does not account for in-object
+slub_debug redzones.  As a result, HW_TAGS KASAN can overwrite these
+redzones and cause false-positive slub_debug reports.
+
+To fix the issue, avoid HW_TAGS KASAN memory initialization when
+slub_debug is enabled altogether.  Implement this by moving the
+__slub_debug_enabled check to slab_post_alloc_hook.  Common slab code
+seems like a more appropriate place for a slub_debug check anyway.
+
+Link: https://lkml.kernel.org/r/678ac92ab790dba9198f9ca14f405651b97c8502.1688561016.git.andreyknvl@google.com
+Fixes: 946fa0dbf2d8 ("mm/slub: extend redzone check to extra allocated kmalloc space than requested")
+Signed-off-by: Andrey Konovalov <andreyknvl@google.com>
+Reported-by: Will Deacon <will@kernel.org>
+Acked-by: Marco Elver <elver@google.com>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Alexander Potapenko <glider@google.com>
+Cc: Andrey Ryabinin <ryabinin.a.a@gmail.com>
+Cc: Catalin Marinas <catalin.marinas@arm.com>
+Cc: Christoph Lameter <cl@linux.com>
+Cc: David Rientjes <rientjes@google.com>
+Cc: Dmitry Vyukov <dvyukov@google.com>
+Cc: Feng Tang <feng.tang@intel.com>
+Cc: Hyeonggon Yoo <42.hyeyoo@gmail.com>
+Cc: Joonsoo Kim <iamjoonsoo.kim@lge.com>
+Cc: kasan-dev@googlegroups.com
+Cc: Pekka Enberg <penberg@kernel.org>
+Cc: Peter Collingbourne <pcc@google.com>
+Cc: Roman Gushchin <roman.gushchin@linux.dev>
+Cc: Vincenzo Frascino <vincenzo.frascino@arm.com>
+Cc: Vlastimil Babka <vbabka@suse.cz>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ mm/kasan/kasan.h |   12 ------------
+ mm/slab.h        |   16 ++++++++++++++--
+ 2 files changed, 14 insertions(+), 14 deletions(-)
+
+--- a/mm/kasan/kasan.h
++++ b/mm/kasan/kasan.h
+@@ -466,18 +466,6 @@ static inline void kasan_unpoison(const
+       if (WARN_ON((unsigned long)addr & KASAN_GRANULE_MASK))
+               return;
+-      /*
+-       * Explicitly initialize the memory with the precise object size to
+-       * avoid overwriting the slab redzone. This disables initialization in
+-       * the arch code and may thus lead to performance penalty. This penalty
+-       * does not affect production builds, as slab redzones are not enabled
+-       * there.
+-       */
+-      if (__slub_debug_enabled() &&
+-          init && ((unsigned long)size & KASAN_GRANULE_MASK)) {
+-              init = false;
+-              memzero_explicit((void *)addr, size);
+-      }
+       size = round_up(size, KASAN_GRANULE_SIZE);
+       hw_set_mem_tag_range((void *)addr, size, tag, init);
+--- a/mm/slab.h
++++ b/mm/slab.h
+@@ -684,6 +684,7 @@ static inline void slab_post_alloc_hook(
+                                       unsigned int orig_size)
+ {
+       unsigned int zero_size = s->object_size;
++      bool kasan_init = init;
+       size_t i;
+       flags &= gfp_allowed_mask;
+@@ -701,6 +702,17 @@ static inline void slab_post_alloc_hook(
+               zero_size = orig_size;
+       /*
++       * When slub_debug is enabled, avoid memory initialization integrated
++       * into KASAN and instead zero out the memory via the memset below with
++       * the proper size. Otherwise, KASAN might overwrite SLUB redzones and
++       * cause false-positive reports. This does not lead to a performance
++       * penalty on production builds, as slub_debug is not intended to be
++       * enabled there.
++       */
++      if (__slub_debug_enabled())
++              kasan_init = false;
++
++      /*
+        * As memory initialization might be integrated into KASAN,
+        * kasan_slab_alloc and initialization memset must be
+        * kept together to avoid discrepancies in behavior.
+@@ -708,8 +720,8 @@ static inline void slab_post_alloc_hook(
+        * As p[i] might get tagged, memset and kmemleak hook come after KASAN.
+        */
+       for (i = 0; i < size; i++) {
+-              p[i] = kasan_slab_alloc(s, p[i], flags, init);
+-              if (p[i] && init && !kasan_has_integrated_init())
++              p[i] = kasan_slab_alloc(s, p[i], flags, kasan_init);
++              if (p[i] && init && (!kasan_init || !kasan_has_integrated_init()))
+                       memset(p[i], 0, zero_size);
+               kmemleak_alloc_recursive(p[i], s->object_size, 1,
+                                        s->flags, flags);
diff --git a/queue-6.4/kasan-use-internal-prototypes-matching-gcc-13-builtins.patch b/queue-6.4/kasan-use-internal-prototypes-matching-gcc-13-builtins.patch
new file mode 100644 (file)
index 0000000..7e29b27
--- /dev/null
@@ -0,0 +1,845 @@
+From bb6e04a173f06e51819a4bb512e127dfbc50dcfa Mon Sep 17 00:00:00 2001
+From: Arnd Bergmann <arnd@arndb.de>
+Date: Tue, 9 May 2023 16:57:21 +0200
+Subject: kasan: use internal prototypes matching gcc-13 builtins
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+commit bb6e04a173f06e51819a4bb512e127dfbc50dcfa upstream.
+
+gcc-13 warns about function definitions for builtin interfaces that have a
+different prototype, e.g.:
+
+In file included from kasan_test.c:31:
+kasan.h:574:6: error: conflicting types for built-in function '__asan_register_globals'; expected 'void(void *, long int)' [-Werror=builtin-declaration-mismatch]
+  574 | void __asan_register_globals(struct kasan_global *globals, size_t size);
+kasan.h:577:6: error: conflicting types for built-in function '__asan_alloca_poison'; expected 'void(void *, long int)' [-Werror=builtin-declaration-mismatch]
+  577 | void __asan_alloca_poison(unsigned long addr, size_t size);
+kasan.h:580:6: error: conflicting types for built-in function '__asan_load1'; expected 'void(void *)' [-Werror=builtin-declaration-mismatch]
+  580 | void __asan_load1(unsigned long addr);
+kasan.h:581:6: error: conflicting types for built-in function '__asan_store1'; expected 'void(void *)' [-Werror=builtin-declaration-mismatch]
+  581 | void __asan_store1(unsigned long addr);
+kasan.h:643:6: error: conflicting types for built-in function '__hwasan_tag_memory'; expected 'void(void *, unsigned char,  long int)' [-Werror=builtin-declaration-mismatch]
+  643 | void __hwasan_tag_memory(unsigned long addr, u8 tag, unsigned long size);
+
+The two problems are:
+
+ - Addresses are passes as 'unsigned long' in the kernel, but gcc-13
+   expects a 'void *'.
+
+ - sizes meant to use a signed ssize_t rather than size_t.
+
+Change all the prototypes to match these.  Using 'void *' consistently for
+addresses gets rid of a couple of type casts, so push that down to the
+leaf functions where possible.
+
+This now passes all randconfig builds on arm, arm64 and x86, but I have
+not tested it on the other architectures that support kasan, since they
+tend to fail randconfig builds in other ways.  This might fail if any of
+the 32-bit architectures expect a 'long' instead of 'int' for the size
+argument.
+
+The __asan_allocas_unpoison() function prototype is somewhat weird, since
+it uses a pointer for 'stack_top' and an size_t for 'stack_bottom'.  This
+looks like it is meant to be 'addr' and 'size' like the others, but the
+implementation clearly treats them as 'top' and 'bottom'.
+
+Link: https://lkml.kernel.org/r/20230509145735.9263-2-arnd@kernel.org
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Cc: Alexander Potapenko <glider@google.com>
+Cc: Andrey Konovalov <andreyknvl@gmail.com>
+Cc: Andrey Ryabinin <ryabinin.a.a@gmail.com>
+Cc: Dmitry Vyukov <dvyukov@google.com>
+Cc: Marco Elver <elver@google.com>
+Cc: Vincenzo Frascino <vincenzo.frascino@arm.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/arm64/kernel/traps.c |    2 
+ arch/arm64/mm/fault.c     |    2 
+ include/linux/kasan.h     |    2 
+ mm/kasan/common.c         |    2 
+ mm/kasan/generic.c        |   72 ++++++++++-----------
+ mm/kasan/kasan.h          |  156 +++++++++++++++++++++++-----------------------
+ mm/kasan/report.c         |   17 ++---
+ mm/kasan/report_generic.c |   12 +--
+ mm/kasan/report_hw_tags.c |    2 
+ mm/kasan/report_sw_tags.c |    2 
+ mm/kasan/shadow.c         |   36 +++++-----
+ mm/kasan/sw_tags.c        |   20 ++---
+ 12 files changed, 162 insertions(+), 163 deletions(-)
+
+--- a/arch/arm64/kernel/traps.c
++++ b/arch/arm64/kernel/traps.c
+@@ -1044,7 +1044,7 @@ static int kasan_handler(struct pt_regs
+       bool recover = esr & KASAN_ESR_RECOVER;
+       bool write = esr & KASAN_ESR_WRITE;
+       size_t size = KASAN_ESR_SIZE(esr);
+-      u64 addr = regs->regs[0];
++      void *addr = (void *)regs->regs[0];
+       u64 pc = regs->pc;
+       kasan_report(addr, size, write, pc);
+--- a/arch/arm64/mm/fault.c
++++ b/arch/arm64/mm/fault.c
+@@ -317,7 +317,7 @@ static void report_tag_fault(unsigned lo
+        * find out access size.
+        */
+       bool is_write = !!(esr & ESR_ELx_WNR);
+-      kasan_report(addr, 0, is_write, regs->pc);
++      kasan_report((void *)addr, 0, is_write, regs->pc);
+ }
+ #else
+ /* Tag faults aren't enabled without CONFIG_KASAN_HW_TAGS. */
+--- a/include/linux/kasan.h
++++ b/include/linux/kasan.h
+@@ -343,7 +343,7 @@ static inline void *kasan_reset_tag(cons
+  * @is_write: whether the bad access is a write or a read
+  * @ip: instruction pointer for the accessibility check or the bad access itself
+  */
+-bool kasan_report(unsigned long addr, size_t size,
++bool kasan_report(const void *addr, size_t size,
+               bool is_write, unsigned long ip);
+ #else /* CONFIG_KASAN_SW_TAGS || CONFIG_KASAN_HW_TAGS */
+--- a/mm/kasan/common.c
++++ b/mm/kasan/common.c
+@@ -445,7 +445,7 @@ void * __must_check __kasan_krealloc(con
+ bool __kasan_check_byte(const void *address, unsigned long ip)
+ {
+       if (!kasan_byte_accessible(address)) {
+-              kasan_report((unsigned long)address, 1, false, ip);
++              kasan_report(address, 1, false, ip);
+               return false;
+       }
+       return true;
+--- a/mm/kasan/generic.c
++++ b/mm/kasan/generic.c
+@@ -40,39 +40,39 @@
+  * depending on memory access size X.
+  */
+-static __always_inline bool memory_is_poisoned_1(unsigned long addr)
++static __always_inline bool memory_is_poisoned_1(const void *addr)
+ {
+-      s8 shadow_value = *(s8 *)kasan_mem_to_shadow((void *)addr);
++      s8 shadow_value = *(s8 *)kasan_mem_to_shadow(addr);
+       if (unlikely(shadow_value)) {
+-              s8 last_accessible_byte = addr & KASAN_GRANULE_MASK;
++              s8 last_accessible_byte = (unsigned long)addr & KASAN_GRANULE_MASK;
+               return unlikely(last_accessible_byte >= shadow_value);
+       }
+       return false;
+ }
+-static __always_inline bool memory_is_poisoned_2_4_8(unsigned long addr,
++static __always_inline bool memory_is_poisoned_2_4_8(const void *addr,
+                                               unsigned long size)
+ {
+-      u8 *shadow_addr = (u8 *)kasan_mem_to_shadow((void *)addr);
++      u8 *shadow_addr = (u8 *)kasan_mem_to_shadow(addr);
+       /*
+        * Access crosses 8(shadow size)-byte boundary. Such access maps
+        * into 2 shadow bytes, so we need to check them both.
+        */
+-      if (unlikely(((addr + size - 1) & KASAN_GRANULE_MASK) < size - 1))
++      if (unlikely((((unsigned long)addr + size - 1) & KASAN_GRANULE_MASK) < size - 1))
+               return *shadow_addr || memory_is_poisoned_1(addr + size - 1);
+       return memory_is_poisoned_1(addr + size - 1);
+ }
+-static __always_inline bool memory_is_poisoned_16(unsigned long addr)
++static __always_inline bool memory_is_poisoned_16(const void *addr)
+ {
+-      u16 *shadow_addr = (u16 *)kasan_mem_to_shadow((void *)addr);
++      u16 *shadow_addr = (u16 *)kasan_mem_to_shadow(addr);
+       /* Unaligned 16-bytes access maps into 3 shadow bytes. */
+-      if (unlikely(!IS_ALIGNED(addr, KASAN_GRANULE_SIZE)))
++      if (unlikely(!IS_ALIGNED((unsigned long)addr, KASAN_GRANULE_SIZE)))
+               return *shadow_addr || memory_is_poisoned_1(addr + 15);
+       return *shadow_addr;
+@@ -120,26 +120,25 @@ static __always_inline unsigned long mem
+       return bytes_is_nonzero(start, (end - start) % 8);
+ }
+-static __always_inline bool memory_is_poisoned_n(unsigned long addr,
+-                                              size_t size)
++static __always_inline bool memory_is_poisoned_n(const void *addr, size_t size)
+ {
+       unsigned long ret;
+-      ret = memory_is_nonzero(kasan_mem_to_shadow((void *)addr),
+-                      kasan_mem_to_shadow((void *)addr + size - 1) + 1);
++      ret = memory_is_nonzero(kasan_mem_to_shadow(addr),
++                      kasan_mem_to_shadow(addr + size - 1) + 1);
+       if (unlikely(ret)) {
+-              unsigned long last_byte = addr + size - 1;
+-              s8 *last_shadow = (s8 *)kasan_mem_to_shadow((void *)last_byte);
++              const void *last_byte = addr + size - 1;
++              s8 *last_shadow = (s8 *)kasan_mem_to_shadow(last_byte);
+               if (unlikely(ret != (unsigned long)last_shadow ||
+-                      ((long)(last_byte & KASAN_GRANULE_MASK) >= *last_shadow)))
++                      (((long)last_byte & KASAN_GRANULE_MASK) >= *last_shadow)))
+                       return true;
+       }
+       return false;
+ }
+-static __always_inline bool memory_is_poisoned(unsigned long addr, size_t size)
++static __always_inline bool memory_is_poisoned(const void *addr, size_t size)
+ {
+       if (__builtin_constant_p(size)) {
+               switch (size) {
+@@ -159,7 +158,7 @@ static __always_inline bool memory_is_po
+       return memory_is_poisoned_n(addr, size);
+ }
+-static __always_inline bool check_region_inline(unsigned long addr,
++static __always_inline bool check_region_inline(const void *addr,
+                                               size_t size, bool write,
+                                               unsigned long ret_ip)
+ {
+@@ -172,7 +171,7 @@ static __always_inline bool check_region
+       if (unlikely(addr + size < addr))
+               return !kasan_report(addr, size, write, ret_ip);
+-      if (unlikely(!addr_has_metadata((void *)addr)))
++      if (unlikely(!addr_has_metadata(addr)))
+               return !kasan_report(addr, size, write, ret_ip);
+       if (likely(!memory_is_poisoned(addr, size)))
+@@ -181,7 +180,7 @@ static __always_inline bool check_region
+       return !kasan_report(addr, size, write, ret_ip);
+ }
+-bool kasan_check_range(unsigned long addr, size_t size, bool write,
++bool kasan_check_range(const void *addr, size_t size, bool write,
+                                       unsigned long ret_ip)
+ {
+       return check_region_inline(addr, size, write, ret_ip);
+@@ -221,36 +220,37 @@ static void register_global(struct kasan
+                    KASAN_GLOBAL_REDZONE, false);
+ }
+-void __asan_register_globals(struct kasan_global *globals, size_t size)
++void __asan_register_globals(void *ptr, ssize_t size)
+ {
+       int i;
++      struct kasan_global *globals = ptr;
+       for (i = 0; i < size; i++)
+               register_global(&globals[i]);
+ }
+ EXPORT_SYMBOL(__asan_register_globals);
+-void __asan_unregister_globals(struct kasan_global *globals, size_t size)
++void __asan_unregister_globals(void *ptr, ssize_t size)
+ {
+ }
+ EXPORT_SYMBOL(__asan_unregister_globals);
+ #define DEFINE_ASAN_LOAD_STORE(size)                                  \
+-      void __asan_load##size(unsigned long addr)                      \
++      void __asan_load##size(void *addr)                              \
+       {                                                               \
+               check_region_inline(addr, size, false, _RET_IP_);       \
+       }                                                               \
+       EXPORT_SYMBOL(__asan_load##size);                               \
+       __alias(__asan_load##size)                                      \
+-      void __asan_load##size##_noabort(unsigned long);                \
++      void __asan_load##size##_noabort(void *);                       \
+       EXPORT_SYMBOL(__asan_load##size##_noabort);                     \
+-      void __asan_store##size(unsigned long addr)                     \
++      void __asan_store##size(void *addr)                             \
+       {                                                               \
+               check_region_inline(addr, size, true, _RET_IP_);        \
+       }                                                               \
+       EXPORT_SYMBOL(__asan_store##size);                              \
+       __alias(__asan_store##size)                                     \
+-      void __asan_store##size##_noabort(unsigned long);               \
++      void __asan_store##size##_noabort(void *);                      \
+       EXPORT_SYMBOL(__asan_store##size##_noabort)
+ DEFINE_ASAN_LOAD_STORE(1);
+@@ -259,24 +259,24 @@ DEFINE_ASAN_LOAD_STORE(4);
+ DEFINE_ASAN_LOAD_STORE(8);
+ DEFINE_ASAN_LOAD_STORE(16);
+-void __asan_loadN(unsigned long addr, size_t size)
++void __asan_loadN(void *addr, ssize_t size)
+ {
+       kasan_check_range(addr, size, false, _RET_IP_);
+ }
+ EXPORT_SYMBOL(__asan_loadN);
+ __alias(__asan_loadN)
+-void __asan_loadN_noabort(unsigned long, size_t);
++void __asan_loadN_noabort(void *, ssize_t);
+ EXPORT_SYMBOL(__asan_loadN_noabort);
+-void __asan_storeN(unsigned long addr, size_t size)
++void __asan_storeN(void *addr, ssize_t size)
+ {
+       kasan_check_range(addr, size, true, _RET_IP_);
+ }
+ EXPORT_SYMBOL(__asan_storeN);
+ __alias(__asan_storeN)
+-void __asan_storeN_noabort(unsigned long, size_t);
++void __asan_storeN_noabort(void *, ssize_t);
+ EXPORT_SYMBOL(__asan_storeN_noabort);
+ /* to shut up compiler complaints */
+@@ -284,7 +284,7 @@ void __asan_handle_no_return(void) {}
+ EXPORT_SYMBOL(__asan_handle_no_return);
+ /* Emitted by compiler to poison alloca()ed objects. */
+-void __asan_alloca_poison(unsigned long addr, size_t size)
++void __asan_alloca_poison(void *addr, ssize_t size)
+ {
+       size_t rounded_up_size = round_up(size, KASAN_GRANULE_SIZE);
+       size_t padding_size = round_up(size, KASAN_ALLOCA_REDZONE_SIZE) -
+@@ -295,7 +295,7 @@ void __asan_alloca_poison(unsigned long
+                       KASAN_ALLOCA_REDZONE_SIZE);
+       const void *right_redzone = (const void *)(addr + rounded_up_size);
+-      WARN_ON(!IS_ALIGNED(addr, KASAN_ALLOCA_REDZONE_SIZE));
++      WARN_ON(!IS_ALIGNED((unsigned long)addr, KASAN_ALLOCA_REDZONE_SIZE));
+       kasan_unpoison((const void *)(addr + rounded_down_size),
+                       size - rounded_down_size, false);
+@@ -307,18 +307,18 @@ void __asan_alloca_poison(unsigned long
+ EXPORT_SYMBOL(__asan_alloca_poison);
+ /* Emitted by compiler to unpoison alloca()ed areas when the stack unwinds. */
+-void __asan_allocas_unpoison(const void *stack_top, const void *stack_bottom)
++void __asan_allocas_unpoison(void *stack_top, ssize_t stack_bottom)
+ {
+-      if (unlikely(!stack_top || stack_top > stack_bottom))
++      if (unlikely(!stack_top || stack_top > (void *)stack_bottom))
+               return;
+-      kasan_unpoison(stack_top, stack_bottom - stack_top, false);
++      kasan_unpoison(stack_top, (void *)stack_bottom - stack_top, false);
+ }
+ EXPORT_SYMBOL(__asan_allocas_unpoison);
+ /* Emitted by the compiler to [un]poison local variables. */
+ #define DEFINE_ASAN_SET_SHADOW(byte) \
+-      void __asan_set_shadow_##byte(const void *addr, size_t size)    \
++      void __asan_set_shadow_##byte(const void *addr, ssize_t size)   \
+       {                                                               \
+               __memset((void *)addr, 0x##byte, size);                 \
+       }                                                               \
+--- a/mm/kasan/kasan.h
++++ b/mm/kasan/kasan.h
+@@ -198,13 +198,13 @@ enum kasan_report_type {
+ struct kasan_report_info {
+       /* Filled in by kasan_report_*(). */
+       enum kasan_report_type type;
+-      void *access_addr;
++      const void *access_addr;
+       size_t access_size;
+       bool is_write;
+       unsigned long ip;
+       /* Filled in by the common reporting code. */
+-      void *first_bad_addr;
++      const void *first_bad_addr;
+       struct kmem_cache *cache;
+       void *object;
+       size_t alloc_size;
+@@ -311,7 +311,7 @@ static __always_inline bool addr_has_met
+  * @ret_ip: return address
+  * @return: true if access was valid, false if invalid
+  */
+-bool kasan_check_range(unsigned long addr, size_t size, bool write,
++bool kasan_check_range(const void *addr, size_t size, bool write,
+                               unsigned long ret_ip);
+ #else /* CONFIG_KASAN_GENERIC || CONFIG_KASAN_SW_TAGS */
+@@ -323,7 +323,7 @@ static __always_inline bool addr_has_met
+ #endif /* CONFIG_KASAN_GENERIC || CONFIG_KASAN_SW_TAGS */
+-void *kasan_find_first_bad_addr(void *addr, size_t size);
++const void *kasan_find_first_bad_addr(const void *addr, size_t size);
+ size_t kasan_get_alloc_size(void *object, struct kmem_cache *cache);
+ void kasan_complete_mode_report_info(struct kasan_report_info *info);
+ void kasan_metadata_fetch_row(char *buffer, void *row);
+@@ -346,7 +346,7 @@ void kasan_print_aux_stacks(struct kmem_
+ static inline void kasan_print_aux_stacks(struct kmem_cache *cache, const void *object) { }
+ #endif
+-bool kasan_report(unsigned long addr, size_t size,
++bool kasan_report(const void *addr, size_t size,
+               bool is_write, unsigned long ip);
+ void kasan_report_invalid_free(void *object, unsigned long ip, enum kasan_report_type type);
+@@ -571,82 +571,82 @@ void kasan_restore_multi_shot(bool enabl
+  */
+ asmlinkage void kasan_unpoison_task_stack_below(const void *watermark);
+-void __asan_register_globals(struct kasan_global *globals, size_t size);
+-void __asan_unregister_globals(struct kasan_global *globals, size_t size);
++void __asan_register_globals(void *globals, ssize_t size);
++void __asan_unregister_globals(void *globals, ssize_t size);
+ void __asan_handle_no_return(void);
+-void __asan_alloca_poison(unsigned long addr, size_t size);
+-void __asan_allocas_unpoison(const void *stack_top, const void *stack_bottom);
++void __asan_alloca_poison(void *, ssize_t size);
++void __asan_allocas_unpoison(void *stack_top, ssize_t stack_bottom);
+-void __asan_load1(unsigned long addr);
+-void __asan_store1(unsigned long addr);
+-void __asan_load2(unsigned long addr);
+-void __asan_store2(unsigned long addr);
+-void __asan_load4(unsigned long addr);
+-void __asan_store4(unsigned long addr);
+-void __asan_load8(unsigned long addr);
+-void __asan_store8(unsigned long addr);
+-void __asan_load16(unsigned long addr);
+-void __asan_store16(unsigned long addr);
+-void __asan_loadN(unsigned long addr, size_t size);
+-void __asan_storeN(unsigned long addr, size_t size);
+-
+-void __asan_load1_noabort(unsigned long addr);
+-void __asan_store1_noabort(unsigned long addr);
+-void __asan_load2_noabort(unsigned long addr);
+-void __asan_store2_noabort(unsigned long addr);
+-void __asan_load4_noabort(unsigned long addr);
+-void __asan_store4_noabort(unsigned long addr);
+-void __asan_load8_noabort(unsigned long addr);
+-void __asan_store8_noabort(unsigned long addr);
+-void __asan_load16_noabort(unsigned long addr);
+-void __asan_store16_noabort(unsigned long addr);
+-void __asan_loadN_noabort(unsigned long addr, size_t size);
+-void __asan_storeN_noabort(unsigned long addr, size_t size);
+-
+-void __asan_report_load1_noabort(unsigned long addr);
+-void __asan_report_store1_noabort(unsigned long addr);
+-void __asan_report_load2_noabort(unsigned long addr);
+-void __asan_report_store2_noabort(unsigned long addr);
+-void __asan_report_load4_noabort(unsigned long addr);
+-void __asan_report_store4_noabort(unsigned long addr);
+-void __asan_report_load8_noabort(unsigned long addr);
+-void __asan_report_store8_noabort(unsigned long addr);
+-void __asan_report_load16_noabort(unsigned long addr);
+-void __asan_report_store16_noabort(unsigned long addr);
+-void __asan_report_load_n_noabort(unsigned long addr, size_t size);
+-void __asan_report_store_n_noabort(unsigned long addr, size_t size);
+-
+-void __asan_set_shadow_00(const void *addr, size_t size);
+-void __asan_set_shadow_f1(const void *addr, size_t size);
+-void __asan_set_shadow_f2(const void *addr, size_t size);
+-void __asan_set_shadow_f3(const void *addr, size_t size);
+-void __asan_set_shadow_f5(const void *addr, size_t size);
+-void __asan_set_shadow_f8(const void *addr, size_t size);
+-
+-void *__asan_memset(void *addr, int c, size_t len);
+-void *__asan_memmove(void *dest, const void *src, size_t len);
+-void *__asan_memcpy(void *dest, const void *src, size_t len);
+-
+-void __hwasan_load1_noabort(unsigned long addr);
+-void __hwasan_store1_noabort(unsigned long addr);
+-void __hwasan_load2_noabort(unsigned long addr);
+-void __hwasan_store2_noabort(unsigned long addr);
+-void __hwasan_load4_noabort(unsigned long addr);
+-void __hwasan_store4_noabort(unsigned long addr);
+-void __hwasan_load8_noabort(unsigned long addr);
+-void __hwasan_store8_noabort(unsigned long addr);
+-void __hwasan_load16_noabort(unsigned long addr);
+-void __hwasan_store16_noabort(unsigned long addr);
+-void __hwasan_loadN_noabort(unsigned long addr, size_t size);
+-void __hwasan_storeN_noabort(unsigned long addr, size_t size);
+-
+-void __hwasan_tag_memory(unsigned long addr, u8 tag, unsigned long size);
+-
+-void *__hwasan_memset(void *addr, int c, size_t len);
+-void *__hwasan_memmove(void *dest, const void *src, size_t len);
+-void *__hwasan_memcpy(void *dest, const void *src, size_t len);
++void __asan_load1(void *);
++void __asan_store1(void *);
++void __asan_load2(void *);
++void __asan_store2(void *);
++void __asan_load4(void *);
++void __asan_store4(void *);
++void __asan_load8(void *);
++void __asan_store8(void *);
++void __asan_load16(void *);
++void __asan_store16(void *);
++void __asan_loadN(void *, ssize_t size);
++void __asan_storeN(void *, ssize_t size);
++
++void __asan_load1_noabort(void *);
++void __asan_store1_noabort(void *);
++void __asan_load2_noabort(void *);
++void __asan_store2_noabort(void *);
++void __asan_load4_noabort(void *);
++void __asan_store4_noabort(void *);
++void __asan_load8_noabort(void *);
++void __asan_store8_noabort(void *);
++void __asan_load16_noabort(void *);
++void __asan_store16_noabort(void *);
++void __asan_loadN_noabort(void *, ssize_t size);
++void __asan_storeN_noabort(void *, ssize_t size);
++
++void __asan_report_load1_noabort(void *);
++void __asan_report_store1_noabort(void *);
++void __asan_report_load2_noabort(void *);
++void __asan_report_store2_noabort(void *);
++void __asan_report_load4_noabort(void *);
++void __asan_report_store4_noabort(void *);
++void __asan_report_load8_noabort(void *);
++void __asan_report_store8_noabort(void *);
++void __asan_report_load16_noabort(void *);
++void __asan_report_store16_noabort(void *);
++void __asan_report_load_n_noabort(void *, ssize_t size);
++void __asan_report_store_n_noabort(void *, ssize_t size);
++
++void __asan_set_shadow_00(const void *addr, ssize_t size);
++void __asan_set_shadow_f1(const void *addr, ssize_t size);
++void __asan_set_shadow_f2(const void *addr, ssize_t size);
++void __asan_set_shadow_f3(const void *addr, ssize_t size);
++void __asan_set_shadow_f5(const void *addr, ssize_t size);
++void __asan_set_shadow_f8(const void *addr, ssize_t size);
++
++void *__asan_memset(void *addr, int c, ssize_t len);
++void *__asan_memmove(void *dest, const void *src, ssize_t len);
++void *__asan_memcpy(void *dest, const void *src, ssize_t len);
++
++void __hwasan_load1_noabort(void *);
++void __hwasan_store1_noabort(void *);
++void __hwasan_load2_noabort(void *);
++void __hwasan_store2_noabort(void *);
++void __hwasan_load4_noabort(void *);
++void __hwasan_store4_noabort(void *);
++void __hwasan_load8_noabort(void *);
++void __hwasan_store8_noabort(void *);
++void __hwasan_load16_noabort(void *);
++void __hwasan_store16_noabort(void *);
++void __hwasan_loadN_noabort(void *, ssize_t size);
++void __hwasan_storeN_noabort(void *, ssize_t size);
++
++void __hwasan_tag_memory(void *, u8 tag, ssize_t size);
++
++void *__hwasan_memset(void *addr, int c, ssize_t len);
++void *__hwasan_memmove(void *dest, const void *src, ssize_t len);
++void *__hwasan_memcpy(void *dest, const void *src, ssize_t len);
+-void kasan_tag_mismatch(unsigned long addr, unsigned long access_info,
++void kasan_tag_mismatch(void *addr, unsigned long access_info,
+                       unsigned long ret_ip);
+ #endif /* __MM_KASAN_KASAN_H */
+--- a/mm/kasan/report.c
++++ b/mm/kasan/report.c
+@@ -211,7 +211,7 @@ static void start_report(unsigned long *
+       pr_err("==================================================================\n");
+ }
+-static void end_report(unsigned long *flags, void *addr)
++static void end_report(unsigned long *flags, const void *addr)
+ {
+       if (addr)
+               trace_error_report_end(ERROR_DETECTOR_KASAN,
+@@ -450,8 +450,8 @@ static void print_memory_metadata(const
+ static void print_report(struct kasan_report_info *info)
+ {
+-      void *addr = kasan_reset_tag(info->access_addr);
+-      u8 tag = get_tag(info->access_addr);
++      void *addr = kasan_reset_tag((void *)info->access_addr);
++      u8 tag = get_tag((void *)info->access_addr);
+       print_error_description(info);
+       if (addr_has_metadata(addr))
+@@ -468,12 +468,12 @@ static void print_report(struct kasan_re
+ static void complete_report_info(struct kasan_report_info *info)
+ {
+-      void *addr = kasan_reset_tag(info->access_addr);
++      void *addr = kasan_reset_tag((void *)info->access_addr);
+       struct slab *slab;
+       if (info->type == KASAN_REPORT_ACCESS)
+               info->first_bad_addr = kasan_find_first_bad_addr(
+-                                      info->access_addr, info->access_size);
++                                      (void *)info->access_addr, info->access_size);
+       else
+               info->first_bad_addr = addr;
+@@ -544,11 +544,10 @@ void kasan_report_invalid_free(void *ptr
+  * user_access_save/restore(): kasan_report_invalid_free() cannot be called
+  * from a UACCESS region, and kasan_report_async() is not used on x86.
+  */
+-bool kasan_report(unsigned long addr, size_t size, bool is_write,
++bool kasan_report(const void *addr, size_t size, bool is_write,
+                       unsigned long ip)
+ {
+       bool ret = true;
+-      void *ptr = (void *)addr;
+       unsigned long ua_flags = user_access_save();
+       unsigned long irq_flags;
+       struct kasan_report_info info;
+@@ -562,7 +561,7 @@ bool kasan_report(unsigned long addr, si
+       memset(&info, 0, sizeof(info));
+       info.type = KASAN_REPORT_ACCESS;
+-      info.access_addr = ptr;
++      info.access_addr = addr;
+       info.access_size = size;
+       info.is_write = is_write;
+       info.ip = ip;
+@@ -571,7 +570,7 @@ bool kasan_report(unsigned long addr, si
+       print_report(&info);
+-      end_report(&irq_flags, ptr);
++      end_report(&irq_flags, (void *)addr);
+ out:
+       user_access_restore(ua_flags);
+--- a/mm/kasan/report_generic.c
++++ b/mm/kasan/report_generic.c
+@@ -30,9 +30,9 @@
+ #include "kasan.h"
+ #include "../slab.h"
+-void *kasan_find_first_bad_addr(void *addr, size_t size)
++const void *kasan_find_first_bad_addr(const void *addr, size_t size)
+ {
+-      void *p = addr;
++      const void *p = addr;
+       if (!addr_has_metadata(p))
+               return p;
+@@ -362,14 +362,14 @@ void kasan_print_address_stack_frame(con
+ #endif /* CONFIG_KASAN_STACK */
+ #define DEFINE_ASAN_REPORT_LOAD(size)                     \
+-void __asan_report_load##size##_noabort(unsigned long addr) \
++void __asan_report_load##size##_noabort(void *addr) \
+ {                                                         \
+       kasan_report(addr, size, false, _RET_IP_);        \
+ }                                                         \
+ EXPORT_SYMBOL(__asan_report_load##size##_noabort)
+ #define DEFINE_ASAN_REPORT_STORE(size)                     \
+-void __asan_report_store##size##_noabort(unsigned long addr) \
++void __asan_report_store##size##_noabort(void *addr) \
+ {                                                          \
+       kasan_report(addr, size, true, _RET_IP_);          \
+ }                                                          \
+@@ -386,13 +386,13 @@ DEFINE_ASAN_REPORT_STORE(4);
+ DEFINE_ASAN_REPORT_STORE(8);
+ DEFINE_ASAN_REPORT_STORE(16);
+-void __asan_report_load_n_noabort(unsigned long addr, size_t size)
++void __asan_report_load_n_noabort(void *addr, ssize_t size)
+ {
+       kasan_report(addr, size, false, _RET_IP_);
+ }
+ EXPORT_SYMBOL(__asan_report_load_n_noabort);
+-void __asan_report_store_n_noabort(unsigned long addr, size_t size)
++void __asan_report_store_n_noabort(void *addr, ssize_t size)
+ {
+       kasan_report(addr, size, true, _RET_IP_);
+ }
+--- a/mm/kasan/report_hw_tags.c
++++ b/mm/kasan/report_hw_tags.c
+@@ -15,7 +15,7 @@
+ #include "kasan.h"
+-void *kasan_find_first_bad_addr(void *addr, size_t size)
++const void *kasan_find_first_bad_addr(const void *addr, size_t size)
+ {
+       /*
+        * Hardware Tag-Based KASAN only calls this function for normal memory
+--- a/mm/kasan/report_sw_tags.c
++++ b/mm/kasan/report_sw_tags.c
+@@ -30,7 +30,7 @@
+ #include "kasan.h"
+ #include "../slab.h"
+-void *kasan_find_first_bad_addr(void *addr, size_t size)
++const void *kasan_find_first_bad_addr(const void *addr, size_t size)
+ {
+       u8 tag = get_tag(addr);
+       void *p = kasan_reset_tag(addr);
+--- a/mm/kasan/shadow.c
++++ b/mm/kasan/shadow.c
+@@ -28,13 +28,13 @@
+ bool __kasan_check_read(const volatile void *p, unsigned int size)
+ {
+-      return kasan_check_range((unsigned long)p, size, false, _RET_IP_);
++      return kasan_check_range((void *)p, size, false, _RET_IP_);
+ }
+ EXPORT_SYMBOL(__kasan_check_read);
+ bool __kasan_check_write(const volatile void *p, unsigned int size)
+ {
+-      return kasan_check_range((unsigned long)p, size, true, _RET_IP_);
++      return kasan_check_range((void *)p, size, true, _RET_IP_);
+ }
+ EXPORT_SYMBOL(__kasan_check_write);
+@@ -50,7 +50,7 @@ EXPORT_SYMBOL(__kasan_check_write);
+ #undef memset
+ void *memset(void *addr, int c, size_t len)
+ {
+-      if (!kasan_check_range((unsigned long)addr, len, true, _RET_IP_))
++      if (!kasan_check_range(addr, len, true, _RET_IP_))
+               return NULL;
+       return __memset(addr, c, len);
+@@ -60,8 +60,8 @@ void *memset(void *addr, int c, size_t l
+ #undef memmove
+ void *memmove(void *dest, const void *src, size_t len)
+ {
+-      if (!kasan_check_range((unsigned long)src, len, false, _RET_IP_) ||
+-          !kasan_check_range((unsigned long)dest, len, true, _RET_IP_))
++      if (!kasan_check_range(src, len, false, _RET_IP_) ||
++          !kasan_check_range(dest, len, true, _RET_IP_))
+               return NULL;
+       return __memmove(dest, src, len);
+@@ -71,17 +71,17 @@ void *memmove(void *dest, const void *sr
+ #undef memcpy
+ void *memcpy(void *dest, const void *src, size_t len)
+ {
+-      if (!kasan_check_range((unsigned long)src, len, false, _RET_IP_) ||
+-          !kasan_check_range((unsigned long)dest, len, true, _RET_IP_))
++      if (!kasan_check_range(src, len, false, _RET_IP_) ||
++          !kasan_check_range(dest, len, true, _RET_IP_))
+               return NULL;
+       return __memcpy(dest, src, len);
+ }
+ #endif
+-void *__asan_memset(void *addr, int c, size_t len)
++void *__asan_memset(void *addr, int c, ssize_t len)
+ {
+-      if (!kasan_check_range((unsigned long)addr, len, true, _RET_IP_))
++      if (!kasan_check_range(addr, len, true, _RET_IP_))
+               return NULL;
+       return __memset(addr, c, len);
+@@ -89,10 +89,10 @@ void *__asan_memset(void *addr, int c, s
+ EXPORT_SYMBOL(__asan_memset);
+ #ifdef __HAVE_ARCH_MEMMOVE
+-void *__asan_memmove(void *dest, const void *src, size_t len)
++void *__asan_memmove(void *dest, const void *src, ssize_t len)
+ {
+-      if (!kasan_check_range((unsigned long)src, len, false, _RET_IP_) ||
+-          !kasan_check_range((unsigned long)dest, len, true, _RET_IP_))
++      if (!kasan_check_range(src, len, false, _RET_IP_) ||
++          !kasan_check_range(dest, len, true, _RET_IP_))
+               return NULL;
+       return __memmove(dest, src, len);
+@@ -100,10 +100,10 @@ void *__asan_memmove(void *dest, const v
+ EXPORT_SYMBOL(__asan_memmove);
+ #endif
+-void *__asan_memcpy(void *dest, const void *src, size_t len)
++void *__asan_memcpy(void *dest, const void *src, ssize_t len)
+ {
+-      if (!kasan_check_range((unsigned long)src, len, false, _RET_IP_) ||
+-          !kasan_check_range((unsigned long)dest, len, true, _RET_IP_))
++      if (!kasan_check_range(src, len, false, _RET_IP_) ||
++          !kasan_check_range(dest, len, true, _RET_IP_))
+               return NULL;
+       return __memcpy(dest, src, len);
+@@ -111,13 +111,13 @@ void *__asan_memcpy(void *dest, const vo
+ EXPORT_SYMBOL(__asan_memcpy);
+ #ifdef CONFIG_KASAN_SW_TAGS
+-void *__hwasan_memset(void *addr, int c, size_t len) __alias(__asan_memset);
++void *__hwasan_memset(void *addr, int c, ssize_t len) __alias(__asan_memset);
+ EXPORT_SYMBOL(__hwasan_memset);
+ #ifdef __HAVE_ARCH_MEMMOVE
+-void *__hwasan_memmove(void *dest, const void *src, size_t len) __alias(__asan_memmove);
++void *__hwasan_memmove(void *dest, const void *src, ssize_t len) __alias(__asan_memmove);
+ EXPORT_SYMBOL(__hwasan_memmove);
+ #endif
+-void *__hwasan_memcpy(void *dest, const void *src, size_t len) __alias(__asan_memcpy);
++void *__hwasan_memcpy(void *dest, const void *src, ssize_t len) __alias(__asan_memcpy);
+ EXPORT_SYMBOL(__hwasan_memcpy);
+ #endif
+--- a/mm/kasan/sw_tags.c
++++ b/mm/kasan/sw_tags.c
+@@ -70,8 +70,8 @@ u8 kasan_random_tag(void)
+       return (u8)(state % (KASAN_TAG_MAX + 1));
+ }
+-bool kasan_check_range(unsigned long addr, size_t size, bool write,
+-                              unsigned long ret_ip)
++bool kasan_check_range(const void *addr, size_t size, bool write,
++                      unsigned long ret_ip)
+ {
+       u8 tag;
+       u8 *shadow_first, *shadow_last, *shadow;
+@@ -133,12 +133,12 @@ bool kasan_byte_accessible(const void *a
+ }
+ #define DEFINE_HWASAN_LOAD_STORE(size)                                        \
+-      void __hwasan_load##size##_noabort(unsigned long addr)          \
++      void __hwasan_load##size##_noabort(void *addr)                  \
+       {                                                               \
+-              kasan_check_range(addr, size, false, _RET_IP_); \
++              kasan_check_range(addr, size, false, _RET_IP_);         \
+       }                                                               \
+       EXPORT_SYMBOL(__hwasan_load##size##_noabort);                   \
+-      void __hwasan_store##size##_noabort(unsigned long addr)         \
++      void __hwasan_store##size##_noabort(void *addr)                 \
+       {                                                               \
+               kasan_check_range(addr, size, true, _RET_IP_);          \
+       }                                                               \
+@@ -150,25 +150,25 @@ DEFINE_HWASAN_LOAD_STORE(4);
+ DEFINE_HWASAN_LOAD_STORE(8);
+ DEFINE_HWASAN_LOAD_STORE(16);
+-void __hwasan_loadN_noabort(unsigned long addr, unsigned long size)
++void __hwasan_loadN_noabort(void *addr, ssize_t size)
+ {
+       kasan_check_range(addr, size, false, _RET_IP_);
+ }
+ EXPORT_SYMBOL(__hwasan_loadN_noabort);
+-void __hwasan_storeN_noabort(unsigned long addr, unsigned long size)
++void __hwasan_storeN_noabort(void *addr, ssize_t size)
+ {
+       kasan_check_range(addr, size, true, _RET_IP_);
+ }
+ EXPORT_SYMBOL(__hwasan_storeN_noabort);
+-void __hwasan_tag_memory(unsigned long addr, u8 tag, unsigned long size)
++void __hwasan_tag_memory(void *addr, u8 tag, ssize_t size)
+ {
+-      kasan_poison((void *)addr, size, tag, false);
++      kasan_poison(addr, size, tag, false);
+ }
+ EXPORT_SYMBOL(__hwasan_tag_memory);
+-void kasan_tag_mismatch(unsigned long addr, unsigned long access_info,
++void kasan_tag_mismatch(void *addr, unsigned long access_info,
+                       unsigned long ret_ip)
+ {
+       kasan_report(addr, 1 << (access_info & 0xf), access_info & 0x10,
diff --git a/queue-6.4/kbuild-make-modules_install-copy-modules.builtin-.modinfo.patch b/queue-6.4/kbuild-make-modules_install-copy-modules.builtin-.modinfo.patch
new file mode 100644 (file)
index 0000000..bb393b1
--- /dev/null
@@ -0,0 +1,104 @@
+From 8ae071fc216a25f4f797f33c56857f4dd6b4408e Mon Sep 17 00:00:00 2001
+From: Masahiro Yamada <masahiroy@kernel.org>
+Date: Thu, 15 Jun 2023 20:17:43 +0900
+Subject: kbuild: make modules_install copy modules.builtin(.modinfo)
+
+From: Masahiro Yamada <masahiroy@kernel.org>
+
+commit 8ae071fc216a25f4f797f33c56857f4dd6b4408e upstream.
+
+Josh Triplett reports that initramfs-tools needs modules.builtin and
+modules.builtin.modinfo to create a working initramfs for a non-modular
+kernel.
+
+If this is a general tooling issue not limited to Debian, I think it
+makes sense to change modules_install.
+
+This commit changes the targets as follows when CONFIG_MODULES=n.
+
+In-tree builds:
+  make modules          -> no-op
+  make modules_install  -> install modules.builtin(.modinfo)
+
+External module builds:
+  make modules          -> show error message like before
+  make modules_install  -> show error message like before
+
+Link: https://lore.kernel.org/lkml/36a4014c73a52af27d930d3ca31d362b60f4461c.1686356364.git.josh@joshtriplett.org/
+Reported-by: Josh Triplett <josh@joshtriplett.org>
+Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
+Reviewed-by: Nicolas Schier <nicolas@fjasle.eu>
+Tested-by: Nicolas Schier <nicolas@fjasle.eu>
+Reviewed-by: Josh Triplett <josh@joshtriplett.org>
+Tested-by: Josh Triplett <josh@joshtriplett.org>
+Stable-dep-of: 4243afdb9326 ("kbuild: builddeb: always make modules_install, to install modules.builtin*")
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ Makefile |   26 ++++++++++++++++----------
+ 1 file changed, 16 insertions(+), 10 deletions(-)
+
+--- a/Makefile
++++ b/Makefile
+@@ -1561,6 +1561,8 @@ modules_sign_only := y
+ endif
+ endif
++endif # CONFIG_MODULES
++
+ modinst_pre :=
+ ifneq ($(filter modules_install,$(MAKECMDGOALS)),)
+ modinst_pre := __modinst_pre
+@@ -1571,18 +1573,18 @@ PHONY += __modinst_pre
+ __modinst_pre:
+       @rm -rf $(MODLIB)/kernel
+       @rm -f $(MODLIB)/source
+-      @mkdir -p $(MODLIB)/kernel
++      @mkdir -p $(MODLIB)
++ifdef CONFIG_MODULES
+       @ln -s $(abspath $(srctree)) $(MODLIB)/source
+       @if [ ! $(objtree) -ef  $(MODLIB)/build ]; then \
+               rm -f $(MODLIB)/build ; \
+               ln -s $(CURDIR) $(MODLIB)/build ; \
+       fi
+       @sed 's:^\(.*\)\.o$$:kernel/\1.ko:' modules.order > $(MODLIB)/modules.order
++endif
+       @cp -f modules.builtin $(MODLIB)/
+       @cp -f $(objtree)/modules.builtin.modinfo $(MODLIB)/
+-endif # CONFIG_MODULES
+-
+ ###
+ # Cleaning is done on three levels.
+ # make clean     Delete most generated files
+@@ -1924,6 +1926,13 @@ help:
+       @echo  '  clean           - remove generated files in module directory only'
+       @echo  ''
++__external_modules_error:
++      @echo >&2 '***'
++      @echo >&2 '*** The present kernel disabled CONFIG_MODULES.'
++      @echo >&2 '*** You cannot build or install external modules.'
++      @echo >&2 '***'
++      @false
++
+ endif # KBUILD_EXTMOD
+ # ---------------------------------------------------------------------------
+@@ -1960,13 +1969,10 @@ else # CONFIG_MODULES
+ # Modules not configured
+ # ---------------------------------------------------------------------------
+-modules modules_install:
+-      @echo >&2 '***'
+-      @echo >&2 '*** The present kernel configuration has modules disabled.'
+-      @echo >&2 '*** To use the module feature, please run "make menuconfig" etc.'
+-      @echo >&2 '*** to enable CONFIG_MODULES.'
+-      @echo >&2 '***'
+-      @exit 1
++PHONY += __external_modules_error
++
++modules modules_install: __external_modules_error
++      @:
+ KBUILD_MODULES :=
diff --git a/queue-6.4/mtd-rawnand-meson-fix-unaligned-dma-buffers-handling.patch b/queue-6.4/mtd-rawnand-meson-fix-unaligned-dma-buffers-handling.patch
new file mode 100644 (file)
index 0000000..51761fb
--- /dev/null
@@ -0,0 +1,44 @@
+From 98480a181a08ceeede417e5b28f6d0429d8ae156 Mon Sep 17 00:00:00 2001
+From: Arseniy Krasnov <AVKrasnov@sberdevices.ru>
+Date: Thu, 15 Jun 2023 11:08:15 +0300
+Subject: mtd: rawnand: meson: fix unaligned DMA buffers handling
+
+From: Arseniy Krasnov <AVKrasnov@sberdevices.ru>
+
+commit 98480a181a08ceeede417e5b28f6d0429d8ae156 upstream.
+
+Meson NAND controller requires 8 bytes alignment for DMA addresses,
+otherwise it "aligns" passed address by itself thus accessing invalid
+location in the provided buffer. This patch makes unaligned buffers to
+be reallocated to become valid.
+
+Fixes: 8fae856c5350 ("mtd: rawnand: meson: add support for Amlogic NAND flash controller")
+Cc: <Stable@vger.kernel.org>
+Signed-off-by: Arseniy Krasnov <AVKrasnov@sberdevices.ru>
+Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Link: https://lore.kernel.org/linux-mtd/20230615080815.3291006-1-AVKrasnov@sberdevices.ru
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/mtd/nand/raw/meson_nand.c |    4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/drivers/mtd/nand/raw/meson_nand.c
++++ b/drivers/mtd/nand/raw/meson_nand.c
+@@ -76,6 +76,7 @@
+ #define GENCMDIADDRH(aih, addr)               ((aih) | (((addr) >> 16) & 0xffff))
+ #define DMA_DIR(dir)          ((dir) ? NFC_CMD_N2M : NFC_CMD_M2N)
++#define DMA_ADDR_ALIGN                8
+ #define ECC_CHECK_RETURN_FF   (-1)
+@@ -842,6 +843,9 @@ static int meson_nfc_read_oob(struct nan
+ static bool meson_nfc_is_buffer_dma_safe(const void *buffer)
+ {
++      if ((uintptr_t)buffer % DMA_ADDR_ALIGN)
++              return false;
++
+       if (virt_addr_valid(buffer) && (!object_is_on_stack(buffer)))
+               return true;
+       return false;
diff --git a/queue-6.4/net-bcmgenet-ensure-mdio-unregistration-has-clocks-enabled.patch b/queue-6.4/net-bcmgenet-ensure-mdio-unregistration-has-clocks-enabled.patch
new file mode 100644 (file)
index 0000000..b59f808
--- /dev/null
@@ -0,0 +1,39 @@
+From 1b5ea7ffb7a3bdfffb4b7f40ce0d20a3372ee405 Mon Sep 17 00:00:00 2001
+From: Florian Fainelli <florian.fainelli@broadcom.com>
+Date: Thu, 22 Jun 2023 03:31:07 -0700
+Subject: net: bcmgenet: Ensure MDIO unregistration has clocks enabled
+
+From: Florian Fainelli <florian.fainelli@broadcom.com>
+
+commit 1b5ea7ffb7a3bdfffb4b7f40ce0d20a3372ee405 upstream.
+
+With support for Ethernet PHY LEDs having been added, while
+unregistering a MDIO bus and its child device liks PHYs there may be
+"late" accesses to the MDIO bus. One typical use case is setting the PHY
+LEDs brightness to OFF for instance.
+
+We need to ensure that the MDIO bus controller remains entirely
+functional since it runs off the main GENET adapter clock.
+
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/all/20230617155500.4005881-1-andrew@lunn.ch/
+Fixes: 9a4e79697009 ("net: bcmgenet: utilize generic Broadcom UniMAC MDIO controller driver")
+Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Link: https://lore.kernel.org/r/20230622103107.1760280-1-florian.fainelli@broadcom.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/broadcom/genet/bcmmii.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/net/ethernet/broadcom/genet/bcmmii.c
++++ b/drivers/net/ethernet/broadcom/genet/bcmmii.c
+@@ -673,5 +673,7 @@ void bcmgenet_mii_exit(struct net_device
+       if (of_phy_is_fixed_link(dn))
+               of_phy_deregister_fixed_link(dn);
+       of_node_put(priv->phy_dn);
++      clk_prepare_enable(priv->clk);
+       platform_device_unregister(priv->mii_pdev);
++      clk_disable_unprepare(priv->clk);
+ }
diff --git a/queue-6.4/net-phy-dp83td510-fix-kernel-stall-during-netboot-in-dp83td510e-phy-driver.patch b/queue-6.4/net-phy-dp83td510-fix-kernel-stall-during-netboot-in-dp83td510e-phy-driver.patch
new file mode 100644 (file)
index 0000000..49c0dfc
--- /dev/null
@@ -0,0 +1,99 @@
+From fc0649395dca81f2b3b02d9b248acb38cbcee55c Mon Sep 17 00:00:00 2001
+From: Oleksij Rempel <o.rempel@pengutronix.de>
+Date: Wed, 21 Jun 2023 06:38:48 +0200
+Subject: net: phy: dp83td510: fix kernel stall during netboot in DP83TD510E PHY driver
+
+From: Oleksij Rempel <o.rempel@pengutronix.de>
+
+commit fc0649395dca81f2b3b02d9b248acb38cbcee55c upstream.
+
+Fix an issue where the kernel would stall during netboot, showing the
+"sched: RT throttling activated" message. This stall was triggered by
+the behavior of the mii_interrupt bit (Bit 7 - DP83TD510E_STS_MII_INT)
+in the DP83TD510E's PHY_STS Register (Address = 0x10). The DP83TD510E
+datasheet (2020) states that the bit clears on write, however, in
+practice, the bit clears on read.
+
+This discrepancy had significant implications on the driver's interrupt
+handling. The PHY_STS Register was used by handle_interrupt() to check
+for pending interrupts and by read_status() to get the current link
+status. The call to read_status() was unintentionally clearing the
+mii_interrupt status bit without deasserting the IRQ pin, causing
+handle_interrupt() to miss other pending interrupts. This issue was most
+apparent during netboot.
+
+The fix refrains from using the PHY_STS Register for interrupt handling.
+Instead, we now solely rely on the INTERRUPT_REG_1 Register (Address =
+0x12) and INTERRUPT_REG_2 Register (Address = 0x13) for this purpose.
+These registers directly influence the IRQ pin state and are latched
+high until read.
+
+Note: The INTERRUPT_REG_2 Register (Address = 0x13) exists and can also
+be used for interrupt handling, specifically for "Aneg page received
+interrupt" and "Polarity change interrupt". However, these features are
+currently not supported by this driver.
+
+Fixes: 165cd04fe253 ("net: phy: dp83td510: Add support for the DP83TD510 Ethernet PHY")
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Link: https://lore.kernel.org/r/20230621043848.3806124-1-o.rempel@pengutronix.de
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/phy/dp83td510.c |   23 +++++------------------
+ 1 file changed, 5 insertions(+), 18 deletions(-)
+
+--- a/drivers/net/phy/dp83td510.c
++++ b/drivers/net/phy/dp83td510.c
+@@ -12,6 +12,11 @@
+ /* MDIO_MMD_VEND2 registers */
+ #define DP83TD510E_PHY_STS                    0x10
++/* Bit 7 - mii_interrupt, active high. Clears on read.
++ * Note: Clearing does not necessarily deactivate IRQ pin if interrupts pending.
++ * This differs from the DP83TD510E datasheet (2020) which states this bit
++ * clears on write 0.
++ */
+ #define DP83TD510E_STS_MII_INT                        BIT(7)
+ #define DP83TD510E_LINK_STATUS                        BIT(0)
+@@ -53,12 +58,6 @@ static int dp83td510_config_intr(struct
+       int ret;
+       if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
+-              /* Clear any pending interrupts */
+-              ret = phy_write_mmd(phydev, MDIO_MMD_VEND2, DP83TD510E_PHY_STS,
+-                                  0x0);
+-              if (ret)
+-                      return ret;
+-
+               ret = phy_write_mmd(phydev, MDIO_MMD_VEND2,
+                                   DP83TD510E_INTERRUPT_REG_1,
+                                   DP83TD510E_INT1_LINK_EN);
+@@ -81,10 +80,6 @@ static int dp83td510_config_intr(struct
+                                        DP83TD510E_GENCFG_INT_EN);
+               if (ret)
+                       return ret;
+-
+-              /* Clear any pending interrupts */
+-              ret = phy_write_mmd(phydev, MDIO_MMD_VEND2, DP83TD510E_PHY_STS,
+-                                  0x0);
+       }
+       return ret;
+@@ -94,14 +89,6 @@ static irqreturn_t dp83td510_handle_inte
+ {
+       int  ret;
+-      ret = phy_read_mmd(phydev, MDIO_MMD_VEND2, DP83TD510E_PHY_STS);
+-      if (ret < 0) {
+-              phy_error(phydev);
+-              return IRQ_NONE;
+-      } else if (!(ret & DP83TD510E_STS_MII_INT)) {
+-              return IRQ_NONE;
+-      }
+-
+       /* Read the current enabled interrupts */
+       ret = phy_read_mmd(phydev, MDIO_MMD_VEND2, DP83TD510E_INTERRUPT_REG_1);
+       if (ret < 0) {
diff --git a/queue-6.4/pinctrl-amd-detect-and-mask-spurious-interrupts.patch b/queue-6.4/pinctrl-amd-detect-and-mask-spurious-interrupts.patch
new file mode 100644 (file)
index 0000000..e860ab1
--- /dev/null
@@ -0,0 +1,62 @@
+From 0cf9e48ff22e15f3f0882991f33d23ccc5ae1d01 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Kornel=20Dul=C4=99ba?= <korneld@chromium.org>
+Date: Fri, 21 Apr 2023 07:06:23 -0500
+Subject: pinctrl: amd: Detect and mask spurious interrupts
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Kornel DulÄ™ba <korneld@chromium.org>
+
+commit 0cf9e48ff22e15f3f0882991f33d23ccc5ae1d01 upstream.
+
+Leverage gpiochip_line_is_irq to check whether a pin has an irq
+associated with it. The previous check ("irq == 0") didn't make much
+sense. The irq variable refers to the pinctrl irq, and has nothing do to
+with an individual pin.
+
+On some systems, during suspend/resume cycle, the firmware leaves
+an interrupt enabled on a pin that is not used by the kernel.
+Without this patch that caused an interrupt storm.
+
+Cc: stable@vger.kernel.org
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=217315
+Signed-off-by: Kornel DulÄ™ba <korneld@chromium.org>
+Reviewed-by: Mario Limonciello <mario.limonciello@amd.com>
+Link: https://lore.kernel.org/r/20230421120625.3366-4-mario.limonciello@amd.com
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/pinctrl/pinctrl-amd.c |   12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+--- a/drivers/pinctrl/pinctrl-amd.c
++++ b/drivers/pinctrl/pinctrl-amd.c
+@@ -660,21 +660,21 @@ static bool do_amd_gpio_irq_handler(int
+                        * We must read the pin register again, in case the
+                        * value was changed while executing
+                        * generic_handle_domain_irq() above.
+-                       * If we didn't find a mapping for the interrupt,
+-                       * disable it in order to avoid a system hang caused
+-                       * by an interrupt storm.
++                       * If the line is not an irq, disable it in order to
++                       * avoid a system hang caused by an interrupt storm.
+                        */
+                       raw_spin_lock_irqsave(&gpio_dev->lock, flags);
+                       regval = readl(regs + i);
+-                      if (irq == 0) {
+-                              regval &= ~BIT(INTERRUPT_ENABLE_OFF);
++                      if (!gpiochip_line_is_irq(gc, irqnr + i)) {
++                              regval &= ~BIT(INTERRUPT_MASK_OFF);
+                               dev_dbg(&gpio_dev->pdev->dev,
+                                       "Disabling spurious GPIO IRQ %d\n",
+                                       irqnr + i);
++                      } else {
++                              ret = true;
+                       }
+                       writel(regval, regs + i);
+                       raw_spin_unlock_irqrestore(&gpio_dev->lock, flags);
+-                      ret = true;
+               }
+       }
+       /* did not cause wake on resume context for shared IRQ */
diff --git a/queue-6.4/pinctrl-amd-detect-internal-gpio0-debounce-handling.patch b/queue-6.4/pinctrl-amd-detect-internal-gpio0-debounce-handling.patch
new file mode 100644 (file)
index 0000000..7a3f970
--- /dev/null
@@ -0,0 +1,77 @@
+From 968ab9261627fa305307e3935ca1a32fcddd36cb Mon Sep 17 00:00:00 2001
+From: Mario Limonciello <mario.limonciello@amd.com>
+Date: Fri, 21 Apr 2023 07:06:21 -0500
+Subject: pinctrl: amd: Detect internal GPIO0 debounce handling
+
+From: Mario Limonciello <mario.limonciello@amd.com>
+
+commit 968ab9261627fa305307e3935ca1a32fcddd36cb upstream.
+
+commit 4e5a04be88fe ("pinctrl: amd: disable and mask interrupts on probe")
+had a mistake in loop iteration 63 that it would clear offset 0xFC instead
+of 0x100.  Offset 0xFC is actually `WAKE_INT_MASTER_REG`.  This was
+clearing bits 13 and 15 from the register which significantly changed the
+expected handling for some platforms for GPIO0.
+
+commit b26cd9325be4 ("pinctrl: amd: Disable and mask interrupts on resume")
+actually fixed this bug, but lead to regressions on Lenovo Z13 and some
+other systems.  This is because there was no handling in the driver for bit
+15 debounce behavior.
+
+Quoting a public BKDG:
+```
+EnWinBlueBtn. Read-write. Reset: 0. 0=GPIO0 detect debounced power button;
+Power button override is 4 seconds. 1=GPIO0 detect debounced power button
+in S3/S5/S0i3, and detect "pressed less than 2 seconds" and "pressed 2~10
+seconds" in S0; Power button override is 10 seconds
+```
+
+Cross referencing the same master register in Windows it's obvious that
+Windows doesn't use debounce values in this configuration.  So align the
+Linux driver to do this as well.  This fixes wake on lid when
+WAKE_INT_MASTER_REG is properly programmed.
+
+Cc: stable@vger.kernel.org
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=217315
+Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
+Link: https://lore.kernel.org/r/20230421120625.3366-2-mario.limonciello@amd.com
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/pinctrl/pinctrl-amd.c |    7 +++++++
+ drivers/pinctrl/pinctrl-amd.h |    1 +
+ 2 files changed, 8 insertions(+)
+
+--- a/drivers/pinctrl/pinctrl-amd.c
++++ b/drivers/pinctrl/pinctrl-amd.c
+@@ -125,6 +125,12 @@ static int amd_gpio_set_debounce(struct
+       struct amd_gpio *gpio_dev = gpiochip_get_data(gc);
+       raw_spin_lock_irqsave(&gpio_dev->lock, flags);
++
++      /* Use special handling for Pin0 debounce */
++      pin_reg = readl(gpio_dev->base + WAKE_INT_MASTER_REG);
++      if (pin_reg & INTERNAL_GPIO0_DEBOUNCE)
++              debounce = 0;
++
+       pin_reg = readl(gpio_dev->base + offset * 4);
+       if (debounce) {
+@@ -219,6 +225,7 @@ static void amd_gpio_dbg_show(struct seq
+       char *debounce_enable;
+       char *wake_cntrlz;
++      seq_printf(s, "WAKE_INT_MASTER_REG: 0x%08x\n", readl(gpio_dev->base + WAKE_INT_MASTER_REG));
+       for (bank = 0; bank < gpio_dev->hwbank_num; bank++) {
+               unsigned int time = 0;
+               unsigned int unit = 0;
+--- a/drivers/pinctrl/pinctrl-amd.h
++++ b/drivers/pinctrl/pinctrl-amd.h
+@@ -17,6 +17,7 @@
+ #define AMD_GPIO_PINS_BANK3     32
+ #define WAKE_INT_MASTER_REG 0xfc
++#define INTERNAL_GPIO0_DEBOUNCE (1 << 15)
+ #define EOI_MASK (1 << 29)
+ #define WAKE_INT_STATUS_REG0 0x2f8
diff --git a/queue-6.4/pinctrl-amd-drop-pull-up-select-configuration.patch b/queue-6.4/pinctrl-amd-drop-pull-up-select-configuration.patch
new file mode 100644 (file)
index 0000000..4d1b89b
--- /dev/null
@@ -0,0 +1,86 @@
+From 3f62312d04d4c68aace9cd06fc135e09573325f3 Mon Sep 17 00:00:00 2001
+From: Mario Limonciello <mario.limonciello@amd.com>
+Date: Wed, 5 Jul 2023 08:30:04 -0500
+Subject: pinctrl: amd: Drop pull up select configuration
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Mario Limonciello <mario.limonciello@amd.com>
+
+commit 3f62312d04d4c68aace9cd06fc135e09573325f3 upstream.
+
+pinctrl-amd currently tries to program bit 19 of all GPIOs to select
+either a 4kΩ or 8hΩ pull up, but this isn't what bit 19 does.  Bit
+19 is marked as reserved, even in the latest platforms documentation.
+
+Drop this programming functionality.
+
+Tested-by: Jan Visser <starquake@linuxeverywhere.org>
+Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
+Link: https://lore.kernel.org/r/20230705133005.577-4-mario.limonciello@amd.com
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/pinctrl/pinctrl-amd.c |   16 ++++------------
+ drivers/pinctrl/pinctrl-amd.h |    1 -
+ 2 files changed, 4 insertions(+), 13 deletions(-)
+
+--- a/drivers/pinctrl/pinctrl-amd.c
++++ b/drivers/pinctrl/pinctrl-amd.c
+@@ -209,7 +209,6 @@ static void amd_gpio_dbg_show(struct seq
+       char *pin_sts;
+       char *interrupt_sts;
+       char *wake_sts;
+-      char *pull_up_sel;
+       char *orientation;
+       char debounce_value[40];
+       char *debounce_enable;
+@@ -317,14 +316,9 @@ static void amd_gpio_dbg_show(struct seq
+                       seq_printf(s, "   %s|", wake_sts);
+                       if (pin_reg & BIT(PULL_UP_ENABLE_OFF)) {
+-                              if (pin_reg & BIT(PULL_UP_SEL_OFF))
+-                                      pull_up_sel = "8k";
+-                              else
+-                                      pull_up_sel = "4k";
+-                              seq_printf(s, "%s â†‘|",
+-                                         pull_up_sel);
++                              seq_puts(s, "  â†‘ |");
+                       } else if (pin_reg & BIT(PULL_DOWN_ENABLE_OFF)) {
+-                              seq_puts(s, "   â†“|");
++                              seq_puts(s, "  â†“ |");
+                       } else  {
+                               seq_puts(s, "    |");
+                       }
+@@ -751,7 +745,7 @@ static int amd_pinconf_get(struct pinctr
+               break;
+       case PIN_CONFIG_BIAS_PULL_UP:
+-              arg = (pin_reg >> PULL_UP_SEL_OFF) & (BIT(0) | BIT(1));
++              arg = (pin_reg >> PULL_UP_ENABLE_OFF) & BIT(0);
+               break;
+       case PIN_CONFIG_DRIVE_STRENGTH:
+@@ -798,10 +792,8 @@ static int amd_pinconf_set(struct pinctr
+                       break;
+               case PIN_CONFIG_BIAS_PULL_UP:
+-                      pin_reg &= ~BIT(PULL_UP_SEL_OFF);
+-                      pin_reg |= (arg & BIT(0)) << PULL_UP_SEL_OFF;
+                       pin_reg &= ~BIT(PULL_UP_ENABLE_OFF);
+-                      pin_reg |= ((arg>>1) & BIT(0)) << PULL_UP_ENABLE_OFF;
++                      pin_reg |= (arg & BIT(0)) << PULL_UP_ENABLE_OFF;
+                       break;
+               case PIN_CONFIG_DRIVE_STRENGTH:
+--- a/drivers/pinctrl/pinctrl-amd.h
++++ b/drivers/pinctrl/pinctrl-amd.h
+@@ -36,7 +36,6 @@
+ #define WAKE_CNTRL_OFF_S4               15
+ #define PIN_STS_OFF                   16
+ #define DRV_STRENGTH_SEL_OFF          17
+-#define PULL_UP_SEL_OFF                       19
+ #define PULL_UP_ENABLE_OFF            20
+ #define PULL_DOWN_ENABLE_OFF          21
+ #define OUTPUT_VALUE_OFF              22
diff --git a/queue-6.4/pinctrl-amd-fix-mistake-in-handling-clearing-pins-at-startup.patch b/queue-6.4/pinctrl-amd-fix-mistake-in-handling-clearing-pins-at-startup.patch
new file mode 100644 (file)
index 0000000..8f98b75
--- /dev/null
@@ -0,0 +1,39 @@
+From a855724dc08b8cb0c13ab1e065a4922f1e5a7552 Mon Sep 17 00:00:00 2001
+From: Mario Limonciello <mario.limonciello@amd.com>
+Date: Fri, 21 Apr 2023 07:06:22 -0500
+Subject: pinctrl: amd: Fix mistake in handling clearing pins at startup
+
+From: Mario Limonciello <mario.limonciello@amd.com>
+
+commit a855724dc08b8cb0c13ab1e065a4922f1e5a7552 upstream.
+
+commit 4e5a04be88fe ("pinctrl: amd: disable and mask interrupts on probe")
+had a mistake in loop iteration 63 that it would clear offset 0xFC instead
+of 0x100.  Offset 0xFC is actually `WAKE_INT_MASTER_REG`.  This was
+clearing bits 13 and 15 from the register which significantly changed the
+expected handling for some platforms for GPIO0.
+
+Cc: stable@vger.kernel.org
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=217315
+Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
+Link: https://lore.kernel.org/r/20230421120625.3366-3-mario.limonciello@amd.com
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/pinctrl/pinctrl-amd.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/pinctrl/pinctrl-amd.c
++++ b/drivers/pinctrl/pinctrl-amd.c
+@@ -897,9 +897,9 @@ static void amd_gpio_irq_init(struct amd
+               raw_spin_lock_irqsave(&gpio_dev->lock, flags);
+-              pin_reg = readl(gpio_dev->base + i * 4);
++              pin_reg = readl(gpio_dev->base + pin * 4);
+               pin_reg &= ~mask;
+-              writel(pin_reg, gpio_dev->base + i * 4);
++              writel(pin_reg, gpio_dev->base + pin * 4);
+               raw_spin_unlock_irqrestore(&gpio_dev->lock, flags);
+       }
diff --git a/queue-6.4/pinctrl-amd-only-use-special-debounce-behavior-for-gpio-0.patch b/queue-6.4/pinctrl-amd-only-use-special-debounce-behavior-for-gpio-0.patch
new file mode 100644 (file)
index 0000000..6364989
--- /dev/null
@@ -0,0 +1,40 @@
+From 0d5ace1a07f7e846d0f6d972af60d05515599d0b Mon Sep 17 00:00:00 2001
+From: Mario Limonciello <mario.limonciello@amd.com>
+Date: Wed, 5 Jul 2023 08:30:02 -0500
+Subject: pinctrl: amd: Only use special debounce behavior for GPIO 0
+
+From: Mario Limonciello <mario.limonciello@amd.com>
+
+commit 0d5ace1a07f7e846d0f6d972af60d05515599d0b upstream.
+
+It's uncommon to use debounce on any other pin, but technically
+we should only set debounce to 0 when working off GPIO0.
+
+Cc: stable@vger.kernel.org
+Tested-by: Jan Visser <starquake@linuxeverywhere.org>
+Fixes: 968ab9261627 ("pinctrl: amd: Detect internal GPIO0 debounce handling")
+Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
+Link: https://lore.kernel.org/r/20230705133005.577-2-mario.limonciello@amd.com
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/pinctrl/pinctrl-amd.c |    8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+--- a/drivers/pinctrl/pinctrl-amd.c
++++ b/drivers/pinctrl/pinctrl-amd.c
+@@ -127,9 +127,11 @@ static int amd_gpio_set_debounce(struct
+       raw_spin_lock_irqsave(&gpio_dev->lock, flags);
+       /* Use special handling for Pin0 debounce */
+-      pin_reg = readl(gpio_dev->base + WAKE_INT_MASTER_REG);
+-      if (pin_reg & INTERNAL_GPIO0_DEBOUNCE)
+-              debounce = 0;
++      if (offset == 0) {
++              pin_reg = readl(gpio_dev->base + WAKE_INT_MASTER_REG);
++              if (pin_reg & INTERNAL_GPIO0_DEBOUNCE)
++                      debounce = 0;
++      }
+       pin_reg = readl(gpio_dev->base + offset * 4);
diff --git a/queue-6.4/pinctrl-amd-revert-pinctrl-amd-disable-and-mask-interrupts-on-probe.patch b/queue-6.4/pinctrl-amd-revert-pinctrl-amd-disable-and-mask-interrupts-on-probe.patch
new file mode 100644 (file)
index 0000000..2966af5
--- /dev/null
@@ -0,0 +1,79 @@
+From 65f6c7c91cb2ebacbf155e0f881f81e79f90d138 Mon Sep 17 00:00:00 2001
+From: Mario Limonciello <mario.limonciello@amd.com>
+Date: Fri, 21 Apr 2023 07:06:24 -0500
+Subject: pinctrl: amd: Revert "pinctrl: amd: disable and mask interrupts on probe"
+
+From: Mario Limonciello <mario.limonciello@amd.com>
+
+commit 65f6c7c91cb2ebacbf155e0f881f81e79f90d138 upstream.
+
+commit 4e5a04be88fe ("pinctrl: amd: disable and mask interrupts on probe")
+was well intentioned to mask a firmware issue on a surface laptop, but it
+has a few problems:
+1. It had a bug in the loop handling for iteration 63 that lead to other
+   problems with GPIO0 handling.
+2. It disables interrupts that are used internally by the SOC but masked
+   by default.
+3. It masked a real firmware problem in some chromebooks that should have
+   been caught during development but wasn't.
+
+There has been a lot of other development around s2idle; particularly
+around handling of the spurious wakeups.  If there is still a problem on
+the original reported surface laptop it should be avoided by adding a quirk
+to gpiolib-acpi for that system instead.
+
+Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
+Link: https://lore.kernel.org/r/20230421120625.3366-5-mario.limonciello@amd.com
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/pinctrl/pinctrl-amd.c |   31 -------------------------------
+ 1 file changed, 31 deletions(-)
+
+--- a/drivers/pinctrl/pinctrl-amd.c
++++ b/drivers/pinctrl/pinctrl-amd.c
+@@ -877,34 +877,6 @@ static const struct pinconf_ops amd_pinc
+       .pin_config_group_set = amd_pinconf_group_set,
+ };
+-static void amd_gpio_irq_init(struct amd_gpio *gpio_dev)
+-{
+-      struct pinctrl_desc *desc = gpio_dev->pctrl->desc;
+-      unsigned long flags;
+-      u32 pin_reg, mask;
+-      int i;
+-
+-      mask = BIT(WAKE_CNTRL_OFF_S0I3) | BIT(WAKE_CNTRL_OFF_S3) |
+-              BIT(INTERRUPT_MASK_OFF) | BIT(INTERRUPT_ENABLE_OFF) |
+-              BIT(WAKE_CNTRL_OFF_S4);
+-
+-      for (i = 0; i < desc->npins; i++) {
+-              int pin = desc->pins[i].number;
+-              const struct pin_desc *pd = pin_desc_get(gpio_dev->pctrl, pin);
+-
+-              if (!pd)
+-                      continue;
+-
+-              raw_spin_lock_irqsave(&gpio_dev->lock, flags);
+-
+-              pin_reg = readl(gpio_dev->base + pin * 4);
+-              pin_reg &= ~mask;
+-              writel(pin_reg, gpio_dev->base + pin * 4);
+-
+-              raw_spin_unlock_irqrestore(&gpio_dev->lock, flags);
+-      }
+-}
+-
+ #ifdef CONFIG_PM_SLEEP
+ static bool amd_gpio_should_save(struct amd_gpio *gpio_dev, unsigned int pin)
+ {
+@@ -1142,9 +1114,6 @@ static int amd_gpio_probe(struct platfor
+               return PTR_ERR(gpio_dev->pctrl);
+       }
+-      /* Disable and mask interrupts */
+-      amd_gpio_irq_init(gpio_dev);
+-
+       girq = &gpio_dev->gc.irq;
+       gpio_irq_chip_set_chip(girq, &amd_gpio_irqchip);
+       /* This will let us handle the parent IRQ in the driver */
diff --git a/queue-6.4/pinctrl-amd-unify-debounce-handling-into-amd_pinconf_set.patch b/queue-6.4/pinctrl-amd-unify-debounce-handling-into-amd_pinconf_set.patch
new file mode 100644 (file)
index 0000000..4f9e8b6
--- /dev/null
@@ -0,0 +1,83 @@
+From 283c5ce7da0a676f46539094d40067ad17c4f294 Mon Sep 17 00:00:00 2001
+From: Mario Limonciello <mario.limonciello@amd.com>
+Date: Wed, 5 Jul 2023 08:30:05 -0500
+Subject: pinctrl: amd: Unify debounce handling into amd_pinconf_set()
+
+From: Mario Limonciello <mario.limonciello@amd.com>
+
+commit 283c5ce7da0a676f46539094d40067ad17c4f294 upstream.
+
+Debounce handling is done in two different entry points in the driver.
+Unify this to make sure that it's always handled the same.
+
+Tested-by: Jan Visser <starquake@linuxeverywhere.org>
+Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
+Link: https://lore.kernel.org/r/20230705133005.577-5-mario.limonciello@amd.com
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/pinctrl/pinctrl-amd.c |   21 +++++----------------
+ 1 file changed, 5 insertions(+), 16 deletions(-)
+
+--- a/drivers/pinctrl/pinctrl-amd.c
++++ b/drivers/pinctrl/pinctrl-amd.c
+@@ -115,16 +115,12 @@ static void amd_gpio_set_value(struct gp
+       raw_spin_unlock_irqrestore(&gpio_dev->lock, flags);
+ }
+-static int amd_gpio_set_debounce(struct gpio_chip *gc, unsigned offset,
+-              unsigned debounce)
++static int amd_gpio_set_debounce(struct amd_gpio *gpio_dev, unsigned int offset,
++                               unsigned int debounce)
+ {
+       u32 time;
+       u32 pin_reg;
+       int ret = 0;
+-      unsigned long flags;
+-      struct amd_gpio *gpio_dev = gpiochip_get_data(gc);
+-
+-      raw_spin_lock_irqsave(&gpio_dev->lock, flags);
+       /* Use special handling for Pin0 debounce */
+       if (offset == 0) {
+@@ -183,7 +179,6 @@ static int amd_gpio_set_debounce(struct
+               pin_reg &= ~(DB_CNTRl_MASK << DB_CNTRL_OFF);
+       }
+       writel(pin_reg, gpio_dev->base + offset * 4);
+-      raw_spin_unlock_irqrestore(&gpio_dev->lock, flags);
+       return ret;
+ }
+@@ -782,9 +777,8 @@ static int amd_pinconf_set(struct pinctr
+               switch (param) {
+               case PIN_CONFIG_INPUT_DEBOUNCE:
+-                      pin_reg &= ~DB_TMR_OUT_MASK;
+-                      pin_reg |= arg & DB_TMR_OUT_MASK;
+-                      break;
++                      ret = amd_gpio_set_debounce(gpio_dev, pin, arg);
++                      goto out_unlock;
+               case PIN_CONFIG_BIAS_PULL_DOWN:
+                       pin_reg &= ~BIT(PULL_DOWN_ENABLE_OFF);
+@@ -811,6 +805,7 @@ static int amd_pinconf_set(struct pinctr
+               writel(pin_reg, gpio_dev->base + pin*4);
+       }
++out_unlock:
+       raw_spin_unlock_irqrestore(&gpio_dev->lock, flags);
+       return ret;
+@@ -857,12 +852,6 @@ static int amd_gpio_set_config(struct gp
+ {
+       struct amd_gpio *gpio_dev = gpiochip_get_data(gc);
+-      if (pinconf_to_config_param(config) == PIN_CONFIG_INPUT_DEBOUNCE) {
+-              u32 debounce = pinconf_to_config_argument(config);
+-
+-              return amd_gpio_set_debounce(gc, pin, debounce);
+-      }
+-
+       return amd_pinconf_set(gpio_dev->pctrl, pin, &config, 1);
+ }
diff --git a/queue-6.4/pinctrl-amd-use-amd_pinconf_set-for-all-config-options.patch b/queue-6.4/pinctrl-amd-use-amd_pinconf_set-for-all-config-options.patch
new file mode 100644 (file)
index 0000000..84d4d25
--- /dev/null
@@ -0,0 +1,103 @@
+From 635a750d958e158e17af0f524bedc484b27fbb93 Mon Sep 17 00:00:00 2001
+From: Mario Limonciello <mario.limonciello@amd.com>
+Date: Wed, 5 Jul 2023 08:30:03 -0500
+Subject: pinctrl: amd: Use amd_pinconf_set() for all config options
+
+From: Mario Limonciello <mario.limonciello@amd.com>
+
+commit 635a750d958e158e17af0f524bedc484b27fbb93 upstream.
+
+On ASUS TUF A16 it is reported that the ITE5570 ACPI device connected to
+GPIO 7 is causing an interrupt storm.  This issue doesn't happen on
+Windows.
+
+Comparing the GPIO register configuration between Windows and Linux
+bit 20 has been configured as a pull up on Windows, but not on Linux.
+Checking GPIO declaration from the firmware it is clear it *should* have
+been a pull up on Linux as well.
+
+```
+GpioInt (Level, ActiveLow, Exclusive, PullUp, 0x0000,
+        "\\_SB.GPIO", 0x00, ResourceConsumer, ,)
+{   // Pin list
+0x0007
+}
+```
+
+On Linux amd_gpio_set_config() is currently only used for programming
+the debounce. Actually the GPIO core calls it with all the arguments
+that are supported by a GPIO, pinctrl-amd just responds `-ENOTSUPP`.
+
+To solve this issue expand amd_gpio_set_config() to support the other
+arguments amd_pinconf_set() supports, namely `PIN_CONFIG_BIAS_PULL_DOWN`,
+`PIN_CONFIG_BIAS_PULL_UP`, and `PIN_CONFIG_DRIVE_STRENGTH`.
+
+Reported-by: Nik P <npliashechnikov@gmail.com>
+Reported-by: Nathan Schulte <nmschulte@gmail.com>
+Reported-by: Friedrich Vock <friedrich.vock@gmx.de>
+Closes: https://bugzilla.kernel.org/show_bug.cgi?id=217336
+Reported-by: dridri85@gmail.com
+Closes: https://bugzilla.kernel.org/show_bug.cgi?id=217493
+Link: https://lore.kernel.org/linux-input/20230530154058.17594-1-friedrich.vock@gmx.de/
+Tested-by: Jan Visser <starquake@linuxeverywhere.org>
+Fixes: 2956b5d94a76 ("pinctrl / gpio: Introduce .set_config() callback for GPIO chips")
+Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
+Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Link: https://lore.kernel.org/r/20230705133005.577-3-mario.limonciello@amd.com
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/pinctrl/pinctrl-amd.c |   28 +++++++++++++++-------------
+ 1 file changed, 15 insertions(+), 13 deletions(-)
+
+--- a/drivers/pinctrl/pinctrl-amd.c
++++ b/drivers/pinctrl/pinctrl-amd.c
+@@ -188,18 +188,6 @@ static int amd_gpio_set_debounce(struct
+       return ret;
+ }
+-static int amd_gpio_set_config(struct gpio_chip *gc, unsigned offset,
+-                             unsigned long config)
+-{
+-      u32 debounce;
+-
+-      if (pinconf_to_config_param(config) != PIN_CONFIG_INPUT_DEBOUNCE)
+-              return -ENOTSUPP;
+-
+-      debounce = pinconf_to_config_argument(config);
+-      return amd_gpio_set_debounce(gc, offset, debounce);
+-}
+-
+ #ifdef CONFIG_DEBUG_FS
+ static void amd_gpio_dbg_show(struct seq_file *s, struct gpio_chip *gc)
+ {
+@@ -782,7 +770,7 @@ static int amd_pinconf_get(struct pinctr
+ }
+ static int amd_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
+-                              unsigned long *configs, unsigned num_configs)
++                         unsigned long *configs, unsigned int num_configs)
+ {
+       int i;
+       u32 arg;
+@@ -872,6 +860,20 @@ static int amd_pinconf_group_set(struct
+       return 0;
+ }
++static int amd_gpio_set_config(struct gpio_chip *gc, unsigned int pin,
++                             unsigned long config)
++{
++      struct amd_gpio *gpio_dev = gpiochip_get_data(gc);
++
++      if (pinconf_to_config_param(config) == PIN_CONFIG_INPUT_DEBOUNCE) {
++              u32 debounce = pinconf_to_config_argument(config);
++
++              return amd_gpio_set_debounce(gc, pin, debounce);
++      }
++
++      return amd_pinconf_set(gpio_dev->pctrl, pin, &config, 1);
++}
++
+ static const struct pinconf_ops amd_pinconf_ops = {
+       .pin_config_get         = amd_pinconf_get,
+       .pin_config_set         = amd_pinconf_set,
index 7b69d3abafc0c7c0daf03e627f6e5fd7272e5497..ae027cbf63d1425dea1373a1027f93fd1b2b6f98 100644 (file)
@@ -111,3 +111,30 @@ smb-client-fix-parsing-of-source-mount-option.patch
 drm-client-send-hotplug-event-after-registering-a-client.patch
 f2fs-don-t-reset-unchangable-mount-option-in-f2fs_remount.patch
 f2fs-fix-deadlock-in-i_xattr_sem-and-inode-page-lock.patch
+kbuild-make-modules_install-copy-modules.builtin-.modinfo.patch
+pinctrl-amd-detect-internal-gpio0-debounce-handling.patch
+pinctrl-amd-fix-mistake-in-handling-clearing-pins-at-startup.patch
+pinctrl-amd-detect-and-mask-spurious-interrupts.patch
+pinctrl-amd-revert-pinctrl-amd-disable-and-mask-interrupts-on-probe.patch
+pinctrl-amd-only-use-special-debounce-behavior-for-gpio-0.patch
+pinctrl-amd-use-amd_pinconf_set-for-all-config-options.patch
+pinctrl-amd-drop-pull-up-select-configuration.patch
+pinctrl-amd-unify-debounce-handling-into-amd_pinconf_set.patch
+tpm-do-not-remap-from-acpi-resources-again-for-pluton-tpm.patch
+tpm-tpm_vtpm_proxy-fix-a-race-condition-in-dev-vtpmx-creation.patch
+tpm-tpm_tis-disable-interrupts-only-for-aeon-upx-i11.patch
+tpm-tis_i2c-limit-read-bursts-to-i2c_smbus_block_max-32-bytes.patch
+tpm-tpm_tis-disable-interrupts-for-framework-laptop-intel-12th-gen.patch
+tpm-tis_i2c-limit-write-bursts-to-i2c_smbus_block_max-32-bytes.patch
+tpm-return-false-from-tpm_amd_is_rng_defective-on-non-x86-platforms.patch
+tpm-tpm_tis-disable-interrupts-for-framework-laptop-intel-13th-gen.patch
+tpm-tpm_tis-disable-interrupts-after-1000-unhandled-irqs.patch
+tpm-tpm_tis-disable-interrupts-for-lenovo-l590-devices.patch
+mtd-rawnand-meson-fix-unaligned-dma-buffers-handling.patch
+net-bcmgenet-ensure-mdio-unregistration-has-clocks-enabled.patch
+net-phy-dp83td510-fix-kernel-stall-during-netboot-in-dp83td510e-phy-driver.patch
+kasan-add-kasan_tag_mismatch-prototype.patch
+kasan-use-internal-prototypes-matching-gcc-13-builtins.patch
+kasan-slub-fix-hw_tags-zeroing-with-slub_debug.patch
+kasan-fix-type-cast-in-memory_is_poisoned_n.patch
+tracing-user_events-fix-incorrect-return-value-for-writing-operation-when-events-are-disabled.patch
diff --git a/queue-6.4/tpm-do-not-remap-from-acpi-resources-again-for-pluton-tpm.patch b/queue-6.4/tpm-do-not-remap-from-acpi-resources-again-for-pluton-tpm.patch
new file mode 100644 (file)
index 0000000..0917c45
--- /dev/null
@@ -0,0 +1,58 @@
+From b1c1b98962d17a922989aa3b2822946bbb5c091f Mon Sep 17 00:00:00 2001
+From: Valentin David <valentin.david@gmail.com>
+Date: Mon, 10 Jul 2023 22:27:49 +0200
+Subject: tpm: Do not remap from ACPI resources again for Pluton TPM
+
+From: Valentin David <valentin.david@gmail.com>
+
+commit b1c1b98962d17a922989aa3b2822946bbb5c091f upstream.
+
+For Pluton TPM devices, it was assumed that there was no ACPI memory
+regions. This is not true for ASUS ROG Ally. ACPI advertises
+0xfd500000-0xfd5fffff.
+
+Since remapping is already done in `crb_map_pluton`, remapping again
+in `crb_map_io` causes EBUSY error:
+
+[    3.510453] tpm_crb MSFT0101:00: can't request region for resource [mem 0xfd500000-0xfd5fffff]
+[    3.510463] tpm_crb: probe of MSFT0101:00 failed with error -16
+
+Cc: stable@vger.kernel.org # v6.3+
+Fixes: 4d2732882703 ("tpm_crb: Add support for CRB devices based on Pluton")
+Signed-off-by: Valentin David <valentin.david@gmail.com>
+Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
+Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/char/tpm/tpm_crb.c |   19 +++++++++++--------
+ 1 file changed, 11 insertions(+), 8 deletions(-)
+
+--- a/drivers/char/tpm/tpm_crb.c
++++ b/drivers/char/tpm/tpm_crb.c
+@@ -563,15 +563,18 @@ static int crb_map_io(struct acpi_device
+       u32 rsp_size;
+       int ret;
+-      INIT_LIST_HEAD(&acpi_resource_list);
+-      ret = acpi_dev_get_resources(device, &acpi_resource_list,
+-                                   crb_check_resource, iores_array);
+-      if (ret < 0)
+-              return ret;
+-      acpi_dev_free_resource_list(&acpi_resource_list);
+-
+-      /* Pluton doesn't appear to define ACPI memory regions */
++      /*
++       * Pluton sometimes does not define ACPI memory regions.
++       * Mapping is then done in crb_map_pluton
++       */
+       if (priv->sm != ACPI_TPM2_COMMAND_BUFFER_WITH_PLUTON) {
++              INIT_LIST_HEAD(&acpi_resource_list);
++              ret = acpi_dev_get_resources(device, &acpi_resource_list,
++                                           crb_check_resource, iores_array);
++              if (ret < 0)
++                      return ret;
++              acpi_dev_free_resource_list(&acpi_resource_list);
++
+               if (resource_type(iores_array) != IORESOURCE_MEM) {
+                       dev_err(dev, FW_BUG "TPM2 ACPI table does not define a memory resource\n");
+                       return -EINVAL;
diff --git a/queue-6.4/tpm-return-false-from-tpm_amd_is_rng_defective-on-non-x86-platforms.patch b/queue-6.4/tpm-return-false-from-tpm_amd_is_rng_defective-on-non-x86-platforms.patch
new file mode 100644 (file)
index 0000000..9ef8c07
--- /dev/null
@@ -0,0 +1,49 @@
+From ecff6813d2bcf0c670881a9ba3f51cb032dd405a Mon Sep 17 00:00:00 2001
+From: Jerry Snitselaar <jsnitsel@redhat.com>
+Date: Thu, 29 Jun 2023 13:41:47 -0700
+Subject: tpm: return false from tpm_amd_is_rng_defective on non-x86 platforms
+
+From: Jerry Snitselaar <jsnitsel@redhat.com>
+
+commit ecff6813d2bcf0c670881a9ba3f51cb032dd405a upstream.
+
+tpm_amd_is_rng_defective is for dealing with an issue related to the
+AMD firmware TPM, so on non-x86 architectures just have it inline and
+return false.
+
+Cc: stable@vger.kernel.org # v6.3+
+Reported-by: Sachin Sant <sachinp@linux.ibm.com>
+Reported-by: Aneesh Kumar K. V <aneesh.kumar@linux.ibm.com>
+Closes: https://lore.kernel.org/lkml/99B81401-DB46-49B9-B321-CF832B50CAC3@linux.ibm.com/
+Fixes: f1324bbc4011 ("tpm: disable hwrng for fTPM on some AMD designs")
+Signed-off-by: Jerry Snitselaar <jsnitsel@redhat.com>
+Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
+Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/char/tpm/tpm-chip.c |    7 +++++++
+ 1 file changed, 7 insertions(+)
+
+--- a/drivers/char/tpm/tpm-chip.c
++++ b/drivers/char/tpm/tpm-chip.c
+@@ -518,6 +518,7 @@ static int tpm_add_legacy_sysfs(struct t
+  * 6.x.y.z series: 6.0.18.6 +
+  * 3.x.y.z series: 3.57.y.5 +
+  */
++#ifdef CONFIG_X86
+ static bool tpm_amd_is_rng_defective(struct tpm_chip *chip)
+ {
+       u32 val1, val2;
+@@ -566,6 +567,12 @@ release:
+       return true;
+ }
++#else
++static inline bool tpm_amd_is_rng_defective(struct tpm_chip *chip)
++{
++      return false;
++}
++#endif /* CONFIG_X86 */
+ static int tpm_hwrng_read(struct hwrng *rng, void *data, size_t max, bool wait)
+ {
diff --git a/queue-6.4/tpm-tis_i2c-limit-read-bursts-to-i2c_smbus_block_max-32-bytes.patch b/queue-6.4/tpm-tis_i2c-limit-read-bursts-to-i2c_smbus_block_max-32-bytes.patch
new file mode 100644 (file)
index 0000000..6bf8e47
--- /dev/null
@@ -0,0 +1,75 @@
+From f3b70b6e3390bfdf18fdd7d278a72a12784fdcce Mon Sep 17 00:00:00 2001
+From: Alexander Sverdlin <alexander.sverdlin@siemens.com>
+Date: Wed, 24 May 2023 17:40:39 +0200
+Subject: tpm: tis_i2c: Limit read bursts to I2C_SMBUS_BLOCK_MAX (32) bytes
+
+From: Alexander Sverdlin <alexander.sverdlin@siemens.com>
+
+commit f3b70b6e3390bfdf18fdd7d278a72a12784fdcce upstream.
+
+Underlying I2C bus drivers not always support longer transfers and
+imx-lpi2c for instance doesn't. SLB 9673 offers 427-bytes packets.
+
+Visible symptoms are:
+
+tpm tpm0: Error left over data
+tpm tpm0: tpm_transmit: tpm_recv: error -5
+tpm_tis_i2c: probe of 1-002e failed with error -5
+
+Cc: stable@vger.kernel.org # v5.20+
+Fixes: bbc23a07b072 ("tpm: Add tpm_tis_i2c backend for tpm_tis_core")
+Tested-by: Michael Haener <michael.haener@siemens.com>
+Signed-off-by: Alexander Sverdlin <alexander.sverdlin@siemens.com>
+Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
+Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>
+Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/char/tpm/tpm_tis_i2c.c |   35 +++++++++++++++++++++--------------
+ 1 file changed, 21 insertions(+), 14 deletions(-)
+
+--- a/drivers/char/tpm/tpm_tis_i2c.c
++++ b/drivers/char/tpm/tpm_tis_i2c.c
+@@ -189,21 +189,28 @@ static int tpm_tis_i2c_read_bytes(struct
+       int ret;
+       for (i = 0; i < TPM_RETRY; i++) {
+-              /* write register */
+-              msg.len = sizeof(reg);
+-              msg.buf = &reg;
+-              msg.flags = 0;
+-              ret = tpm_tis_i2c_retry_transfer_until_ack(data, &msg);
+-              if (ret < 0)
+-                      return ret;
++              u16 read = 0;
+-              /* read data */
+-              msg.buf = result;
+-              msg.len = len;
+-              msg.flags = I2C_M_RD;
+-              ret = tpm_tis_i2c_retry_transfer_until_ack(data, &msg);
+-              if (ret < 0)
+-                      return ret;
++              while (read < len) {
++                      /* write register */
++                      msg.len = sizeof(reg);
++                      msg.buf = &reg;
++                      msg.flags = 0;
++                      ret = tpm_tis_i2c_retry_transfer_until_ack(data, &msg);
++                      if (ret < 0)
++                              return ret;
++
++                      /* read data */
++                      msg.buf = result + read;
++                      msg.len = len - read;
++                      msg.flags = I2C_M_RD;
++                      if (msg.len > I2C_SMBUS_BLOCK_MAX)
++                              msg.len = I2C_SMBUS_BLOCK_MAX;
++                      ret = tpm_tis_i2c_retry_transfer_until_ack(data, &msg);
++                      if (ret < 0)
++                              return ret;
++                      read += msg.len;
++              }
+               ret = tpm_tis_i2c_sanity_check_read(reg, len, result);
+               if (ret == 0)
diff --git a/queue-6.4/tpm-tis_i2c-limit-write-bursts-to-i2c_smbus_block_max-32-bytes.patch b/queue-6.4/tpm-tis_i2c-limit-write-bursts-to-i2c_smbus_block_max-32-bytes.patch
new file mode 100644 (file)
index 0000000..d66a601
--- /dev/null
@@ -0,0 +1,62 @@
+From 83e7e5d89f04d1c417492940f7922bc8416a8cc4 Mon Sep 17 00:00:00 2001
+From: Alexander Sverdlin <alexander.sverdlin@siemens.com>
+Date: Wed, 24 May 2023 17:40:40 +0200
+Subject: tpm: tis_i2c: Limit write bursts to I2C_SMBUS_BLOCK_MAX (32) bytes
+
+From: Alexander Sverdlin <alexander.sverdlin@siemens.com>
+
+commit 83e7e5d89f04d1c417492940f7922bc8416a8cc4 upstream.
+
+Underlying I2C bus drivers not always support longer transfers and
+imx-lpi2c for instance doesn't. The fix is symmetric to previous patch
+which fixed the read direction.
+
+Cc: stable@vger.kernel.org # v5.20+
+Fixes: bbc23a07b072 ("tpm: Add tpm_tis_i2c backend for tpm_tis_core")
+Tested-by: Michael Haener <michael.haener@siemens.com>
+Signed-off-by: Alexander Sverdlin <alexander.sverdlin@siemens.com>
+Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
+Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>
+Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/char/tpm/tpm_tis_i2c.c |   22 +++++++++++++++-------
+ 1 file changed, 15 insertions(+), 7 deletions(-)
+
+--- a/drivers/char/tpm/tpm_tis_i2c.c
++++ b/drivers/char/tpm/tpm_tis_i2c.c
+@@ -230,19 +230,27 @@ static int tpm_tis_i2c_write_bytes(struc
+       struct i2c_msg msg = { .addr = phy->i2c_client->addr };
+       u8 reg = tpm_tis_i2c_address_to_register(addr);
+       int ret;
++      u16 wrote = 0;
+       if (len > TPM_BUFSIZE - 1)
+               return -EIO;
+-      /* write register and data in one go */
+       phy->io_buf[0] = reg;
+-      memcpy(phy->io_buf + sizeof(reg), value, len);
+-
+-      msg.len = sizeof(reg) + len;
+       msg.buf = phy->io_buf;
+-      ret = tpm_tis_i2c_retry_transfer_until_ack(data, &msg);
+-      if (ret < 0)
+-              return ret;
++      while (wrote < len) {
++              /* write register and data in one go */
++              msg.len = sizeof(reg) + len - wrote;
++              if (msg.len > I2C_SMBUS_BLOCK_MAX)
++                      msg.len = I2C_SMBUS_BLOCK_MAX;
++
++              memcpy(phy->io_buf + sizeof(reg), value + wrote,
++                     msg.len - sizeof(reg));
++
++              ret = tpm_tis_i2c_retry_transfer_until_ack(data, &msg);
++              if (ret < 0)
++                      return ret;
++              wrote += msg.len - sizeof(reg);
++      }
+       return 0;
+ }
diff --git a/queue-6.4/tpm-tpm_tis-disable-interrupts-after-1000-unhandled-irqs.patch b/queue-6.4/tpm-tpm_tis-disable-interrupts-after-1000-unhandled-irqs.patch
new file mode 100644 (file)
index 0000000..c848dcc
--- /dev/null
@@ -0,0 +1,268 @@
+From 481c2d14627de8ecbb54dd125466e4b4a5069b47 Mon Sep 17 00:00:00 2001
+From: Lino Sanfilippo <l.sanfilippo@kunbus.com>
+Date: Thu, 13 Jul 2023 21:01:08 +0200
+Subject: tpm,tpm_tis: Disable interrupts after 1000 unhandled IRQs
+
+From: Lino Sanfilippo <l.sanfilippo@kunbus.com>
+
+commit 481c2d14627de8ecbb54dd125466e4b4a5069b47 upstream.
+
+After activation of interrupts for TPM TIS drivers 0-day reports an
+interrupt storm on an Inspur NF5180M6 server.
+
+Fix this by detecting the storm and falling back to polling:
+Count the number of unhandled interrupts within a 10 ms time interval. In
+case that more than 1000 were unhandled deactivate interrupts entirely,
+deregister the handler and use polling instead.
+
+Also print a note to point to the tpm_tis_dmi_table.
+
+Since the interrupt deregistration function devm_free_irq() waits for all
+interrupt handlers to finish, only trigger a worker in the interrupt
+handler and do the unregistration in the worker to avoid a deadlock.
+
+Note: the storm detection logic equals the implementation in
+note_interrupt() which uses timestamps and counters stored in struct
+irq_desc. Since this structure is private to the generic interrupt core
+the TPM TIS core uses its own timestamps and counters. Furthermore the TPM
+interrupt handler always returns IRQ_HANDLED to prevent the generic
+interrupt core from processing the interrupt storm.
+
+Cc: stable@vger.kernel.org # v6.4+
+Fixes: e644b2f498d2 ("tpm, tpm_tis: Enable interrupt test")
+Reported-by: kernel test robot <yujie.liu@intel.com>
+Closes: https://lore.kernel.org/oe-lkp/202305041325.ae8b0c43-yujie.liu@intel.com/
+Suggested-by: Lukas Wunner <lukas@wunner.de>
+Signed-off-by: Lino Sanfilippo <l.sanfilippo@kunbus.com>
+Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
+Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/char/tpm/tpm_tis_core.c | 103 +++++++++++++++++++++++++++-----
+ drivers/char/tpm/tpm_tis_core.h |   4 ++
+ 2 files changed, 92 insertions(+), 15 deletions(-)
+
+diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c
+index 558144fa707a..88a5384c09c0 100644
+--- a/drivers/char/tpm/tpm_tis_core.c
++++ b/drivers/char/tpm/tpm_tis_core.c
+@@ -24,9 +24,12 @@
+ #include <linux/wait.h>
+ #include <linux/acpi.h>
+ #include <linux/freezer.h>
++#include <linux/dmi.h>
+ #include "tpm.h"
+ #include "tpm_tis_core.h"
++#define TPM_TIS_MAX_UNHANDLED_IRQS    1000
++
+ static void tpm_tis_clkrun_enable(struct tpm_chip *chip, bool value);
+ static bool wait_for_tpm_stat_cond(struct tpm_chip *chip, u8 mask,
+@@ -468,25 +471,29 @@ static int tpm_tis_send_data(struct tpm_chip *chip, const u8 *buf, size_t len)
+       return rc;
+ }
+-static void disable_interrupts(struct tpm_chip *chip)
++static void __tpm_tis_disable_interrupts(struct tpm_chip *chip)
++{
++      struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
++      u32 int_mask = 0;
++
++      tpm_tis_read32(priv, TPM_INT_ENABLE(priv->locality), &int_mask);
++      int_mask &= ~TPM_GLOBAL_INT_ENABLE;
++      tpm_tis_write32(priv, TPM_INT_ENABLE(priv->locality), int_mask);
++
++      chip->flags &= ~TPM_CHIP_FLAG_IRQ;
++}
++
++static void tpm_tis_disable_interrupts(struct tpm_chip *chip)
+ {
+       struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
+-      u32 intmask;
+-      int rc;
+       if (priv->irq == 0)
+               return;
+-      rc = tpm_tis_read32(priv, TPM_INT_ENABLE(priv->locality), &intmask);
+-      if (rc < 0)
+-              intmask = 0;
+-
+-      intmask &= ~TPM_GLOBAL_INT_ENABLE;
+-      rc = tpm_tis_write32(priv, TPM_INT_ENABLE(priv->locality), intmask);
++      __tpm_tis_disable_interrupts(chip);
+       devm_free_irq(chip->dev.parent, priv->irq, chip);
+       priv->irq = 0;
+-      chip->flags &= ~TPM_CHIP_FLAG_IRQ;
+ }
+ /*
+@@ -552,7 +559,7 @@ static int tpm_tis_send(struct tpm_chip *chip, u8 *buf, size_t len)
+       if (!test_bit(TPM_TIS_IRQ_TESTED, &priv->flags))
+               tpm_msleep(1);
+       if (!test_bit(TPM_TIS_IRQ_TESTED, &priv->flags))
+-              disable_interrupts(chip);
++              tpm_tis_disable_interrupts(chip);
+       set_bit(TPM_TIS_IRQ_TESTED, &priv->flags);
+       return rc;
+ }
+@@ -752,6 +759,57 @@ static bool tpm_tis_req_canceled(struct tpm_chip *chip, u8 status)
+       return status == TPM_STS_COMMAND_READY;
+ }
++static irqreturn_t tpm_tis_revert_interrupts(struct tpm_chip *chip)
++{
++      struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
++      const char *product;
++      const char *vendor;
++
++      dev_warn(&chip->dev, FW_BUG
++               "TPM interrupt storm detected, polling instead\n");
++
++      vendor = dmi_get_system_info(DMI_SYS_VENDOR);
++      product = dmi_get_system_info(DMI_PRODUCT_VERSION);
++
++      if (vendor && product) {
++              dev_info(&chip->dev,
++                      "Consider adding the following entry to tpm_tis_dmi_table:\n");
++              dev_info(&chip->dev, "\tDMI_SYS_VENDOR: %s\n", vendor);
++              dev_info(&chip->dev, "\tDMI_PRODUCT_VERSION: %s\n", product);
++      }
++
++      if (tpm_tis_request_locality(chip, 0) != 0)
++              return IRQ_NONE;
++
++      __tpm_tis_disable_interrupts(chip);
++      tpm_tis_relinquish_locality(chip, 0);
++
++      schedule_work(&priv->free_irq_work);
++
++      return IRQ_HANDLED;
++}
++
++static irqreturn_t tpm_tis_update_unhandled_irqs(struct tpm_chip *chip)
++{
++      struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
++      irqreturn_t irqret = IRQ_HANDLED;
++
++      if (!(chip->flags & TPM_CHIP_FLAG_IRQ))
++              return IRQ_HANDLED;
++
++      if (time_after(jiffies, priv->last_unhandled_irq + HZ/10))
++              priv->unhandled_irqs = 1;
++      else
++              priv->unhandled_irqs++;
++
++      priv->last_unhandled_irq = jiffies;
++
++      if (priv->unhandled_irqs > TPM_TIS_MAX_UNHANDLED_IRQS)
++              irqret = tpm_tis_revert_interrupts(chip);
++
++      return irqret;
++}
++
+ static irqreturn_t tis_int_handler(int dummy, void *dev_id)
+ {
+       struct tpm_chip *chip = dev_id;
+@@ -761,10 +819,10 @@ static irqreturn_t tis_int_handler(int dummy, void *dev_id)
+       rc = tpm_tis_read32(priv, TPM_INT_STATUS(priv->locality), &interrupt);
+       if (rc < 0)
+-              return IRQ_NONE;
++              goto err;
+       if (interrupt == 0)
+-              return IRQ_NONE;
++              goto err;
+       set_bit(TPM_TIS_IRQ_TESTED, &priv->flags);
+       if (interrupt & TPM_INTF_DATA_AVAIL_INT)
+@@ -780,10 +838,13 @@ static irqreturn_t tis_int_handler(int dummy, void *dev_id)
+       rc = tpm_tis_write32(priv, TPM_INT_STATUS(priv->locality), interrupt);
+       tpm_tis_relinquish_locality(chip, 0);
+       if (rc < 0)
+-              return IRQ_NONE;
++              goto err;
+       tpm_tis_read32(priv, TPM_INT_STATUS(priv->locality), &interrupt);
+       return IRQ_HANDLED;
++
++err:
++      return tpm_tis_update_unhandled_irqs(chip);
+ }
+ static void tpm_tis_gen_interrupt(struct tpm_chip *chip)
+@@ -804,6 +865,15 @@ static void tpm_tis_gen_interrupt(struct tpm_chip *chip)
+               chip->flags &= ~TPM_CHIP_FLAG_IRQ;
+ }
++static void tpm_tis_free_irq_func(struct work_struct *work)
++{
++      struct tpm_tis_data *priv = container_of(work, typeof(*priv), free_irq_work);
++      struct tpm_chip *chip = priv->chip;
++
++      devm_free_irq(chip->dev.parent, priv->irq, chip);
++      priv->irq = 0;
++}
++
+ /* Register the IRQ and issue a command that will cause an interrupt. If an
+  * irq is seen then leave the chip setup for IRQ operation, otherwise reverse
+  * everything and leave in polling mode. Returns 0 on success.
+@@ -816,6 +886,7 @@ static int tpm_tis_probe_irq_single(struct tpm_chip *chip, u32 intmask,
+       int rc;
+       u32 int_status;
++      INIT_WORK(&priv->free_irq_work, tpm_tis_free_irq_func);
+       rc = devm_request_threaded_irq(chip->dev.parent, irq, NULL,
+                                      tis_int_handler, IRQF_ONESHOT | flags,
+@@ -918,6 +989,7 @@ void tpm_tis_remove(struct tpm_chip *chip)
+               interrupt = 0;
+       tpm_tis_write32(priv, reg, ~TPM_GLOBAL_INT_ENABLE & interrupt);
++      flush_work(&priv->free_irq_work);
+       tpm_tis_clkrun_enable(chip, false);
+@@ -1021,6 +1093,7 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
+       chip->timeout_b = msecs_to_jiffies(TIS_TIMEOUT_B_MAX);
+       chip->timeout_c = msecs_to_jiffies(TIS_TIMEOUT_C_MAX);
+       chip->timeout_d = msecs_to_jiffies(TIS_TIMEOUT_D_MAX);
++      priv->chip = chip;
+       priv->timeout_min = TPM_TIMEOUT_USECS_MIN;
+       priv->timeout_max = TPM_TIMEOUT_USECS_MAX;
+       priv->phy_ops = phy_ops;
+@@ -1179,7 +1252,7 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
+                       rc = tpm_tis_request_locality(chip, 0);
+                       if (rc < 0)
+                               goto out_err;
+-                      disable_interrupts(chip);
++                      tpm_tis_disable_interrupts(chip);
+                       tpm_tis_relinquish_locality(chip, 0);
+               }
+       }
+diff --git a/drivers/char/tpm/tpm_tis_core.h b/drivers/char/tpm/tpm_tis_core.h
+index 610bfadb6acf..b1a169d7d1ca 100644
+--- a/drivers/char/tpm/tpm_tis_core.h
++++ b/drivers/char/tpm/tpm_tis_core.h
+@@ -91,11 +91,15 @@ enum tpm_tis_flags {
+ };
+ struct tpm_tis_data {
++      struct tpm_chip *chip;
+       u16 manufacturer_id;
+       struct mutex locality_count_mutex;
+       unsigned int locality_count;
+       int locality;
+       int irq;
++      struct work_struct free_irq_work;
++      unsigned long last_unhandled_irq;
++      unsigned int unhandled_irqs;
+       unsigned int int_mask;
+       unsigned long flags;
+       void __iomem *ilb_base_addr;
+-- 
+2.41.0
+
diff --git a/queue-6.4/tpm-tpm_tis-disable-interrupts-for-framework-laptop-intel-12th-gen.patch b/queue-6.4/tpm-tpm_tis-disable-interrupts-for-framework-laptop-intel-12th-gen.patch
new file mode 100644 (file)
index 0000000..49bf302
--- /dev/null
@@ -0,0 +1,46 @@
+From 08b0af4478bacb8bb701c172c99a34ea32da89f5 Mon Sep 17 00:00:00 2001
+From: Christian Hesse <mail@eworm.de>
+Date: Mon, 10 Jul 2023 23:16:09 +0200
+Subject: tpm/tpm_tis: Disable interrupts for Framework Laptop Intel 12th gen
+
+From: Christian Hesse <mail@eworm.de>
+
+commit 08b0af4478bacb8bb701c172c99a34ea32da89f5 upstream.
+
+This device suffer an irq storm, so add it in tpm_tis_dmi_table to
+force polling.
+
+Cc: stable@vger.kernel.org # v6.4+
+Link: https://community.frame.work/t/boot-and-shutdown-hangs-with-arch-linux-kernel-6-4-1-mainline-and-arch/33118
+Fixes: e644b2f498d2 ("tpm, tpm_tis: Enable interrupt test")
+Reported-by: <roubro1991@gmail.com>
+Closes: https://bugzilla.kernel.org/show_bug.cgi?id=217631
+Signed-off-by: Christian Hesse <mail@eworm.de>
+Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/char/tpm/tpm_tis.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c
+index 9cb4e81fc548..5dd391ed3320 100644
+--- a/drivers/char/tpm/tpm_tis.c
++++ b/drivers/char/tpm/tpm_tis.c
+@@ -114,6 +114,14 @@ static int tpm_tis_disable_irq(const struct dmi_system_id *d)
+ }
+ static const struct dmi_system_id tpm_tis_dmi_table[] = {
++      {
++              .callback = tpm_tis_disable_irq,
++              .ident = "Framework Laptop (12th Gen Intel Core)",
++              .matches = {
++                      DMI_MATCH(DMI_SYS_VENDOR, "Framework"),
++                      DMI_MATCH(DMI_PRODUCT_NAME, "Laptop (12th Gen Intel Core)"),
++              },
++      },
+       {
+               .callback = tpm_tis_disable_irq,
+               .ident = "ThinkPad T490s",
+-- 
+2.41.0
+
diff --git a/queue-6.4/tpm-tpm_tis-disable-interrupts-for-framework-laptop-intel-13th-gen.patch b/queue-6.4/tpm-tpm_tis-disable-interrupts-for-framework-laptop-intel-13th-gen.patch
new file mode 100644 (file)
index 0000000..78fde3b
--- /dev/null
@@ -0,0 +1,46 @@
+From bc825e851c2fe89c127cac1e0e5cf344c4940619 Mon Sep 17 00:00:00 2001
+From: Christian Hesse <mail@eworm.de>
+Date: Mon, 10 Jul 2023 23:16:10 +0200
+Subject: tpm/tpm_tis: Disable interrupts for Framework Laptop Intel 13th gen
+
+From: Christian Hesse <mail@eworm.de>
+
+commit bc825e851c2fe89c127cac1e0e5cf344c4940619 upstream.
+
+This device suffer an irq storm, so add it in tpm_tis_dmi_table to
+force polling.
+
+Cc: stable@vger.kernel.org # v6.4+
+Link: https://community.frame.work/t/boot-and-shutdown-hangs-with-arch-linux-kernel-6-4-1-mainline-and-arch/33118
+Fixes: e644b2f498d2 ("tpm, tpm_tis: Enable interrupt test")
+Reported-by: <roubro1991@gmail.com>
+Closes: https://bugzilla.kernel.org/show_bug.cgi?id=217631
+Signed-off-by: Christian Hesse <mail@eworm.de>
+Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/char/tpm/tpm_tis.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c
+index 5dd391ed3320..4e4426965cd0 100644
+--- a/drivers/char/tpm/tpm_tis.c
++++ b/drivers/char/tpm/tpm_tis.c
+@@ -122,6 +122,14 @@ static const struct dmi_system_id tpm_tis_dmi_table[] = {
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Laptop (12th Gen Intel Core)"),
+               },
+       },
++      {
++              .callback = tpm_tis_disable_irq,
++              .ident = "Framework Laptop (13th Gen Intel Core)",
++              .matches = {
++                      DMI_MATCH(DMI_SYS_VENDOR, "Framework"),
++                      DMI_MATCH(DMI_PRODUCT_NAME, "Laptop (13th Gen Intel Core)"),
++              },
++      },
+       {
+               .callback = tpm_tis_disable_irq,
+               .ident = "ThinkPad T490s",
+-- 
+2.41.0
+
diff --git a/queue-6.4/tpm-tpm_tis-disable-interrupts-for-lenovo-l590-devices.patch b/queue-6.4/tpm-tpm_tis-disable-interrupts-for-lenovo-l590-devices.patch
new file mode 100644 (file)
index 0000000..0c2f291
--- /dev/null
@@ -0,0 +1,47 @@
+From 393f362389cecc2e4f2e3520a6c8ee9dbb1e3d15 Mon Sep 17 00:00:00 2001
+From: Florian Bezdeka <florian@bezdeka.de>
+Date: Tue, 20 Jun 2023 13:11:01 +0200
+Subject: tpm/tpm_tis: Disable interrupts for Lenovo L590 devices
+
+From: Florian Bezdeka <florian@bezdeka.de>
+
+commit 393f362389cecc2e4f2e3520a6c8ee9dbb1e3d15 upstream.
+
+The Lenovo L590 suffers from an irq storm issue like the T490, T490s
+and P360 Tiny, so add an entry for it to tpm_tis_dmi_table and force
+polling.
+
+Cc: stable@vger.kernel.org # v6.4+
+Link: https://bugzilla.redhat.com/show_bug.cgi?id=2214069#c0
+Fixes: e644b2f498d2 ("tpm, tpm_tis: Enable interrupt test")
+Signed-off-by: Florian Bezdeka <florian@bezdeka.de>
+Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>
+Reviewed-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/char/tpm/tpm_tis.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c
+index 4e4426965cd0..cc42cf3de960 100644
+--- a/drivers/char/tpm/tpm_tis.c
++++ b/drivers/char/tpm/tpm_tis.c
+@@ -154,6 +154,14 @@ static const struct dmi_system_id tpm_tis_dmi_table[] = {
+                       DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad L490"),
+               },
+       },
++      {
++              .callback = tpm_tis_disable_irq,
++              .ident = "ThinkPad L590",
++              .matches = {
++                      DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
++                      DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad L590"),
++              },
++      },
+       {
+               .callback = tpm_tis_disable_irq,
+               .ident = "UPX-TGL",
+-- 
+2.41.0
+
diff --git a/queue-6.4/tpm-tpm_tis-disable-interrupts-only-for-aeon-upx-i11.patch b/queue-6.4/tpm-tpm_tis-disable-interrupts-only-for-aeon-upx-i11.patch
new file mode 100644 (file)
index 0000000..0db64e4
--- /dev/null
@@ -0,0 +1,37 @@
+From edb13d7bb034c4d5523f15e9aeea31c504af6f91 Mon Sep 17 00:00:00 2001
+From: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
+Date: Wed, 17 May 2023 15:29:31 +0300
+Subject: tpm: tpm_tis: Disable interrupts *only* for AEON UPX-i11
+
+From: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
+
+commit edb13d7bb034c4d5523f15e9aeea31c504af6f91 upstream.
+
+Further restrict with DMI_PRODUCT_VERSION.
+
+Cc: stable@vger.kernel.org # v6.4+
+Link: https://lore.kernel.org/linux-integrity/20230517122931.22385-1-peter.ujfalusi@linux.intel.com/
+Fixes: 95a9359ee22f ("tpm: tpm_tis: Disable interrupts for AEON UPX-i11")
+Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
+Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
+Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/char/tpm/tpm_tis.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c
+index 7db3593941ea..9cb4e81fc548 100644
+--- a/drivers/char/tpm/tpm_tis.c
++++ b/drivers/char/tpm/tpm_tis.c
+@@ -143,6 +143,7 @@ static const struct dmi_system_id tpm_tis_dmi_table[] = {
+               .ident = "UPX-TGL",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "AAEON"),
++                      DMI_MATCH(DMI_PRODUCT_VERSION, "UPX-TGL"),
+               },
+       },
+       {}
+-- 
+2.41.0
+
diff --git a/queue-6.4/tpm-tpm_vtpm_proxy-fix-a-race-condition-in-dev-vtpmx-creation.patch b/queue-6.4/tpm-tpm_vtpm_proxy-fix-a-race-condition-in-dev-vtpmx-creation.patch
new file mode 100644 (file)
index 0000000..7ac9e67
--- /dev/null
@@ -0,0 +1,80 @@
+From f4032d615f90970d6c3ac1d9c0bce3351eb4445c Mon Sep 17 00:00:00 2001
+From: Jarkko Sakkinen <jarkko.sakkinen@tuni.fi>
+Date: Tue, 16 May 2023 01:25:54 +0300
+Subject: tpm: tpm_vtpm_proxy: fix a race condition in /dev/vtpmx creation
+
+From: Jarkko Sakkinen <jarkko.sakkinen@tuni.fi>
+
+commit f4032d615f90970d6c3ac1d9c0bce3351eb4445c upstream.
+
+/dev/vtpmx is made visible before 'workqueue' is initialized, which can
+lead to a memory corruption in the worst case scenario.
+
+Address this by initializing 'workqueue' as the very first step of the
+driver initialization.
+
+Cc: stable@vger.kernel.org
+Fixes: 6f99612e2500 ("tpm: Proxy driver for supporting multiple emulated TPMs")
+Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
+Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@tuni.fi>
+Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/char/tpm/tpm_vtpm_proxy.c |   30 +++++++-----------------------
+ 1 file changed, 7 insertions(+), 23 deletions(-)
+
+--- a/drivers/char/tpm/tpm_vtpm_proxy.c
++++ b/drivers/char/tpm/tpm_vtpm_proxy.c
+@@ -683,37 +683,21 @@ static struct miscdevice vtpmx_miscdev =
+       .fops = &vtpmx_fops,
+ };
+-static int vtpmx_init(void)
+-{
+-      return misc_register(&vtpmx_miscdev);
+-}
+-
+-static void vtpmx_cleanup(void)
+-{
+-      misc_deregister(&vtpmx_miscdev);
+-}
+-
+ static int __init vtpm_module_init(void)
+ {
+       int rc;
+-      rc = vtpmx_init();
+-      if (rc) {
+-              pr_err("couldn't create vtpmx device\n");
+-              return rc;
+-      }
+-
+       workqueue = create_workqueue("tpm-vtpm");
+       if (!workqueue) {
+               pr_err("couldn't create workqueue\n");
+-              rc = -ENOMEM;
+-              goto err_vtpmx_cleanup;
++              return -ENOMEM;
+       }
+-      return 0;
+-
+-err_vtpmx_cleanup:
+-      vtpmx_cleanup();
++      rc = misc_register(&vtpmx_miscdev);
++      if (rc) {
++              pr_err("couldn't create vtpmx device\n");
++              destroy_workqueue(workqueue);
++      }
+       return rc;
+ }
+@@ -721,7 +705,7 @@ err_vtpmx_cleanup:
+ static void __exit vtpm_module_exit(void)
+ {
+       destroy_workqueue(workqueue);
+-      vtpmx_cleanup();
++      misc_deregister(&vtpmx_miscdev);
+ }
+ module_init(vtpm_module_init);
diff --git a/queue-6.4/tracing-user_events-fix-incorrect-return-value-for-writing-operation-when-events-are-disabled.patch b/queue-6.4/tracing-user_events-fix-incorrect-return-value-for-writing-operation-when-events-are-disabled.patch
new file mode 100644 (file)
index 0000000..dca7d56
--- /dev/null
@@ -0,0 +1,37 @@
+From f6d026eea390d59787a6cdc2ef5c983d02e029d0 Mon Sep 17 00:00:00 2001
+From: sunliming <sunliming@kylinos.cn>
+Date: Mon, 26 Jun 2023 19:13:42 +0800
+Subject: tracing/user_events: Fix incorrect return value for writing operation when events are disabled
+
+From: sunliming <sunliming@kylinos.cn>
+
+commit f6d026eea390d59787a6cdc2ef5c983d02e029d0 upstream.
+
+The writing operation return the count of writes regardless of whether events
+are enabled or disabled. Switch it to return -EBADF to indicates that the event
+is disabled.
+
+Link: https://lkml.kernel.org/r/20230626111344.19136-2-sunliming@kylinos.cn
+
+Cc: stable@vger.kernel.org
+7f5a08c79df35 ("user_events: Add minimal support for trace_event into ftrace")
+Acked-by: Beau Belgrave <beaub@linux.microsoft.com>
+Signed-off-by: sunliming <sunliming@kylinos.cn>
+Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ kernel/trace/trace_events_user.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/kernel/trace/trace_events_user.c
++++ b/kernel/trace/trace_events_user.c
+@@ -2096,7 +2096,8 @@ static ssize_t user_events_write_core(st
+               if (unlikely(faulted))
+                       return -EFAULT;
+-      }
++      } else
++              return -EBADF;
+       return ret;
+ }