--- /dev/null
+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 */
--- /dev/null
+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;
--- /dev/null
+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);
--- /dev/null
+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,
--- /dev/null
+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 :=
+
--- /dev/null
+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;
--- /dev/null
+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);
+ }
--- /dev/null
+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) {
--- /dev/null
+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 */
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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);
+ }
--- /dev/null
+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);
+
--- /dev/null
+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 */
--- /dev/null
+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);
+ }
+
--- /dev/null
+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,
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
--- /dev/null
+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;
--- /dev/null
+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)
+ {
--- /dev/null
+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 = ®
+- 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 = ®
++ 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)
--- /dev/null
+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;
+ }
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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);
--- /dev/null
+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;
+ }