--- /dev/null
+From fc3d2d8da62d1731dd1ec10acc392318ca6c371f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Dec 2020 19:10:30 -0800
+Subject: arch, mm: restore dependency of __kernel_map_pages() on
+ DEBUG_PAGEALLOC
+
+From: Mike Rapoport <rppt@linux.ibm.com>
+
+[ Upstream commit 5d6ad668f31625c6aa9ed8dc3bdb29561d2b1144 ]
+
+The design of DEBUG_PAGEALLOC presumes that __kernel_map_pages() must
+never fail. With this assumption is wouldn't be safe to allow general
+usage of this function.
+
+Moreover, some architectures that implement __kernel_map_pages() have this
+function guarded by #ifdef DEBUG_PAGEALLOC and some refuse to map/unmap
+pages when page allocation debugging is disabled at runtime.
+
+As all the users of __kernel_map_pages() were converted to use
+debug_pagealloc_map_pages() it is safe to make it available only when
+DEBUG_PAGEALLOC is set.
+
+Link: https://lkml.kernel.org/r/20201109192128.960-4-rppt@kernel.org
+Signed-off-by: Mike Rapoport <rppt@linux.ibm.com>
+Acked-by: David Hildenbrand <david@redhat.com>
+Acked-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
+Cc: Albert Ou <aou@eecs.berkeley.edu>
+Cc: Andy Lutomirski <luto@kernel.org>
+Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
+Cc: Borislav Petkov <bp@alien8.de>
+Cc: Catalin Marinas <catalin.marinas@arm.com>
+Cc: Christian Borntraeger <borntraeger@de.ibm.com>
+Cc: Christoph Lameter <cl@linux.com>
+Cc: Dave Hansen <dave.hansen@linux.intel.com>
+Cc: David Rientjes <rientjes@google.com>
+Cc: "David S. Miller" <davem@davemloft.net>
+Cc: "Edgecombe, Rick P" <rick.p.edgecombe@intel.com>
+Cc: Heiko Carstens <hca@linux.ibm.com>
+Cc: "H. Peter Anvin" <hpa@zytor.com>
+Cc: Ingo Molnar <mingo@redhat.com>
+Cc: Joonsoo Kim <iamjoonsoo.kim@lge.com>
+Cc: Len Brown <len.brown@intel.com>
+Cc: Michael Ellerman <mpe@ellerman.id.au>
+Cc: Palmer Dabbelt <palmer@dabbelt.com>
+Cc: Paul Mackerras <paulus@samba.org>
+Cc: Paul Walmsley <paul.walmsley@sifive.com>
+Cc: Pavel Machek <pavel@ucw.cz>
+Cc: Pekka Enberg <penberg@kernel.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: Vasily Gorbik <gor@linux.ibm.com>
+Cc: Vlastimil Babka <vbabka@suse.cz>
+Cc: Will Deacon <will@kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Stable-dep-of: fb1cf0878328 ("riscv: rewrite __kernel_map_pages() to fix sleeping in invalid context")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/Kconfig | 3 +++
+ arch/arm64/Kconfig | 4 +---
+ arch/arm64/mm/pageattr.c | 8 ++++++--
+ arch/powerpc/Kconfig | 5 +----
+ arch/riscv/Kconfig | 4 +---
+ arch/riscv/include/asm/pgtable.h | 2 --
+ arch/riscv/mm/pageattr.c | 2 ++
+ arch/s390/Kconfig | 4 +---
+ arch/sparc/Kconfig | 4 +---
+ arch/x86/Kconfig | 4 +---
+ arch/x86/mm/pat/set_memory.c | 2 ++
+ include/linux/mm.h | 10 +++++++---
+ 12 files changed, 26 insertions(+), 26 deletions(-)
+
+diff --git a/arch/Kconfig b/arch/Kconfig
+index 72e4cef062aca..3f025e47fb5d6 100644
+--- a/arch/Kconfig
++++ b/arch/Kconfig
+@@ -1073,6 +1073,9 @@ config ARCH_SPLIT_ARG64
+ If a 32-bit architecture requires 64-bit arguments to be split into
+ pairs of 32-bit arguments, select this option.
+
++config ARCH_SUPPORTS_DEBUG_PAGEALLOC
++ bool
++
+ source "kernel/gcov/Kconfig"
+
+ source "scripts/gcc-plugins/Kconfig"
+diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
+index 13cf137da999a..c47b2887f300e 100644
+--- a/arch/arm64/Kconfig
++++ b/arch/arm64/Kconfig
+@@ -71,6 +71,7 @@ config ARM64
+ select ARCH_USE_QUEUED_RWLOCKS
+ select ARCH_USE_QUEUED_SPINLOCKS
+ select ARCH_USE_SYM_ANNOTATIONS
++ select ARCH_SUPPORTS_DEBUG_PAGEALLOC
+ select ARCH_SUPPORTS_MEMORY_FAILURE
+ select ARCH_SUPPORTS_SHADOW_CALL_STACK if CC_HAVE_SHADOW_CALL_STACK
+ select ARCH_SUPPORTS_ATOMIC_RMW
+@@ -1063,9 +1064,6 @@ config HOLES_IN_ZONE
+
+ source "kernel/Kconfig.hz"
+
+-config ARCH_SUPPORTS_DEBUG_PAGEALLOC
+- def_bool y
+-
+ config ARCH_SPARSEMEM_ENABLE
+ def_bool y
+ select SPARSEMEM_VMEMMAP_ENABLE
+diff --git a/arch/arm64/mm/pageattr.c b/arch/arm64/mm/pageattr.c
+index 1b94f5b826545..439325532be1e 100644
+--- a/arch/arm64/mm/pageattr.c
++++ b/arch/arm64/mm/pageattr.c
+@@ -155,7 +155,7 @@ int set_direct_map_invalid_noflush(struct page *page)
+ .clear_mask = __pgprot(PTE_VALID),
+ };
+
+- if (!rodata_full)
++ if (!debug_pagealloc_enabled() && !rodata_full)
+ return 0;
+
+ return apply_to_page_range(&init_mm,
+@@ -170,7 +170,7 @@ int set_direct_map_default_noflush(struct page *page)
+ .clear_mask = __pgprot(PTE_RDONLY),
+ };
+
+- if (!rodata_full)
++ if (!debug_pagealloc_enabled() && !rodata_full)
+ return 0;
+
+ return apply_to_page_range(&init_mm,
+@@ -178,6 +178,7 @@ int set_direct_map_default_noflush(struct page *page)
+ PAGE_SIZE, change_page_range, &data);
+ }
+
++#ifdef CONFIG_DEBUG_PAGEALLOC
+ void __kernel_map_pages(struct page *page, int numpages, int enable)
+ {
+ if (!debug_pagealloc_enabled() && !rodata_full)
+@@ -186,6 +187,7 @@ void __kernel_map_pages(struct page *page, int numpages, int enable)
+ set_memory_valid((unsigned long)page_address(page), numpages, enable);
+ }
+
++#ifdef CONFIG_HIBERNATION
+ /*
+ * This function is used to determine if a linear map page has been marked as
+ * not-valid. Walk the page table and check the PTE_VALID bit. This is based
+@@ -232,3 +234,5 @@ bool kernel_page_present(struct page *page)
+ ptep = pte_offset_kernel(pmdp, addr);
+ return pte_valid(READ_ONCE(*ptep));
+ }
++#endif /* CONFIG_HIBERNATION */
++#endif /* CONFIG_DEBUG_PAGEALLOC */
+diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
+index 78dd6be8b31dd..c8e5b0929ef25 100644
+--- a/arch/powerpc/Kconfig
++++ b/arch/powerpc/Kconfig
+@@ -146,6 +146,7 @@ config PPC
+ select ARCH_MIGHT_HAVE_PC_SERIO
+ select ARCH_OPTIONAL_KERNEL_RWX if ARCH_HAS_STRICT_KERNEL_RWX
+ select ARCH_SUPPORTS_ATOMIC_RMW
++ select ARCH_SUPPORTS_DEBUG_PAGEALLOC if PPC32 || PPC_BOOK3S_64
+ select ARCH_USE_BUILTIN_BSWAP
+ select ARCH_USE_CMPXCHG_LOCKREF if PPC64
+ select ARCH_USE_QUEUED_RWLOCKS if PPC_QUEUED_SPINLOCKS
+@@ -356,10 +357,6 @@ config PPC_OF_PLATFORM_PCI
+ depends on PCI
+ depends on PPC64 # not supported on 32 bits yet
+
+-config ARCH_SUPPORTS_DEBUG_PAGEALLOC
+- depends on PPC32 || PPC_BOOK3S_64
+- def_bool y
+-
+ config ARCH_SUPPORTS_UPROBES
+ def_bool y
+
+diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
+index 70271db833831..dc141bd752a2a 100644
+--- a/arch/riscv/Kconfig
++++ b/arch/riscv/Kconfig
+@@ -14,6 +14,7 @@ config RISCV
+ def_bool y
+ select ARCH_CLOCKSOURCE_INIT
+ select ARCH_SUPPORTS_ATOMIC_RMW
++ select ARCH_SUPPORTS_DEBUG_PAGEALLOC if MMU
+ select ARCH_HAS_BINFMT_FLAT
+ select ARCH_HAS_DEBUG_VM_PGTABLE
+ select ARCH_HAS_DEBUG_VIRTUAL if MMU
+@@ -160,9 +161,6 @@ config ARCH_SELECT_MEMORY_MODEL
+ config ARCH_WANT_GENERAL_HUGETLB
+ def_bool y
+
+-config ARCH_SUPPORTS_DEBUG_PAGEALLOC
+- def_bool y
+-
+ config SYS_SUPPORTS_HUGETLBFS
+ depends on MMU
+ def_bool y
+diff --git a/arch/riscv/include/asm/pgtable.h b/arch/riscv/include/asm/pgtable.h
+index 982745572945e..99110223eb0e1 100644
+--- a/arch/riscv/include/asm/pgtable.h
++++ b/arch/riscv/include/asm/pgtable.h
+@@ -460,8 +460,6 @@ static inline int ptep_clear_flush_young(struct vm_area_struct *vma,
+ #define VMALLOC_START _AC(0, UL)
+ #define VMALLOC_END TASK_SIZE
+
+-static inline void __kernel_map_pages(struct page *page, int numpages, int enable) {}
+-
+ #endif /* !CONFIG_MMU */
+
+ #define kern_addr_valid(addr) (1) /* FIXME */
+diff --git a/arch/riscv/mm/pageattr.c b/arch/riscv/mm/pageattr.c
+index 09f6be19ba7b3..ae63a0227e2fb 100644
+--- a/arch/riscv/mm/pageattr.c
++++ b/arch/riscv/mm/pageattr.c
+@@ -184,6 +184,7 @@ int set_direct_map_default_noflush(struct page *page)
+ return ret;
+ }
+
++#ifdef CONFIG_DEBUG_PAGEALLOC
+ void __kernel_map_pages(struct page *page, int numpages, int enable)
+ {
+ if (!debug_pagealloc_enabled())
+@@ -196,3 +197,4 @@ void __kernel_map_pages(struct page *page, int numpages, int enable)
+ __set_memory((unsigned long)page_address(page), numpages,
+ __pgprot(0), __pgprot(_PAGE_PRESENT));
+ }
++#endif
+diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
+index 878993982e39d..cf5b7bb3726f7 100644
+--- a/arch/s390/Kconfig
++++ b/arch/s390/Kconfig
+@@ -35,9 +35,6 @@ config GENERIC_LOCKBREAK
+ config PGSTE
+ def_bool y if KVM
+
+-config ARCH_SUPPORTS_DEBUG_PAGEALLOC
+- def_bool y
+-
+ config AUDIT_ARCH
+ def_bool y
+
+@@ -106,6 +103,7 @@ config S390
+ select ARCH_INLINE_WRITE_UNLOCK_IRQRESTORE
+ select ARCH_STACKWALK
+ select ARCH_SUPPORTS_ATOMIC_RMW
++ select ARCH_SUPPORTS_DEBUG_PAGEALLOC
+ select ARCH_SUPPORTS_NUMA_BALANCING
+ select ARCH_USE_BUILTIN_BSWAP
+ select ARCH_USE_CMPXCHG_LOCKREF
+diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig
+index 7e2ce4c8d6571..1206bb46dd016 100644
+--- a/arch/sparc/Kconfig
++++ b/arch/sparc/Kconfig
+@@ -89,6 +89,7 @@ config SPARC64
+ select HAVE_C_RECORDMCOUNT
+ select HAVE_ARCH_AUDITSYSCALL
+ select ARCH_SUPPORTS_ATOMIC_RMW
++ select ARCH_SUPPORTS_DEBUG_PAGEALLOC
+ select HAVE_NMI
+ select HAVE_REGS_AND_STACK_ACCESS_API
+ select ARCH_USE_QUEUED_RWLOCKS
+@@ -149,9 +150,6 @@ config GENERIC_ISA_DMA
+ bool
+ default y if SPARC32
+
+-config ARCH_SUPPORTS_DEBUG_PAGEALLOC
+- def_bool y if SPARC64
+-
+ config PGTABLE_LEVELS
+ default 4 if 64BIT
+ default 3
+diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
+index 0c802ade80406..a948d614fbe52 100644
+--- a/arch/x86/Kconfig
++++ b/arch/x86/Kconfig
+@@ -94,6 +94,7 @@ config X86
+ select ARCH_STACKWALK
+ select ARCH_SUPPORTS_ACPI
+ select ARCH_SUPPORTS_ATOMIC_RMW
++ select ARCH_SUPPORTS_DEBUG_PAGEALLOC
+ select ARCH_SUPPORTS_NUMA_BALANCING if X86_64
+ select ARCH_USE_BUILTIN_BSWAP
+ select ARCH_USE_QUEUED_RWLOCKS
+@@ -333,9 +334,6 @@ config ZONE_DMA32
+ config AUDIT_ARCH
+ def_bool y if X86_64
+
+-config ARCH_SUPPORTS_DEBUG_PAGEALLOC
+- def_bool y
+-
+ config KASAN_SHADOW_OFFSET
+ hex
+ depends on KASAN
+diff --git a/arch/x86/mm/pat/set_memory.c b/arch/x86/mm/pat/set_memory.c
+index 217dda690ed82..57ba2603d481e 100644
+--- a/arch/x86/mm/pat/set_memory.c
++++ b/arch/x86/mm/pat/set_memory.c
+@@ -2194,6 +2194,7 @@ int set_direct_map_default_noflush(struct page *page)
+ return __set_pages_p(page, 1);
+ }
+
++#ifdef CONFIG_DEBUG_PAGEALLOC
+ void __kernel_map_pages(struct page *page, int numpages, int enable)
+ {
+ if (PageHighMem(page))
+@@ -2239,6 +2240,7 @@ bool kernel_page_present(struct page *page)
+ return (pte_val(*pte) & _PAGE_PRESENT);
+ }
+ #endif /* CONFIG_HIBERNATION */
++#endif /* CONFIG_DEBUG_PAGEALLOC */
+
+ int __init kernel_map_pages_in_pgd(pgd_t *pgd, u64 pfn, unsigned long address,
+ unsigned numpages, unsigned long page_flags)
+diff --git a/include/linux/mm.h b/include/linux/mm.h
+index 61ed8b20ea704..5c957fbef655b 100644
+--- a/include/linux/mm.h
++++ b/include/linux/mm.h
+@@ -2955,7 +2955,11 @@ static inline bool debug_pagealloc_enabled_static(void)
+ return static_branch_unlikely(&_debug_pagealloc_enabled);
+ }
+
+-#if defined(CONFIG_DEBUG_PAGEALLOC) || defined(CONFIG_ARCH_HAS_SET_DIRECT_MAP)
++#ifdef CONFIG_DEBUG_PAGEALLOC
++/*
++ * To support DEBUG_PAGEALLOC architecture must ensure that
++ * __kernel_map_pages() never fails
++ */
+ extern void __kernel_map_pages(struct page *page, int numpages, int enable);
+
+ static inline void debug_pagealloc_map_pages(struct page *page, int numpages)
+@@ -2973,13 +2977,13 @@ static inline void debug_pagealloc_unmap_pages(struct page *page, int numpages)
+ #ifdef CONFIG_HIBERNATION
+ extern bool kernel_page_present(struct page *page);
+ #endif /* CONFIG_HIBERNATION */
+-#else /* CONFIG_DEBUG_PAGEALLOC || CONFIG_ARCH_HAS_SET_DIRECT_MAP */
++#else /* CONFIG_DEBUG_PAGEALLOC */
+ static inline void debug_pagealloc_map_pages(struct page *page, int numpages) {}
+ static inline void debug_pagealloc_unmap_pages(struct page *page, int numpages) {}
+ #ifdef CONFIG_HIBERNATION
+ static inline bool kernel_page_present(struct page *page) { return true; }
+ #endif /* CONFIG_HIBERNATION */
+-#endif /* CONFIG_DEBUG_PAGEALLOC || CONFIG_ARCH_HAS_SET_DIRECT_MAP */
++#endif /* CONFIG_DEBUG_PAGEALLOC */
+
+ #ifdef __HAVE_ARCH_GATE_AREA
+ extern struct vm_area_struct *get_gate_vma(struct mm_struct *mm);
+--
+2.43.0
+
--- /dev/null
+From 80f534bf878947967c23c3707e2f49786c613a87 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 12 Mar 2024 19:31:03 +0100
+Subject: ARM: dts: samsung: exynos4412-origen: fix keypad no-autorepeat
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+
+[ Upstream commit 88208d3cd79821117fd3fb80d9bcab618467d37b ]
+
+Although the Samsung SoC keypad binding defined
+linux,keypad-no-autorepeat property, Linux driver never implemented it
+and always used linux,input-no-autorepeat. Correct the DTS to use
+property actually implemented.
+
+This also fixes dtbs_check errors like:
+
+ exynos4412-origen.dtb: keypad@100a0000: 'linux,keypad-no-autorepeat' does not match any of the regexes: '^key-[0-9a-z]+$', 'pinctrl-[0-9]+'
+
+Cc: <stable@vger.kernel.org>
+Fixes: bd08f6277e44 ("ARM: dts: Add keypad entries to Exynos4412 based Origen")
+Link: https://lore.kernel.org/r/20240312183105.715735-2-krzysztof.kozlowski@linaro.org
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/exynos4412-origen.dts | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm/boot/dts/exynos4412-origen.dts b/arch/arm/boot/dts/exynos4412-origen.dts
+index e2d76ea4404e8..7138bf291437e 100644
+--- a/arch/arm/boot/dts/exynos4412-origen.dts
++++ b/arch/arm/boot/dts/exynos4412-origen.dts
+@@ -447,7 +447,7 @@ buck9_reg: BUCK9 {
+ &keypad {
+ samsung,keypad-num-rows = <3>;
+ samsung,keypad-num-columns = <2>;
+- linux,keypad-no-autorepeat;
++ linux,input-no-autorepeat;
+ wakeup-source;
+ pinctrl-0 = <&keypad_rows &keypad_cols>;
+ pinctrl-names = "default";
+--
+2.43.0
+
--- /dev/null
+From 3000528e599655fb07c8721e38dce1113e1506b5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 12 Mar 2024 19:31:04 +0100
+Subject: ARM: dts: samsung: smdk4412: fix keypad no-autorepeat
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+
+[ Upstream commit 4ac4c1d794e7ff454d191bbdab7585ed8dbf3758 ]
+
+Although the Samsung SoC keypad binding defined
+linux,keypad-no-autorepeat property, Linux driver never implemented it
+and always used linux,input-no-autorepeat. Correct the DTS to use
+property actually implemented.
+
+This also fixes dtbs_check errors like:
+
+ exynos4412-smdk4412.dtb: keypad@100a0000: 'key-A', 'key-B', 'key-C', 'key-D', 'key-E', 'linux,keypad-no-autorepeat' do not match any of the regexes: '^key-[0-9a-z]+$', 'pinctrl-[0-9]+'
+
+Cc: <stable@vger.kernel.org>
+Fixes: c9b92dd70107 ("ARM: dts: Add keypad entries to SMDK4412")
+Link: https://lore.kernel.org/r/20240312183105.715735-3-krzysztof.kozlowski@linaro.org
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/exynos4412-smdk4412.dts | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm/boot/dts/exynos4412-smdk4412.dts b/arch/arm/boot/dts/exynos4412-smdk4412.dts
+index 49971203a8aa0..6e6bef907a72e 100644
+--- a/arch/arm/boot/dts/exynos4412-smdk4412.dts
++++ b/arch/arm/boot/dts/exynos4412-smdk4412.dts
+@@ -65,7 +65,7 @@ cooling_map1: map1 {
+ &keypad {
+ samsung,keypad-num-rows = <3>;
+ samsung,keypad-num-columns = <8>;
+- linux,keypad-no-autorepeat;
++ linux,input-no-autorepeat;
+ wakeup-source;
+ pinctrl-0 = <&keypad_rows &keypad_cols>;
+ pinctrl-names = "default";
+--
+2.43.0
+
--- /dev/null
+From c89ced90e68e2ca3e71114eea17731380f8f1853 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 12 Mar 2024 19:31:02 +0100
+Subject: ARM: dts: samsung: smdkv310: fix keypad no-autorepeat
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+
+[ Upstream commit 87d8e522d6f5a004f0aa06c0def302df65aff296 ]
+
+Although the Samsung SoC keypad binding defined
+linux,keypad-no-autorepeat property, Linux driver never implemented it
+and always used linux,input-no-autorepeat. Correct the DTS to use
+property actually implemented.
+
+This also fixes dtbs_check errors like:
+
+ exynos4210-smdkv310.dtb: keypad@100a0000: 'linux,keypad-no-autorepeat' does not match any of the regexes: '^key-[0-9a-z]+$', 'pinctrl-[0-9]+'
+
+Cc: <stable@vger.kernel.org>
+Fixes: 0561ceabd0f1 ("ARM: dts: Add intial dts file for EXYNOS4210 SoC, SMDKV310 and ORIGEN")
+Link: https://lore.kernel.org/r/20240312183105.715735-1-krzysztof.kozlowski@linaro.org
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/exynos4210-smdkv310.dts | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm/boot/dts/exynos4210-smdkv310.dts b/arch/arm/boot/dts/exynos4210-smdkv310.dts
+index c5609afa6101c..a6622a0d9b58b 100644
+--- a/arch/arm/boot/dts/exynos4210-smdkv310.dts
++++ b/arch/arm/boot/dts/exynos4210-smdkv310.dts
+@@ -84,7 +84,7 @@ eeprom@52 {
+ &keypad {
+ samsung,keypad-num-rows = <2>;
+ samsung,keypad-num-columns = <8>;
+- linux,keypad-no-autorepeat;
++ linux,input-no-autorepeat;
+ wakeup-source;
+ pinctrl-names = "default";
+ pinctrl-0 = <&keypad_rows &keypad_cols>;
+--
+2.43.0
+
--- /dev/null
+From 4d7775fa87d4a813fa37f8a35d60272557395c51 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 9 May 2024 09:11:17 +0800
+Subject: bcache: fix variable length array abuse in btree_iter
+
+From: Matthew Mirvish <matthew@mm12.xyz>
+
+[ Upstream commit 3a861560ccb35f2a4f0a4b8207fa7c2a35fc7f31 ]
+
+btree_iter is used in two ways: either allocated on the stack with a
+fixed size MAX_BSETS, or from a mempool with a dynamic size based on the
+specific cache set. Previously, the struct had a fixed-length array of
+size MAX_BSETS which was indexed out-of-bounds for the dynamically-sized
+iterators, which causes UBSAN to complain.
+
+This patch uses the same approach as in bcachefs's sort_iter and splits
+the iterator into a btree_iter with a flexible array member and a
+btree_iter_stack which embeds a btree_iter as well as a fixed-length
+data array.
+
+Cc: stable@vger.kernel.org
+Closes: https://bugs.launchpad.net/ubuntu/+source/linux/+bug/2039368
+Signed-off-by: Matthew Mirvish <matthew@mm12.xyz>
+Signed-off-by: Coly Li <colyli@suse.de>
+Link: https://lore.kernel.org/r/20240509011117.2697-3-colyli@suse.de
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/md/bcache/bset.c | 44 +++++++++++++++++------------------
+ drivers/md/bcache/bset.h | 28 ++++++++++++++--------
+ drivers/md/bcache/btree.c | 40 ++++++++++++++++---------------
+ drivers/md/bcache/super.c | 5 ++--
+ drivers/md/bcache/sysfs.c | 2 +-
+ drivers/md/bcache/writeback.c | 10 ++++----
+ 6 files changed, 70 insertions(+), 59 deletions(-)
+
+diff --git a/drivers/md/bcache/bset.c b/drivers/md/bcache/bset.c
+index 67a2c47f4201a..f006c780dd4bf 100644
+--- a/drivers/md/bcache/bset.c
++++ b/drivers/md/bcache/bset.c
+@@ -54,7 +54,7 @@ void bch_dump_bucket(struct btree_keys *b)
+ int __bch_count_data(struct btree_keys *b)
+ {
+ unsigned int ret = 0;
+- struct btree_iter iter;
++ struct btree_iter_stack iter;
+ struct bkey *k;
+
+ if (b->ops->is_extents)
+@@ -67,7 +67,7 @@ void __bch_check_keys(struct btree_keys *b, const char *fmt, ...)
+ {
+ va_list args;
+ struct bkey *k, *p = NULL;
+- struct btree_iter iter;
++ struct btree_iter_stack iter;
+ const char *err;
+
+ for_each_key(b, k, &iter) {
+@@ -877,7 +877,7 @@ unsigned int bch_btree_insert_key(struct btree_keys *b, struct bkey *k,
+ unsigned int status = BTREE_INSERT_STATUS_NO_INSERT;
+ struct bset *i = bset_tree_last(b)->data;
+ struct bkey *m, *prev = NULL;
+- struct btree_iter iter;
++ struct btree_iter_stack iter;
+ struct bkey preceding_key_on_stack = ZERO_KEY;
+ struct bkey *preceding_key_p = &preceding_key_on_stack;
+
+@@ -893,9 +893,9 @@ unsigned int bch_btree_insert_key(struct btree_keys *b, struct bkey *k,
+ else
+ preceding_key(k, &preceding_key_p);
+
+- m = bch_btree_iter_init(b, &iter, preceding_key_p);
++ m = bch_btree_iter_stack_init(b, &iter, preceding_key_p);
+
+- if (b->ops->insert_fixup(b, k, &iter, replace_key))
++ if (b->ops->insert_fixup(b, k, &iter.iter, replace_key))
+ return status;
+
+ status = BTREE_INSERT_STATUS_INSERT;
+@@ -1096,33 +1096,33 @@ void bch_btree_iter_push(struct btree_iter *iter, struct bkey *k,
+ btree_iter_cmp));
+ }
+
+-static struct bkey *__bch_btree_iter_init(struct btree_keys *b,
+- struct btree_iter *iter,
+- struct bkey *search,
+- struct bset_tree *start)
++static struct bkey *__bch_btree_iter_stack_init(struct btree_keys *b,
++ struct btree_iter_stack *iter,
++ struct bkey *search,
++ struct bset_tree *start)
+ {
+ struct bkey *ret = NULL;
+
+- iter->size = ARRAY_SIZE(iter->data);
+- iter->used = 0;
++ iter->iter.size = ARRAY_SIZE(iter->stack_data);
++ iter->iter.used = 0;
+
+ #ifdef CONFIG_BCACHE_DEBUG
+- iter->b = b;
++ iter->iter.b = b;
+ #endif
+
+ for (; start <= bset_tree_last(b); start++) {
+ ret = bch_bset_search(b, start, search);
+- bch_btree_iter_push(iter, ret, bset_bkey_last(start->data));
++ bch_btree_iter_push(&iter->iter, ret, bset_bkey_last(start->data));
+ }
+
+ return ret;
+ }
+
+-struct bkey *bch_btree_iter_init(struct btree_keys *b,
+- struct btree_iter *iter,
++struct bkey *bch_btree_iter_stack_init(struct btree_keys *b,
++ struct btree_iter_stack *iter,
+ struct bkey *search)
+ {
+- return __bch_btree_iter_init(b, iter, search, b->set);
++ return __bch_btree_iter_stack_init(b, iter, search, b->set);
+ }
+
+ static inline struct bkey *__bch_btree_iter_next(struct btree_iter *iter,
+@@ -1289,10 +1289,10 @@ void bch_btree_sort_partial(struct btree_keys *b, unsigned int start,
+ struct bset_sort_state *state)
+ {
+ size_t order = b->page_order, keys = 0;
+- struct btree_iter iter;
++ struct btree_iter_stack iter;
+ int oldsize = bch_count_data(b);
+
+- __bch_btree_iter_init(b, &iter, NULL, &b->set[start]);
++ __bch_btree_iter_stack_init(b, &iter, NULL, &b->set[start]);
+
+ if (start) {
+ unsigned int i;
+@@ -1303,7 +1303,7 @@ void bch_btree_sort_partial(struct btree_keys *b, unsigned int start,
+ order = get_order(__set_bytes(b->set->data, keys));
+ }
+
+- __btree_sort(b, &iter, start, order, false, state);
++ __btree_sort(b, &iter.iter, start, order, false, state);
+
+ EBUG_ON(oldsize >= 0 && bch_count_data(b) != oldsize);
+ }
+@@ -1319,11 +1319,11 @@ void bch_btree_sort_into(struct btree_keys *b, struct btree_keys *new,
+ struct bset_sort_state *state)
+ {
+ uint64_t start_time = local_clock();
+- struct btree_iter iter;
++ struct btree_iter_stack iter;
+
+- bch_btree_iter_init(b, &iter, NULL);
++ bch_btree_iter_stack_init(b, &iter, NULL);
+
+- btree_mergesort(b, new->set->data, &iter, false, true);
++ btree_mergesort(b, new->set->data, &iter.iter, false, true);
+
+ bch_time_stats_update(&state->time, start_time);
+
+diff --git a/drivers/md/bcache/bset.h b/drivers/md/bcache/bset.h
+index a50dcfda656f5..2ed6dbd35d6e5 100644
+--- a/drivers/md/bcache/bset.h
++++ b/drivers/md/bcache/bset.h
+@@ -321,7 +321,14 @@ struct btree_iter {
+ #endif
+ struct btree_iter_set {
+ struct bkey *k, *end;
+- } data[MAX_BSETS];
++ } data[];
++};
++
++/* Fixed-size btree_iter that can be allocated on the stack */
++
++struct btree_iter_stack {
++ struct btree_iter iter;
++ struct btree_iter_set stack_data[MAX_BSETS];
+ };
+
+ typedef bool (*ptr_filter_fn)(struct btree_keys *b, const struct bkey *k);
+@@ -333,9 +340,9 @@ struct bkey *bch_btree_iter_next_filter(struct btree_iter *iter,
+
+ void bch_btree_iter_push(struct btree_iter *iter, struct bkey *k,
+ struct bkey *end);
+-struct bkey *bch_btree_iter_init(struct btree_keys *b,
+- struct btree_iter *iter,
+- struct bkey *search);
++struct bkey *bch_btree_iter_stack_init(struct btree_keys *b,
++ struct btree_iter_stack *iter,
++ struct bkey *search);
+
+ struct bkey *__bch_bset_search(struct btree_keys *b, struct bset_tree *t,
+ const struct bkey *search);
+@@ -350,13 +357,14 @@ static inline struct bkey *bch_bset_search(struct btree_keys *b,
+ return search ? __bch_bset_search(b, t, search) : t->data->start;
+ }
+
+-#define for_each_key_filter(b, k, iter, filter) \
+- for (bch_btree_iter_init((b), (iter), NULL); \
+- ((k) = bch_btree_iter_next_filter((iter), (b), filter));)
++#define for_each_key_filter(b, k, stack_iter, filter) \
++ for (bch_btree_iter_stack_init((b), (stack_iter), NULL); \
++ ((k) = bch_btree_iter_next_filter(&((stack_iter)->iter), (b), \
++ filter));)
+
+-#define for_each_key(b, k, iter) \
+- for (bch_btree_iter_init((b), (iter), NULL); \
+- ((k) = bch_btree_iter_next(iter));)
++#define for_each_key(b, k, stack_iter) \
++ for (bch_btree_iter_stack_init((b), (stack_iter), NULL); \
++ ((k) = bch_btree_iter_next(&((stack_iter)->iter)));)
+
+ /* Sorting */
+
+diff --git a/drivers/md/bcache/btree.c b/drivers/md/bcache/btree.c
+index 1a1a9554474ae..2768b4b4302d6 100644
+--- a/drivers/md/bcache/btree.c
++++ b/drivers/md/bcache/btree.c
+@@ -1283,7 +1283,7 @@ static bool btree_gc_mark_node(struct btree *b, struct gc_stat *gc)
+ uint8_t stale = 0;
+ unsigned int keys = 0, good_keys = 0;
+ struct bkey *k;
+- struct btree_iter iter;
++ struct btree_iter_stack iter;
+ struct bset_tree *t;
+
+ gc->nodes++;
+@@ -1544,7 +1544,7 @@ static int btree_gc_rewrite_node(struct btree *b, struct btree_op *op,
+ static unsigned int btree_gc_count_keys(struct btree *b)
+ {
+ struct bkey *k;
+- struct btree_iter iter;
++ struct btree_iter_stack iter;
+ unsigned int ret = 0;
+
+ for_each_key_filter(&b->keys, k, &iter, bch_ptr_bad)
+@@ -1585,17 +1585,18 @@ static int btree_gc_recurse(struct btree *b, struct btree_op *op,
+ int ret = 0;
+ bool should_rewrite;
+ struct bkey *k;
+- struct btree_iter iter;
++ struct btree_iter_stack iter;
+ struct gc_merge_info r[GC_MERGE_NODES];
+ struct gc_merge_info *i, *last = r + ARRAY_SIZE(r) - 1;
+
+- bch_btree_iter_init(&b->keys, &iter, &b->c->gc_done);
++ bch_btree_iter_stack_init(&b->keys, &iter, &b->c->gc_done);
+
+ for (i = r; i < r + ARRAY_SIZE(r); i++)
+ i->b = ERR_PTR(-EINTR);
+
+ while (1) {
+- k = bch_btree_iter_next_filter(&iter, &b->keys, bch_ptr_bad);
++ k = bch_btree_iter_next_filter(&iter.iter, &b->keys,
++ bch_ptr_bad);
+ if (k) {
+ r->b = bch_btree_node_get(b->c, op, k, b->level - 1,
+ true, b);
+@@ -1885,7 +1886,7 @@ static int bch_btree_check_recurse(struct btree *b, struct btree_op *op)
+ {
+ int ret = 0;
+ struct bkey *k, *p = NULL;
+- struct btree_iter iter;
++ struct btree_iter_stack iter;
+
+ for_each_key_filter(&b->keys, k, &iter, bch_ptr_invalid)
+ bch_initial_mark_key(b->c, b->level, k);
+@@ -1893,10 +1894,10 @@ static int bch_btree_check_recurse(struct btree *b, struct btree_op *op)
+ bch_initial_mark_key(b->c, b->level + 1, &b->key);
+
+ if (b->level) {
+- bch_btree_iter_init(&b->keys, &iter, NULL);
++ bch_btree_iter_stack_init(&b->keys, &iter, NULL);
+
+ do {
+- k = bch_btree_iter_next_filter(&iter, &b->keys,
++ k = bch_btree_iter_next_filter(&iter.iter, &b->keys,
+ bch_ptr_bad);
+ if (k) {
+ btree_node_prefetch(b, k);
+@@ -1924,7 +1925,7 @@ static int bch_btree_check_thread(void *arg)
+ struct btree_check_info *info = arg;
+ struct btree_check_state *check_state = info->state;
+ struct cache_set *c = check_state->c;
+- struct btree_iter iter;
++ struct btree_iter_stack iter;
+ struct bkey *k, *p;
+ int cur_idx, prev_idx, skip_nr;
+
+@@ -1933,8 +1934,8 @@ static int bch_btree_check_thread(void *arg)
+ ret = 0;
+
+ /* root node keys are checked before thread created */
+- bch_btree_iter_init(&c->root->keys, &iter, NULL);
+- k = bch_btree_iter_next_filter(&iter, &c->root->keys, bch_ptr_bad);
++ bch_btree_iter_stack_init(&c->root->keys, &iter, NULL);
++ k = bch_btree_iter_next_filter(&iter.iter, &c->root->keys, bch_ptr_bad);
+ BUG_ON(!k);
+
+ p = k;
+@@ -1952,7 +1953,7 @@ static int bch_btree_check_thread(void *arg)
+ skip_nr = cur_idx - prev_idx;
+
+ while (skip_nr) {
+- k = bch_btree_iter_next_filter(&iter,
++ k = bch_btree_iter_next_filter(&iter.iter,
+ &c->root->keys,
+ bch_ptr_bad);
+ if (k)
+@@ -2025,7 +2026,7 @@ int bch_btree_check(struct cache_set *c)
+ int ret = 0;
+ int i;
+ struct bkey *k = NULL;
+- struct btree_iter iter;
++ struct btree_iter_stack iter;
+ struct btree_check_state check_state;
+
+ /* check and mark root node keys */
+@@ -2521,11 +2522,11 @@ static int bch_btree_map_nodes_recurse(struct btree *b, struct btree_op *op,
+
+ if (b->level) {
+ struct bkey *k;
+- struct btree_iter iter;
++ struct btree_iter_stack iter;
+
+- bch_btree_iter_init(&b->keys, &iter, from);
++ bch_btree_iter_stack_init(&b->keys, &iter, from);
+
+- while ((k = bch_btree_iter_next_filter(&iter, &b->keys,
++ while ((k = bch_btree_iter_next_filter(&iter.iter, &b->keys,
+ bch_ptr_bad))) {
+ ret = bcache_btree(map_nodes_recurse, k, b,
+ op, from, fn, flags);
+@@ -2554,11 +2555,12 @@ int bch_btree_map_keys_recurse(struct btree *b, struct btree_op *op,
+ {
+ int ret = MAP_CONTINUE;
+ struct bkey *k;
+- struct btree_iter iter;
++ struct btree_iter_stack iter;
+
+- bch_btree_iter_init(&b->keys, &iter, from);
++ bch_btree_iter_stack_init(&b->keys, &iter, from);
+
+- while ((k = bch_btree_iter_next_filter(&iter, &b->keys, bch_ptr_bad))) {
++ while ((k = bch_btree_iter_next_filter(&iter.iter, &b->keys,
++ bch_ptr_bad))) {
+ ret = !b->level
+ ? fn(op, b, k)
+ : bcache_btree(map_keys_recurse, k,
+diff --git a/drivers/md/bcache/super.c b/drivers/md/bcache/super.c
+index 04ddaa4bbd77f..14336fd541020 100644
+--- a/drivers/md/bcache/super.c
++++ b/drivers/md/bcache/super.c
+@@ -1939,8 +1939,9 @@ struct cache_set *bch_cache_set_alloc(struct cache_sb *sb)
+ INIT_LIST_HEAD(&c->btree_cache_freed);
+ INIT_LIST_HEAD(&c->data_buckets);
+
+- iter_size = ((meta_bucket_pages(sb) * PAGE_SECTORS) / sb->block_size + 1) *
+- sizeof(struct btree_iter_set);
++ iter_size = sizeof(struct btree_iter) +
++ ((meta_bucket_pages(sb) * PAGE_SECTORS) / sb->block_size) *
++ sizeof(struct btree_iter_set);
+
+ c->devices = kcalloc(c->nr_uuids, sizeof(void *), GFP_KERNEL);
+ if (!c->devices)
+diff --git a/drivers/md/bcache/sysfs.c b/drivers/md/bcache/sysfs.c
+index ca3e2f000cd4d..a31108625f463 100644
+--- a/drivers/md/bcache/sysfs.c
++++ b/drivers/md/bcache/sysfs.c
+@@ -639,7 +639,7 @@ static unsigned int bch_root_usage(struct cache_set *c)
+ unsigned int bytes = 0;
+ struct bkey *k;
+ struct btree *b;
+- struct btree_iter iter;
++ struct btree_iter_stack iter;
+
+ goto lock_root;
+
+diff --git a/drivers/md/bcache/writeback.c b/drivers/md/bcache/writeback.c
+index 8e3f5f004c397..9a2aac59f6bcb 100644
+--- a/drivers/md/bcache/writeback.c
++++ b/drivers/md/bcache/writeback.c
+@@ -852,15 +852,15 @@ static int bch_dirty_init_thread(void *arg)
+ struct dirty_init_thrd_info *info = arg;
+ struct bch_dirty_init_state *state = info->state;
+ struct cache_set *c = state->c;
+- struct btree_iter iter;
++ struct btree_iter_stack iter;
+ struct bkey *k, *p;
+ int cur_idx, prev_idx, skip_nr;
+
+ k = p = NULL;
+ prev_idx = 0;
+
+- bch_btree_iter_init(&c->root->keys, &iter, NULL);
+- k = bch_btree_iter_next_filter(&iter, &c->root->keys, bch_ptr_bad);
++ bch_btree_iter_stack_init(&c->root->keys, &iter, NULL);
++ k = bch_btree_iter_next_filter(&iter.iter, &c->root->keys, bch_ptr_bad);
+ BUG_ON(!k);
+
+ p = k;
+@@ -874,7 +874,7 @@ static int bch_dirty_init_thread(void *arg)
+ skip_nr = cur_idx - prev_idx;
+
+ while (skip_nr) {
+- k = bch_btree_iter_next_filter(&iter,
++ k = bch_btree_iter_next_filter(&iter.iter,
+ &c->root->keys,
+ bch_ptr_bad);
+ if (k)
+@@ -923,7 +923,7 @@ void bch_sectors_dirty_init(struct bcache_device *d)
+ int i;
+ struct btree *b = NULL;
+ struct bkey *k = NULL;
+- struct btree_iter iter;
++ struct btree_iter_stack iter;
+ struct sectors_dirty_init op;
+ struct cache_set *c = d->c;
+ struct bch_dirty_init_state state;
+--
+2.43.0
+
--- /dev/null
+From 5676509437fd421471aec602841d76f29ad0e48f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 23 May 2021 16:54:42 +0000
+Subject: cifs: missed ref-counting smb session in find
+
+From: Shyam Prasad N <sprasad@microsoft.com>
+
+[ Upstream commit e695a9ad0305af6e8b0cbc24a54976ac2120cbb3 ]
+
+When we lookup an smb session based on session id,
+we did not up the ref-count for the session. This can
+potentially cause issues if the session is freed from under us.
+
+Signed-off-by: Shyam Prasad N <sprasad@microsoft.com>
+Reviewed-by: Aurelien Aptel <aaptel@suse.com>
+Reviewed-by: Paulo Alcantara (SUSE) <pc@cjr.nz>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Stable-dep-of: 02c418774f76 ("smb: client: fix deadlock in smb2_find_smb_tcon()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/cifs/smb2transport.c | 12 +++++++++++-
+ 1 file changed, 11 insertions(+), 1 deletion(-)
+
+diff --git a/fs/cifs/smb2transport.c b/fs/cifs/smb2transport.c
+index d659eb70df76d..f40b8de2aeeb3 100644
+--- a/fs/cifs/smb2transport.c
++++ b/fs/cifs/smb2transport.c
+@@ -154,6 +154,7 @@ smb2_find_smb_ses_unlocked(struct TCP_Server_Info *server, __u64 ses_id)
+ list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) {
+ if (ses->Suid != ses_id)
+ continue;
++ ++ses->ses_count;
+ return ses;
+ }
+
+@@ -205,7 +206,14 @@ smb2_find_smb_tcon(struct TCP_Server_Info *server, __u64 ses_id, __u32 tid)
+ return NULL;
+ }
+ tcon = smb2_find_smb_sess_tcon_unlocked(ses, tid);
++ if (!tcon) {
++ cifs_put_smb_ses(ses);
++ spin_unlock(&cifs_tcp_ses_lock);
++ return NULL;
++ }
+ spin_unlock(&cifs_tcp_ses_lock);
++ /* tcon already has a ref to ses, so we don't need ses anymore */
++ cifs_put_smb_ses(ses);
+
+ return tcon;
+ }
+@@ -239,7 +247,7 @@ smb2_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server,
+ if (rc) {
+ cifs_server_dbg(VFS,
+ "%s: sha256 alloc failed\n", __func__);
+- return rc;
++ goto out;
+ }
+ shash = &sdesc->shash;
+ } else {
+@@ -290,6 +298,8 @@ smb2_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server,
+ out:
+ if (allocate_crypto)
+ cifs_free_hash(&hash, &sdesc);
++ if (ses)
++ cifs_put_smb_ses(ses);
+ return rc;
+ }
+
+--
+2.43.0
+
--- /dev/null
+From 78cbc9a916e025099cbd2575c23e96ab651b20cc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 19 Sep 2020 16:21:53 -0400
+Subject: drm/amdgpu/atomfirmware: Add edp and integrated info v2.1 tables
+
+From: Roman Li <Roman.Li@amd.com>
+
+[ Upstream commit b9d90cb031c488d77a47084a009655d235e3d765 ]
+
+Required for vangogh.
+
+Signed-off-by: Roman Li <Roman.Li@amd.com>
+Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
+Reviewed-by: Harry Wentland <harry.wentland@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Stable-dep-of: e64e8f7c178e ("drm/amdgpu/atomfirmware: add intergrated info v2.3 table")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/include/atomfirmware.h | 62 +++++++++++++++++++++-
+ 1 file changed, 61 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/amd/include/atomfirmware.h b/drivers/gpu/drm/amd/include/atomfirmware.h
+index 0799a9ca04401..4eb578b1baef1 100644
+--- a/drivers/gpu/drm/amd/include/atomfirmware.h
++++ b/drivers/gpu/drm/amd/include/atomfirmware.h
+@@ -1304,11 +1304,71 @@ struct atom_integrated_system_info_v1_12
+ struct atom_hdmi_retimer_redriver_set dp3_retimer_set; //for DP3
+ struct atom_DCN_dpphy_dp_tuningset hbr_tuningset; //hbr 2.7G dp tuning set
+ struct atom_DCN_dpphy_dp_tuningset hbr2_tuningset; //hbr2 5.4G dp turnig set
+- struct atom_DCN_dpphy_dp_tuningset edp_tunings; //edp tuning set
++ struct atom_DCN_dpphy_dp_tuningset edp_tunings; //edp tuning set
+ struct atom_DCN_dpphy_dvihdmi_tuningset hdmiCLK6_tuningset;
+ uint32_t reserved[63];
+ };
+
++
++#if defined(CONFIG_DRM_AMD_DC_DCN3_01)
++
++struct edp_info_table
++{
++ uint16_t edp_backlight_pwm_hz;
++ uint16_t edp_ss_percentage;
++ uint16_t edp_ss_rate_10hz;
++ uint16_t reserved1;
++ uint32_t reserved2;
++ uint8_t edp_pwr_on_off_delay;
++ uint8_t edp_pwr_on_vary_bl_to_blon;
++ uint8_t edp_pwr_down_bloff_to_vary_bloff;
++ uint8_t edp_panel_bpc;
++ uint8_t edp_bootup_bl_level;
++ uint8_t reserved3[3];
++ uint32_t reserved4[3];
++};
++
++struct atom_integrated_system_info_v2_1
++{
++ struct atom_common_table_header table_header;
++ uint32_t vbios_misc; //enum of atom_system_vbiosmisc_def
++ uint32_t gpucapinfo; //enum of atom_system_gpucapinf_def
++ uint32_t system_config;
++ uint32_t cpucapinfo;
++ uint16_t gpuclk_ss_percentage; //unit of 0.001%, 1000 mean 1%
++ uint16_t gpuclk_ss_type;
++ uint16_t dpphy_override; // bit vector, enum of atom_sysinfo_dpphy_override_def
++ uint8_t memorytype; // enum of atom_dmi_t17_mem_type_def, APU memory type indication.
++ uint8_t umachannelnumber; // number of memory channels
++ uint8_t htc_hyst_limit;
++ uint8_t htc_tmp_limit;
++ uint8_t reserved1;
++ uint8_t reserved2;
++ struct edp_info_table edp1_info;
++ struct edp_info_table edp2_info;
++ uint32_t reserved3[8];
++ struct atom_external_display_connection_info extdispconninfo;
++ struct atom_DCN_dpphy_dvihdmi_tuningset TMDS_tuningset;
++ struct atom_DCN_dpphy_dvihdmi_tuningset hdmiCLK5_tuningset; //add clk6
++ struct atom_DCN_dpphy_dvihdmi_tuningset hdmiCLK6_tuningset;
++ struct atom_DCN_dpphy_dvihdmi_tuningset hdmiCLK8_tuningset;
++ uint32_t reserved4[6];//reserve 2*sizeof(atom_DCN_dpphy_dvihdmi_tuningset)
++ struct atom_DCN_dpphy_dp_tuningset rbr_tuningset; // rbr 1.62G dp tuning set
++ struct atom_DCN_dpphy_dp_tuningset hbr_tuningset; //hbr 2.7G dp tuning set
++ struct atom_DCN_dpphy_dp_tuningset hbr2_tuningset; //hbr2 5.4G dp turnig set
++ struct atom_DCN_dpphy_dp_tuningset hbr3_tuningset; // HBR3 dp tuning set
++ struct atom_DCN_dpphy_dp_tuningset edp_tunings; //edp tuning set
++ uint32_t reserved5[28];//reserve 2*sizeof(atom_DCN_dpphy_dp_tuningset)
++ struct atom_hdmi_retimer_redriver_set dp0_retimer_set; //for DP0
++ struct atom_hdmi_retimer_redriver_set dp1_retimer_set; //for DP1
++ struct atom_hdmi_retimer_redriver_set dp2_retimer_set; //for DP2
++ struct atom_hdmi_retimer_redriver_set dp3_retimer_set; //for DP3
++ uint32_t reserved6[30];// reserve size of(atom_camera_data) for camera_info
++ uint32_t reserved7[32];
++
++};
++#endif
++
+ // system_config
+ enum atom_system_vbiosmisc_def{
+ INTEGRATED_SYSTEM_INFO__GET_EDID_CALLBACK_FUNC_SUPPORT = 0x01,
+--
+2.43.0
+
--- /dev/null
+From 932a1db41ed0a5e087fc7d9ca22b94e03948c132 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 20 May 2024 18:43:55 +0800
+Subject: drm/amdgpu/atomfirmware: add intergrated info v2.3 table
+
+From: Li Ma <li.ma@amd.com>
+
+[ Upstream commit e64e8f7c178e5228e0b2dbb504b9dc75953a319f ]
+
+[Why]
+The vram width value is 0.
+Because the integratedsysteminfo table in VBIOS has updated to 2.3.
+
+[How]
+Driver needs a new intergrated info v2.3 table too.
+Then the vram width value will be correct.
+
+Signed-off-by: Li Ma <li.ma@amd.com>
+Reviewed-by: Yifan Zhang <yifan1.zhang@amd.com>
+Acked-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c | 15 +++++++
+ drivers/gpu/drm/amd/include/atomfirmware.h | 43 +++++++++++++++++++
+ 2 files changed, 58 insertions(+)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c
+index c5ebf8ee66bc4..f71fbdc02e111 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c
+@@ -113,6 +113,7 @@ union igp_info {
+ struct atom_integrated_system_info_v1_11 v11;
+ struct atom_integrated_system_info_v1_12 v12;
+ struct atom_integrated_system_info_v2_1 v21;
++ struct atom_integrated_system_info_v2_3 v23;
+ };
+
+ union umc_info {
+@@ -239,6 +240,20 @@ amdgpu_atomfirmware_get_vram_info(struct amdgpu_device *adev,
+ if (vram_type)
+ *vram_type = convert_atom_mem_type_to_vram_type(adev, mem_type);
+ break;
++ case 3:
++ mem_channel_number = igp_info->v23.umachannelnumber;
++ if (!mem_channel_number)
++ mem_channel_number = 1;
++ mem_type = igp_info->v23.memorytype;
++ if (mem_type == LpDdr5MemType)
++ mem_channel_width = 32;
++ else
++ mem_channel_width = 64;
++ if (vram_width)
++ *vram_width = mem_channel_number * mem_channel_width;
++ if (vram_type)
++ *vram_type = convert_atom_mem_type_to_vram_type(adev, mem_type);
++ break;
+ default:
+ return -EINVAL;
+ }
+diff --git a/drivers/gpu/drm/amd/include/atomfirmware.h b/drivers/gpu/drm/amd/include/atomfirmware.h
+index c7cfe9d9096dc..7465f84ba5664 100644
+--- a/drivers/gpu/drm/amd/include/atomfirmware.h
++++ b/drivers/gpu/drm/amd/include/atomfirmware.h
+@@ -1419,6 +1419,49 @@ struct atom_integrated_system_info_v2_2
+ uint32_t reserved4[189];
+ };
+
++struct uma_carveout_option {
++ char optionName[29]; //max length of string is 28chars + '\0'. Current design is for "minimum", "Medium", "High". This makes entire struct size 64bits
++ uint8_t memoryCarvedGb; //memory carved out with setting
++ uint8_t memoryRemainingGb; //memory remaining on system
++ union {
++ struct _flags {
++ uint8_t Auto : 1;
++ uint8_t Custom : 1;
++ uint8_t Reserved : 6;
++ } flags;
++ uint8_t all8;
++ } uma_carveout_option_flags;
++};
++
++struct atom_integrated_system_info_v2_3 {
++ struct atom_common_table_header table_header;
++ uint32_t vbios_misc; // enum of atom_system_vbiosmisc_def
++ uint32_t gpucapinfo; // enum of atom_system_gpucapinf_def
++ uint32_t system_config;
++ uint32_t cpucapinfo;
++ uint16_t gpuclk_ss_percentage; // unit of 0.001%, 1000 mean 1%
++ uint16_t gpuclk_ss_type;
++ uint16_t dpphy_override; // bit vector, enum of atom_sysinfo_dpphy_override_def
++ uint8_t memorytype; // enum of atom_dmi_t17_mem_type_def, APU memory type indication.
++ uint8_t umachannelnumber; // number of memory channels
++ uint8_t htc_hyst_limit;
++ uint8_t htc_tmp_limit;
++ uint8_t reserved1; // dp_ss_control
++ uint8_t gpu_package_id;
++ struct edp_info_table edp1_info;
++ struct edp_info_table edp2_info;
++ uint32_t reserved2[8];
++ struct atom_external_display_connection_info extdispconninfo;
++ uint8_t UMACarveoutVersion;
++ uint8_t UMACarveoutIndexMax;
++ uint8_t UMACarveoutTypeDefault;
++ uint8_t UMACarveoutIndexDefault;
++ uint8_t UMACarveoutType; //Auto or Custom
++ uint8_t UMACarveoutIndex;
++ struct uma_carveout_option UMASizeControlOption[20];
++ uint8_t reserved3[110];
++};
++
+ // system_config
+ enum atom_system_vbiosmisc_def{
+ INTEGRATED_SYSTEM_INFO__GET_EDID_CALLBACK_FUNC_SUPPORT = 0x01,
+--
+2.43.0
+
--- /dev/null
+From 0e0594d117ca71ec4d4017b17d20160c871c64c8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 16 Oct 2020 11:42:00 -0400
+Subject: drm/amdgpu: drop CONFIG_DRM_AMD_DC_DCN3_01 from atomfirmware.h
+
+From: Alex Deucher <alexander.deucher@amd.com>
+
+[ Upstream commit 15047bd436a763dd2ddf8e1024b4e25af9cc11ee ]
+
+Not needed.
+
+Reviewed-by: Luben Tuikov <luben.tuikov@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Stable-dep-of: e64e8f7c178e ("drm/amdgpu/atomfirmware: add intergrated info v2.3 table")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/include/atomfirmware.h | 4 ----
+ 1 file changed, 4 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/include/atomfirmware.h b/drivers/gpu/drm/amd/include/atomfirmware.h
+index 4eb578b1baef1..6139d10f4289d 100644
+--- a/drivers/gpu/drm/amd/include/atomfirmware.h
++++ b/drivers/gpu/drm/amd/include/atomfirmware.h
+@@ -1309,9 +1309,6 @@ struct atom_integrated_system_info_v1_12
+ uint32_t reserved[63];
+ };
+
+-
+-#if defined(CONFIG_DRM_AMD_DC_DCN3_01)
+-
+ struct edp_info_table
+ {
+ uint16_t edp_backlight_pwm_hz;
+@@ -1367,7 +1364,6 @@ struct atom_integrated_system_info_v2_1
+ uint32_t reserved7[32];
+
+ };
+-#endif
+
+ // system_config
+ enum atom_system_vbiosmisc_def{
+--
+2.43.0
+
--- /dev/null
+From 5bbed97f73987016b4f084c882125bc76c7fca74 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 Jan 2021 20:13:17 +0800
+Subject: drm/amdgpu: fix vram type and bandwidth error for DDR5 and DDR4
+
+From: Huang Rui <ray.huang@amd.com>
+
+[ Upstream commit 78683229ddeef56ba62e4b680c6394ea97f88d6c ]
+
+This patch is to update atomfirmware parser for the memory type and
+bandwidth of DDR5 and DDR4.
+
+Signed-off-by: Huang Rui <ray.huang@amd.com>
+Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Stable-dep-of: e64e8f7c178e ("drm/amdgpu/atomfirmware: add intergrated info v2.3 table")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c | 53 +++++++++++++------
+ 1 file changed, 36 insertions(+), 17 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c
+index b4df6460e45a9..c5ebf8ee66bc4 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c
+@@ -112,6 +112,7 @@ int amdgpu_atomfirmware_allocate_fb_scratch(struct amdgpu_device *adev)
+ union igp_info {
+ struct atom_integrated_system_info_v1_11 v11;
+ struct atom_integrated_system_info_v1_12 v12;
++ struct atom_integrated_system_info_v2_1 v21;
+ };
+
+ union umc_info {
+@@ -205,24 +206,42 @@ amdgpu_atomfirmware_get_vram_info(struct amdgpu_device *adev,
+ if (adev->flags & AMD_IS_APU) {
+ igp_info = (union igp_info *)
+ (mode_info->atom_context->bios + data_offset);
+- switch (crev) {
+- case 11:
+- mem_channel_number = igp_info->v11.umachannelnumber;
+- /* channel width is 64 */
+- if (vram_width)
+- *vram_width = mem_channel_number * 64;
+- mem_type = igp_info->v11.memorytype;
+- if (vram_type)
+- *vram_type = convert_atom_mem_type_to_vram_type(adev, mem_type);
++ switch (frev) {
++ case 1:
++ switch (crev) {
++ case 11:
++ case 12:
++ mem_channel_number = igp_info->v11.umachannelnumber;
++ if (!mem_channel_number)
++ mem_channel_number = 1;
++ /* channel width is 64 */
++ if (vram_width)
++ *vram_width = mem_channel_number * 64;
++ mem_type = igp_info->v11.memorytype;
++ if (vram_type)
++ *vram_type = convert_atom_mem_type_to_vram_type(adev, mem_type);
++ break;
++ default:
++ return -EINVAL;
++ }
+ break;
+- case 12:
+- mem_channel_number = igp_info->v12.umachannelnumber;
+- /* channel width is 64 */
+- if (vram_width)
+- *vram_width = mem_channel_number * 64;
+- mem_type = igp_info->v12.memorytype;
+- if (vram_type)
+- *vram_type = convert_atom_mem_type_to_vram_type(adev, mem_type);
++ case 2:
++ switch (crev) {
++ case 1:
++ case 2:
++ mem_channel_number = igp_info->v21.umachannelnumber;
++ if (!mem_channel_number)
++ mem_channel_number = 1;
++ /* channel width is 64 */
++ if (vram_width)
++ *vram_width = mem_channel_number * 64;
++ mem_type = igp_info->v21.memorytype;
++ if (vram_type)
++ *vram_type = convert_atom_mem_type_to_vram_type(adev, mem_type);
++ break;
++ default:
++ return -EINVAL;
++ }
+ break;
+ default:
+ return -EINVAL;
+--
+2.43.0
+
--- /dev/null
+From 75053bfdbb4d78694076e47c1e13fef25084a7bf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 19 May 2021 10:38:47 -0400
+Subject: drm/amdgpu: Update atomfirmware for DCN3.1 phy tuning and eDP caps
+
+From: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
+
+[ Upstream commit 753625643e218eb72a6e7b7df87db595a446931a ]
+
+[Why & How]
+We'll need these in driver for phy tuning in DCN3.1.
+
+Multiple eDP support also requires understanding which LCD the backlight
+curve in atombios is for.
+
+Acked-by: Huang Rui <ray.huang@amd.com>
+Signed-off-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Stable-dep-of: e64e8f7c178e ("drm/amdgpu/atomfirmware: add intergrated info v2.3 table")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/include/atomfirmware.h | 56 +++++++++++++++++++++-
+ 1 file changed, 55 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/amd/include/atomfirmware.h b/drivers/gpu/drm/amd/include/atomfirmware.h
+index 6139d10f4289d..c7cfe9d9096dc 100644
+--- a/drivers/gpu/drm/amd/include/atomfirmware.h
++++ b/drivers/gpu/drm/amd/include/atomfirmware.h
+@@ -871,7 +871,8 @@ struct atom_bracket_layout_record
+ };
+
+ enum atom_display_device_tag_def{
+- ATOM_DISPLAY_LCD1_SUPPORT = 0x0002, //an embedded display is either an LVDS or eDP signal type of display
++ ATOM_DISPLAY_LCD1_SUPPORT = 0x0002, //an embedded display is either an LVDS or eDP signal type of display
++ ATOM_DISPLAY_LCD2_SUPPORT = 0x0020, //second edp device tag 0x0020 for backward compability
+ ATOM_DISPLAY_DFP1_SUPPORT = 0x0008,
+ ATOM_DISPLAY_DFP2_SUPPORT = 0x0080,
+ ATOM_DISPLAY_DFP3_SUPPORT = 0x0200,
+@@ -1365,6 +1366,59 @@ struct atom_integrated_system_info_v2_1
+
+ };
+
++struct atom_n6_display_phy_tuning_set {
++ uint8_t display_signal_type;
++ uint8_t phy_sel;
++ uint8_t preset_level;
++ uint8_t reserved1;
++ uint32_t reserved2;
++ uint32_t speed_upto;
++ uint8_t tx_vboost_level;
++ uint8_t tx_vreg_v2i;
++ uint8_t tx_vregdrv_byp;
++ uint8_t tx_term_cntl;
++ uint8_t tx_peak_level;
++ uint8_t tx_slew_en;
++ uint8_t tx_eq_pre;
++ uint8_t tx_eq_main;
++ uint8_t tx_eq_post;
++ uint8_t tx_en_inv_pre;
++ uint8_t tx_en_inv_post;
++ uint8_t reserved3;
++ uint32_t reserved4;
++ uint32_t reserved5;
++ uint32_t reserved6;
++};
++
++struct atom_display_phy_tuning_info {
++ struct atom_common_table_header table_header;
++ struct atom_n6_display_phy_tuning_set disp_phy_tuning[1];
++};
++
++struct atom_integrated_system_info_v2_2
++{
++ struct atom_common_table_header table_header;
++ uint32_t vbios_misc; //enum of atom_system_vbiosmisc_def
++ uint32_t gpucapinfo; //enum of atom_system_gpucapinf_def
++ uint32_t system_config;
++ uint32_t cpucapinfo;
++ uint16_t gpuclk_ss_percentage; //unit of 0.001%, 1000 mean 1%
++ uint16_t gpuclk_ss_type;
++ uint16_t dpphy_override; // bit vector, enum of atom_sysinfo_dpphy_override_def
++ uint8_t memorytype; // enum of atom_dmi_t17_mem_type_def, APU memory type indication.
++ uint8_t umachannelnumber; // number of memory channels
++ uint8_t htc_hyst_limit;
++ uint8_t htc_tmp_limit;
++ uint8_t reserved1;
++ uint8_t reserved2;
++ struct edp_info_table edp1_info;
++ struct edp_info_table edp2_info;
++ uint32_t reserved3[8];
++ struct atom_external_display_connection_info extdispconninfo;
++
++ uint32_t reserved4[189];
++};
++
+ // system_config
+ enum atom_system_vbiosmisc_def{
+ INTEGRATED_SYSTEM_INFO__GET_EDID_CALLBACK_FUNC_SUPPORT = 0x01,
+--
+2.43.0
+
--- /dev/null
+From db94fa5f8f6d8f6f19747a278de06dabfebd8a53 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 28 Aug 2020 17:50:33 +0800
+Subject: drm/amdgpu: update new memory types in atomfirmware header
+
+From: Huang Rui <ray.huang@amd.com>
+
+[ Upstream commit af118ed9ef9fc6c6cc37f2db3d4aa2b66b2c4335 ]
+
+Add new nemory types in atomfirmware header.
+
+Signed-off-by: Huang Rui <ray.huang@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Stable-dep-of: e64e8f7c178e ("drm/amdgpu/atomfirmware: add intergrated info v2.3 table")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/include/atomfirmware.h | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/drivers/gpu/drm/amd/include/atomfirmware.h b/drivers/gpu/drm/amd/include/atomfirmware.h
+index 3e526c394f6cb..0799a9ca04401 100644
+--- a/drivers/gpu/drm/amd/include/atomfirmware.h
++++ b/drivers/gpu/drm/amd/include/atomfirmware.h
+@@ -1367,6 +1367,11 @@ enum atom_dmi_t17_mem_type_def{
+ LpDdr2MemType, ///< Assign 28 to LPDDR2
+ LpDdr3MemType, ///< Assign 29 to LPDDR3
+ LpDdr4MemType, ///< Assign 30 to LPDDR4
++ GDdr6MemType, ///< Assign 31 to GDDR6
++ HbmMemType, ///< Assign 32 to HBM
++ Hbm2MemType, ///< Assign 33 to HBM2
++ Ddr5MemType, ///< Assign 34 to DDR5
++ LpDdr5MemType, ///< Assign 35 to LPDDR5
+ };
+
+
+--
+2.43.0
+
--- /dev/null
+From d1db0e66c6334a4167e4e6cf10db5b7c237296ef Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 28 May 2024 11:32:43 +0000
+Subject: kheaders: explicitly define file modes for archived headers
+
+From: Matthias Maennich <maennich@google.com>
+
+[ Upstream commit 3bd27a847a3a4827a948387cc8f0dbc9fa5931d5 ]
+
+Build environments might be running with different umask settings
+resulting in indeterministic file modes for the files contained in
+kheaders.tar.xz. The file itself is served with 444, i.e. world
+readable. Archive the files explicitly with 744,a+X to improve
+reproducibility across build environments.
+
+--mode=0444 is not suitable as directories need to be executable. Also,
+444 makes it hard to delete all the readonly files after extraction.
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Matthias Maennich <maennich@google.com>
+Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/gen_kheaders.sh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/kernel/gen_kheaders.sh b/kernel/gen_kheaders.sh
+index d7e827c6cd2d2..206ab3d41ee76 100755
+--- a/kernel/gen_kheaders.sh
++++ b/kernel/gen_kheaders.sh
+@@ -84,7 +84,7 @@ find $cpio_dir -type f -print0 |
+
+ # Create archive and try to normalize metadata for reproducibility.
+ tar "${KBUILD_BUILD_TIMESTAMP:+--mtime=$KBUILD_BUILD_TIMESTAMP}" \
+- --owner=0 --group=0 --sort=name --numeric-owner \
++ --owner=0 --group=0 --sort=name --numeric-owner --mode=u=rw,go=r,a+X \
+ -I $XZ -cf $tarfile -C $cpio_dir/ . > /dev/null
+
+ echo $headers_md5 > kernel/kheaders.md5
+--
+2.43.0
+
--- /dev/null
+From 07ed118b48ba24f17ad7c4d80adc8cb6f4e0619a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 6 May 2024 12:30:04 -0400
+Subject: knfsd: LOOKUP can return an illegal error value
+
+From: Trond Myklebust <trond.myklebust@hammerspace.com>
+
+[ Upstream commit e221c45da3770962418fb30c27d941bbc70d595a ]
+
+The 'NFS error' NFSERR_OPNOTSUPP is not described by any of the official
+NFS related RFCs, but appears to have snuck into some older .x files for
+NFSv2.
+Either way, it is not in RFC1094, RFC1813 or any of the NFSv4 RFCs, so
+should not be returned by the knfsd server, and particularly not by the
+"LOOKUP" operation.
+
+Instead, let's return NFSERR_STALE, which is more appropriate if the
+filesystem encodes the filehandle as FILEID_INVALID.
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
+Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfsd/nfsfh.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c
+index db8d62632a5be..ae3323e0708dd 100644
+--- a/fs/nfsd/nfsfh.c
++++ b/fs/nfsd/nfsfh.c
+@@ -573,7 +573,7 @@ fh_compose(struct svc_fh *fhp, struct svc_export *exp, struct dentry *dentry,
+ _fh_update(fhp, exp, dentry);
+ if (fhp->fh_handle.fh_fileid_type == FILEID_INVALID) {
+ fh_put(fhp);
+- return nfserr_opnotsupp;
++ return nfserr_stale;
+ }
+
+ return 0;
+@@ -599,7 +599,7 @@ fh_update(struct svc_fh *fhp)
+
+ _fh_update(fhp, fhp->fh_export, dentry);
+ if (fhp->fh_handle.fh_fileid_type == FILEID_INVALID)
+- return nfserr_opnotsupp;
++ return nfserr_stale;
+ return 0;
+ out_bad:
+ printk(KERN_ERR "fh_update: fh not verified!\n");
+--
+2.43.0
+
--- /dev/null
+From a25514ea7731b0f9a21c67b2a8de9787b31dcd83 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Dec 2020 19:10:20 -0800
+Subject: mm: introduce debug_pagealloc_{map,unmap}_pages() helpers
+
+From: Mike Rapoport <rppt@linux.ibm.com>
+
+[ Upstream commit 77bc7fd607dee2ffb28daff6d0dd8ae42af61ea8 ]
+
+Patch series "arch, mm: improve robustness of direct map manipulation", v7.
+
+During recent discussion about KVM protected memory, David raised a
+concern about usage of __kernel_map_pages() outside of DEBUG_PAGEALLOC
+scope [1].
+
+Indeed, for architectures that define CONFIG_ARCH_HAS_SET_DIRECT_MAP it is
+possible that __kernel_map_pages() would fail, but since this function is
+void, the failure will go unnoticed.
+
+Moreover, there's lack of consistency of __kernel_map_pages() semantics
+across architectures as some guard this function with #ifdef
+DEBUG_PAGEALLOC, some refuse to update the direct map if page allocation
+debugging is disabled at run time and some allow modifying the direct map
+regardless of DEBUG_PAGEALLOC settings.
+
+This set straightens this out by restoring dependency of
+__kernel_map_pages() on DEBUG_PAGEALLOC and updating the call sites
+accordingly.
+
+Since currently the only user of __kernel_map_pages() outside
+DEBUG_PAGEALLOC is hibernation, it is updated to make direct map accesses
+there more explicit.
+
+[1] https://lore.kernel.org/lkml/2759b4bf-e1e3-d006-7d86-78a40348269d@redhat.com
+
+This patch (of 4):
+
+When CONFIG_DEBUG_PAGEALLOC is enabled, it unmaps pages from the kernel
+direct mapping after free_pages(). The pages than need to be mapped back
+before they could be used. Theese mapping operations use
+__kernel_map_pages() guarded with with debug_pagealloc_enabled().
+
+The only place that calls __kernel_map_pages() without checking whether
+DEBUG_PAGEALLOC is enabled is the hibernation code that presumes
+availability of this function when ARCH_HAS_SET_DIRECT_MAP is set. Still,
+on arm64, __kernel_map_pages() will bail out when DEBUG_PAGEALLOC is not
+enabled but set_direct_map_invalid_noflush() may render some pages not
+present in the direct map and hibernation code won't be able to save such
+pages.
+
+To make page allocation debugging and hibernation interaction more robust,
+the dependency on DEBUG_PAGEALLOC or ARCH_HAS_SET_DIRECT_MAP has to be
+made more explicit.
+
+Start with combining the guard condition and the call to
+__kernel_map_pages() into debug_pagealloc_map_pages() and
+debug_pagealloc_unmap_pages() functions to emphasize that
+__kernel_map_pages() should not be called without DEBUG_PAGEALLOC and use
+these new functions to map/unmap pages when page allocation debugging is
+enabled.
+
+Link: https://lkml.kernel.org/r/20201109192128.960-1-rppt@kernel.org
+Link: https://lkml.kernel.org/r/20201109192128.960-2-rppt@kernel.org
+Signed-off-by: Mike Rapoport <rppt@linux.ibm.com>
+Reviewed-by: David Hildenbrand <david@redhat.com>
+Acked-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
+Acked-by: Vlastimil Babka <vbabka@suse.cz>
+Cc: Albert Ou <aou@eecs.berkeley.edu>
+Cc: Andy Lutomirski <luto@kernel.org>
+Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
+Cc: Borislav Petkov <bp@alien8.de>
+Cc: Catalin Marinas <catalin.marinas@arm.com>
+Cc: Christian Borntraeger <borntraeger@de.ibm.com>
+Cc: Christoph Lameter <cl@linux.com>
+Cc: "David S. Miller" <davem@davemloft.net>
+Cc: Dave Hansen <dave.hansen@linux.intel.com>
+Cc: David Rientjes <rientjes@google.com>
+Cc: "Edgecombe, Rick P" <rick.p.edgecombe@intel.com>
+Cc: "H. Peter Anvin" <hpa@zytor.com>
+Cc: Heiko Carstens <hca@linux.ibm.com>
+Cc: Ingo Molnar <mingo@redhat.com>
+Cc: Joonsoo Kim <iamjoonsoo.kim@lge.com>
+Cc: Len Brown <len.brown@intel.com>
+Cc: Michael Ellerman <mpe@ellerman.id.au>
+Cc: Palmer Dabbelt <palmer@dabbelt.com>
+Cc: Paul Mackerras <paulus@samba.org>
+Cc: Paul Walmsley <paul.walmsley@sifive.com>
+Cc: Pavel Machek <pavel@ucw.cz>
+Cc: Pekka Enberg <penberg@kernel.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: Vasily Gorbik <gor@linux.ibm.com>
+Cc: Will Deacon <will@kernel.org>
+Cc: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Stable-dep-of: fb1cf0878328 ("riscv: rewrite __kernel_map_pages() to fix sleeping in invalid context")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/mm.h | 15 +++++++++++++++
+ mm/memory_hotplug.c | 3 +--
+ mm/page_alloc.c | 6 ++----
+ mm/slab.c | 2 +-
+ 4 files changed, 19 insertions(+), 7 deletions(-)
+
+diff --git a/include/linux/mm.h b/include/linux/mm.h
+index b8b677f47a8da..4b9c1b3656a49 100644
+--- a/include/linux/mm.h
++++ b/include/linux/mm.h
+@@ -2967,12 +2967,27 @@ kernel_map_pages(struct page *page, int numpages, int enable)
+ {
+ __kernel_map_pages(page, numpages, enable);
+ }
++
++static inline void debug_pagealloc_map_pages(struct page *page, int numpages)
++{
++ if (debug_pagealloc_enabled_static())
++ __kernel_map_pages(page, numpages, 1);
++}
++
++static inline void debug_pagealloc_unmap_pages(struct page *page, int numpages)
++{
++ if (debug_pagealloc_enabled_static())
++ __kernel_map_pages(page, numpages, 0);
++}
++
+ #ifdef CONFIG_HIBERNATION
+ extern bool kernel_page_present(struct page *page);
+ #endif /* CONFIG_HIBERNATION */
+ #else /* CONFIG_DEBUG_PAGEALLOC || CONFIG_ARCH_HAS_SET_DIRECT_MAP */
+ static inline void
+ kernel_map_pages(struct page *page, int numpages, int enable) {}
++static inline void debug_pagealloc_map_pages(struct page *page, int numpages) {}
++static inline void debug_pagealloc_unmap_pages(struct page *page, int numpages) {}
+ #ifdef CONFIG_HIBERNATION
+ static inline bool kernel_page_present(struct page *page) { return true; }
+ #endif /* CONFIG_HIBERNATION */
+diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
+index 553b0705dce8e..a29b134790596 100644
+--- a/mm/memory_hotplug.c
++++ b/mm/memory_hotplug.c
+@@ -596,8 +596,7 @@ void generic_online_page(struct page *page, unsigned int order)
+ * so we should map it first. This is better than introducing a special
+ * case in page freeing fast path.
+ */
+- if (debug_pagealloc_enabled_static())
+- kernel_map_pages(page, 1 << order, 1);
++ debug_pagealloc_map_pages(page, 1 << order);
+ __free_pages_core(page, order);
+ totalram_pages_add(1UL << order);
+ #ifdef CONFIG_HIGHMEM
+diff --git a/mm/page_alloc.c b/mm/page_alloc.c
+index ed66601044be5..5e02b4bc94a08 100644
+--- a/mm/page_alloc.c
++++ b/mm/page_alloc.c
+@@ -1274,8 +1274,7 @@ static __always_inline bool free_pages_prepare(struct page *page,
+ */
+ arch_free_page(page, order);
+
+- if (debug_pagealloc_enabled_static())
+- kernel_map_pages(page, 1 << order, 0);
++ debug_pagealloc_unmap_pages(page, 1 << order);
+
+ kasan_free_nondeferred_pages(page, order);
+
+@@ -2272,8 +2271,7 @@ inline void post_alloc_hook(struct page *page, unsigned int order,
+ set_page_refcounted(page);
+
+ arch_alloc_page(page, order);
+- if (debug_pagealloc_enabled_static())
+- kernel_map_pages(page, 1 << order, 1);
++ debug_pagealloc_map_pages(page, 1 << order);
+ kasan_alloc_pages(page, order);
+ kernel_poison_pages(page, 1 << order, 1);
+ set_page_owner(page, order, gfp_flags);
+diff --git a/mm/slab.c b/mm/slab.c
+index b2cc2cf7d8a33..067ffc2939904 100644
+--- a/mm/slab.c
++++ b/mm/slab.c
+@@ -1434,7 +1434,7 @@ static void slab_kernel_map(struct kmem_cache *cachep, void *objp, int map)
+ if (!is_debug_pagealloc_cache(cachep))
+ return;
+
+- kernel_map_pages(virt_to_page(objp), cachep->size / PAGE_SIZE, map);
++ __kernel_map_pages(virt_to_page(objp), cachep->size / PAGE_SIZE, map);
+ }
+
+ #else
+--
+2.43.0
+
--- /dev/null
+From 850a915594ef259a944e57a010012abd4138e684 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 27 May 2022 23:23:52 +0530
+Subject: mmc: core: Capture eMMC and SD card errors
+
+From: Shaik Sajida Bhanu <quic_c_sbhanu@quicinc.com>
+
+[ Upstream commit 91f059c95c6a5dbc0907a5f871e7915a5e93c1f9 ]
+
+Add changes to capture eMMC and SD card errors.
+This is useful for debug and testing.
+
+Signed-off-by: Liangliang Lu <quic_luliang@quicinc.com>
+Signed-off-by: Sayali Lokhande <quic_sayalil@quicinc.com>
+Signed-off-by: Bao D. Nguyen <quic_nguyenb@quicinc.com>
+Signed-off-by: Ram Prakash Gupta <quic_rampraka@quicinc.com>
+Signed-off-by: Shaik Sajida Bhanu <quic_c_sbhanu@quicinc.com>
+Acked-by: Adrian Hunter <adrian.hunter@intel.com>
+Link: https://lore.kernel.org/r/1653674036-21829-2-git-send-email-quic_c_sbhanu@quicinc.com
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Stable-dep-of: b3855668d98c ("mmc: sdhci: Add support for "Tuning Error" interrupts")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mmc/core/core.c | 10 +++++++++-
+ include/linux/mmc/host.h | 26 ++++++++++++++++++++++++++
+ 2 files changed, 35 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
+index 2a8c7d5631d14..914ded6025235 100644
+--- a/drivers/mmc/core/core.c
++++ b/drivers/mmc/core/core.c
+@@ -947,9 +947,11 @@ int mmc_execute_tuning(struct mmc_card *card)
+ }
+
+ /* Only print error when we don't check for card removal */
+- if (!host->detect_change)
++ if (!host->detect_change) {
+ pr_err("%s: tuning execution failed: %d\n",
+ mmc_hostname(host), err);
++ mmc_debugfs_err_stats_inc(host, MMC_ERR_TUNING);
++ }
+
+ return err;
+ }
+@@ -2322,6 +2324,12 @@ void mmc_rescan(struct work_struct *work)
+ if (freqs[i] <= host->f_min)
+ break;
+ }
++
++ /*
++ * Ignore the command timeout errors observed during
++ * the card init as those are excepted.
++ */
++ host->err_stats[MMC_ERR_CMD_TIMEOUT] = 0;
+ mmc_release_host(host);
+
+ out:
+diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
+index fb08b86acdbf3..50df925bcefe0 100644
+--- a/include/linux/mmc/host.h
++++ b/include/linux/mmc/host.h
+@@ -79,6 +79,25 @@ struct mmc_ios {
+
+ struct mmc_host;
+
++enum mmc_err_stat {
++ MMC_ERR_CMD_TIMEOUT,
++ MMC_ERR_CMD_CRC,
++ MMC_ERR_DAT_TIMEOUT,
++ MMC_ERR_DAT_CRC,
++ MMC_ERR_AUTO_CMD,
++ MMC_ERR_ADMA,
++ MMC_ERR_TUNING,
++ MMC_ERR_CMDQ_RED,
++ MMC_ERR_CMDQ_GCE,
++ MMC_ERR_CMDQ_ICCE,
++ MMC_ERR_REQ_TIMEOUT,
++ MMC_ERR_CMDQ_REQ_TIMEOUT,
++ MMC_ERR_ICE_CFG,
++ MMC_ERR_CTRL_TIMEOUT,
++ MMC_ERR_UNEXPECTED_IRQ,
++ MMC_ERR_MAX,
++};
++
+ struct mmc_host_ops {
+ /*
+ * It is optional for the host to implement pre_req and post_req in
+@@ -472,6 +491,7 @@ struct mmc_host {
+ /* Host Software Queue support */
+ bool hsq_enabled;
+
++ u32 err_stats[MMC_ERR_MAX];
+ unsigned long private[] ____cacheline_aligned;
+ };
+
+@@ -607,6 +627,12 @@ static inline enum dma_data_direction mmc_get_dma_dir(struct mmc_data *data)
+ return data->flags & MMC_DATA_WRITE ? DMA_TO_DEVICE : DMA_FROM_DEVICE;
+ }
+
++static inline void mmc_debugfs_err_stats_inc(struct mmc_host *host,
++ enum mmc_err_stat stat)
++{
++ host->err_stats[stat] += 1;
++}
++
+ int mmc_send_tuning(struct mmc_host *host, u32 opcode, int *cmd_error);
+ int mmc_abort_tuning(struct mmc_host *host, u32 opcode);
+
+--
+2.43.0
+
--- /dev/null
+From 9b0485c53fffdb27d85c1790abadd790b498040d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 30 Jun 2021 06:16:58 +0200
+Subject: mmc: core: Only print retune error when we don't check for card
+ removal
+
+From: Wolfram Sang <wsa+renesas@sang-engineering.com>
+
+[ Upstream commit 8335928849729f8e5f10c1497c67260742f7a8cb ]
+
+Skip printing a retune error when we scan for a removed card because we
+then expect a failed command.
+
+Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
+Acked-by: Adrian Hunter <adrian.hunter@intel.com>
+Link: https://lore.kernel.org/r/20210630041658.7574-1-wsa+renesas@sang-engineering.com
+[Ulf: Rebased patch]
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Stable-dep-of: b3855668d98c ("mmc: sdhci: Add support for "Tuning Error" interrupts")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mmc/core/core.c | 12 +++++++-----
+ 1 file changed, 7 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
+index d8b38203f0fe9..2a8c7d5631d14 100644
+--- a/drivers/mmc/core/core.c
++++ b/drivers/mmc/core/core.c
+@@ -940,15 +940,17 @@ int mmc_execute_tuning(struct mmc_card *card)
+ opcode = MMC_SEND_TUNING_BLOCK;
+
+ err = host->ops->execute_tuning(host, opcode);
+-
+- if (err) {
+- pr_err("%s: tuning execution failed: %d\n",
+- mmc_hostname(host), err);
+- } else {
++ if (!err) {
+ mmc_retune_clear(host);
+ mmc_retune_enable(host);
++ return 0;
+ }
+
++ /* Only print error when we don't check for card removal */
++ if (!host->detect_change)
++ pr_err("%s: tuning execution failed: %d\n",
++ mmc_hostname(host), err);
++
+ return err;
+ }
+
+--
+2.43.0
+
--- /dev/null
+From e81a9beece2662eeee7fe2153da71b51a2d31e15 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 24 Jun 2021 17:16:16 +0200
+Subject: mmc: host: factor out clearing the retune state
+
+From: Wolfram Sang <wsa+renesas@sang-engineering.com>
+
+[ Upstream commit 8ffb2611a752e1067c18fba39968080469394206 ]
+
+We have this in two places, so let's have a dedicated function. It is
+also more readable.
+
+Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
+Acked-by: Adrian Hunter <adrian.hunter@intel.com>
+Reviewed-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
+Tested-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
+Link: https://lore.kernel.org/r/20210624151616.38770-4-wsa+renesas@sang-engineering.com
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Stable-dep-of: b3855668d98c ("mmc: sdhci: Add support for "Tuning Error" interrupts")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mmc/core/core.c | 3 +--
+ drivers/mmc/core/host.c | 3 +--
+ drivers/mmc/core/host.h | 6 ++++++
+ 3 files changed, 8 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
+index d5ca59bd1c995..d8b38203f0fe9 100644
+--- a/drivers/mmc/core/core.c
++++ b/drivers/mmc/core/core.c
+@@ -945,8 +945,7 @@ int mmc_execute_tuning(struct mmc_card *card)
+ pr_err("%s: tuning execution failed: %d\n",
+ mmc_hostname(host), err);
+ } else {
+- host->retune_now = 0;
+- host->need_retune = 0;
++ mmc_retune_clear(host);
+ mmc_retune_enable(host);
+ }
+
+diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c
+index 7ba1343ca5c1e..28834d1d07679 100644
+--- a/drivers/mmc/core/host.c
++++ b/drivers/mmc/core/host.c
+@@ -139,8 +139,7 @@ void mmc_retune_disable(struct mmc_host *host)
+ mmc_retune_unpause(host);
+ host->can_retune = 0;
+ del_timer_sync(&host->retune_timer);
+- host->retune_now = 0;
+- host->need_retune = 0;
++ mmc_retune_clear(host);
+ }
+
+ void mmc_retune_timer_stop(struct mmc_host *host)
+diff --git a/drivers/mmc/core/host.h b/drivers/mmc/core/host.h
+index 5e3b9534ffb23..855ecf428380f 100644
+--- a/drivers/mmc/core/host.h
++++ b/drivers/mmc/core/host.h
+@@ -21,6 +21,12 @@ int mmc_retune(struct mmc_host *host);
+ void mmc_retune_pause(struct mmc_host *host);
+ void mmc_retune_unpause(struct mmc_host *host);
+
++static inline void mmc_retune_clear(struct mmc_host *host)
++{
++ host->retune_now = 0;
++ host->need_retune = 0;
++}
++
+ static inline void mmc_retune_hold_now(struct mmc_host *host)
+ {
+ host->retune_now = 0;
+--
+2.43.0
+
--- /dev/null
+From 6fbef751cf99c15345f0004ee7ad562dac2a917e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 10 Apr 2024 21:16:35 +0200
+Subject: mmc: sdhci: Add support for "Tuning Error" interrupts
+
+From: Adrian Hunter <adrian.hunter@intel.com>
+
+[ Upstream commit b3855668d98cf9c6aec2db999dd27d872f8ba878 ]
+
+Most Bay Trail devices do not enable UHS modes for the external sdcard slot
+the Lenovo Yoga Tablet 2 830 / 1050 and Lenovo Yoga Tablet 2 Pro 1380 (8",
+10" and 13") models however do enable this.
+
+Using a UHS cards in these tablets results in errors like this one:
+
+[ 225.272001] mmc2: Unexpected interrupt 0x04000000.
+[ 225.272024] mmc2: sdhci: ============ SDHCI REGISTER DUMP ===========
+[ 225.272034] mmc2: sdhci: Sys addr: 0x0712c400 | Version: 0x0000b502
+[ 225.272044] mmc2: sdhci: Blk size: 0x00007200 | Blk cnt: 0x00000007
+[ 225.272054] mmc2: sdhci: Argument: 0x00000000 | Trn mode: 0x00000023
+[ 225.272064] mmc2: sdhci: Present: 0x01e20002 | Host ctl: 0x00000016
+[ 225.272073] mmc2: sdhci: Power: 0x0000000f | Blk gap: 0x00000000
+[ 225.272082] mmc2: sdhci: Wake-up: 0x00000000 | Clock: 0x00000107
+[ 225.272092] mmc2: sdhci: Timeout: 0x0000000e | Int stat: 0x00000001
+[ 225.272101] mmc2: sdhci: Int enab: 0x03ff000b | Sig enab: 0x03ff000b
+[ 225.272110] mmc2: sdhci: ACmd stat: 0x00000000 | Slot int: 0x00000001
+[ 225.272119] mmc2: sdhci: Caps: 0x076864b2 | Caps_1: 0x00000004
+[ 225.272129] mmc2: sdhci: Cmd: 0x00000c1b | Max curr: 0x00000000
+[ 225.272138] mmc2: sdhci: Resp[0]: 0x00000c00 | Resp[1]: 0x00000000
+[ 225.272147] mmc2: sdhci: Resp[2]: 0x00000000 | Resp[3]: 0x00000900
+[ 225.272155] mmc2: sdhci: Host ctl2: 0x0000000c
+[ 225.272164] mmc2: sdhci: ADMA Err: 0x00000003 | ADMA Ptr: 0x0712c200
+[ 225.272172] mmc2: sdhci: ============================================
+
+which results in IO errors leading to issues accessing the sdcard.
+
+0x04000000 is a so-called "Tuning Error" which sofar the SDHCI driver
+does not support / enable. Modify the IRQ handler to process these.
+
+This fixes UHS microsd cards not working with these tablets.
+
+Link: https://lore.kernel.org/r/199bb4aa-c6b5-453e-be37-58bbf468800c@intel.com
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/r/20240410191639.526324-3-hdegoede@redhat.com
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mmc/host/sdhci.c | 10 ++++++++--
+ drivers/mmc/host/sdhci.h | 3 ++-
+ 2 files changed, 10 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
+index 7df35c35778c1..feb1e3a3ddb0a 100644
+--- a/drivers/mmc/host/sdhci.c
++++ b/drivers/mmc/host/sdhci.c
+@@ -3421,12 +3421,18 @@ static void sdhci_data_irq(struct sdhci_host *host, u32 intmask)
+ host->data->error = -EILSEQ;
+ if (!mmc_op_tuning(SDHCI_GET_CMD(sdhci_readw(host, SDHCI_COMMAND))))
+ sdhci_err_stats_inc(host, DAT_CRC);
+- } else if ((intmask & SDHCI_INT_DATA_CRC) &&
++ } else if ((intmask & (SDHCI_INT_DATA_CRC | SDHCI_INT_TUNING_ERROR)) &&
+ SDHCI_GET_CMD(sdhci_readw(host, SDHCI_COMMAND))
+ != MMC_BUS_TEST_R) {
+ host->data->error = -EILSEQ;
+ if (!mmc_op_tuning(SDHCI_GET_CMD(sdhci_readw(host, SDHCI_COMMAND))))
+ sdhci_err_stats_inc(host, DAT_CRC);
++ if (intmask & SDHCI_INT_TUNING_ERROR) {
++ u16 ctrl2 = sdhci_readw(host, SDHCI_HOST_CONTROL2);
++
++ ctrl2 &= ~SDHCI_CTRL_TUNED_CLK;
++ sdhci_writew(host, ctrl2, SDHCI_HOST_CONTROL2);
++ }
+ } else if (intmask & SDHCI_INT_ADMA_ERROR) {
+ pr_err("%s: ADMA error: 0x%08x\n", mmc_hostname(host->mmc),
+ intmask);
+@@ -3963,7 +3969,7 @@ bool sdhci_cqe_irq(struct sdhci_host *host, u32 intmask, int *cmd_error,
+ } else
+ *cmd_error = 0;
+
+- if (intmask & (SDHCI_INT_DATA_END_BIT | SDHCI_INT_DATA_CRC)) {
++ if (intmask & (SDHCI_INT_DATA_END_BIT | SDHCI_INT_DATA_CRC | SDHCI_INT_TUNING_ERROR)) {
+ *data_error = -EILSEQ;
+ if (!mmc_op_tuning(host->cmd->opcode))
+ sdhci_err_stats_inc(host, DAT_CRC);
+diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
+index ca5ae0f038804..2d9c518682f01 100644
+--- a/drivers/mmc/host/sdhci.h
++++ b/drivers/mmc/host/sdhci.h
+@@ -151,6 +151,7 @@
+ #define SDHCI_INT_BUS_POWER 0x00800000
+ #define SDHCI_INT_AUTO_CMD_ERR 0x01000000
+ #define SDHCI_INT_ADMA_ERROR 0x02000000
++#define SDHCI_INT_TUNING_ERROR 0x04000000
+
+ #define SDHCI_INT_NORMAL_MASK 0x00007FFF
+ #define SDHCI_INT_ERROR_MASK 0xFFFF8000
+@@ -162,7 +163,7 @@
+ SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL | \
+ SDHCI_INT_DATA_TIMEOUT | SDHCI_INT_DATA_CRC | \
+ SDHCI_INT_DATA_END_BIT | SDHCI_INT_ADMA_ERROR | \
+- SDHCI_INT_BLK_GAP)
++ SDHCI_INT_BLK_GAP | SDHCI_INT_TUNING_ERROR)
+ #define SDHCI_INT_ALL_MASK ((unsigned int)-1)
+
+ #define SDHCI_CQE_INT_ERR_MASK ( \
+--
+2.43.0
+
--- /dev/null
+From d284b4cefa170ec6852e3c3830ca5ee8654fea9b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 27 May 2022 23:23:53 +0530
+Subject: mmc: sdhci: Capture eMMC and SD card errors
+
+From: Shaik Sajida Bhanu <quic_c_sbhanu@quicinc.com>
+
+[ Upstream commit efe8f5c9b5e118070f424205078ababc46fd130a ]
+
+Add changes to capture eMMC and SD card errors.
+This is useful for debug and testing.
+
+Signed-off-by: Liangliang Lu <quic_luliang@quicinc.com>
+Signed-off-by: Sayali Lokhande <quic_sayalil@quicinc.com>
+Signed-off-by: Bao D. Nguyen <quic_nguyenb@quicinc.com>
+Signed-off-by: Shaik Sajida Bhanu <quic_c_sbhanu@quicinc.com>
+Acked-by: Adrian Hunter <adrian.hunter@intel.com>
+Link: https://lore.kernel.org/r/1653674036-21829-3-git-send-email-quic_c_sbhanu@quicinc.com
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Stable-dep-of: b3855668d98c ("mmc: sdhci: Add support for "Tuning Error" interrupts")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mmc/host/sdhci.c | 59 ++++++++++++++++++++++++++++++----------
+ drivers/mmc/host/sdhci.h | 3 ++
+ include/linux/mmc/mmc.h | 6 ++++
+ 3 files changed, 53 insertions(+), 15 deletions(-)
+
+diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
+index 688248287e8d5..7df35c35778c1 100644
+--- a/drivers/mmc/host/sdhci.c
++++ b/drivers/mmc/host/sdhci.c
+@@ -225,6 +225,7 @@ void sdhci_reset(struct sdhci_host *host, u8 mask)
+ if (timedout) {
+ pr_err("%s: Reset 0x%x never completed.\n",
+ mmc_hostname(host->mmc), (int)mask);
++ sdhci_err_stats_inc(host, CTRL_TIMEOUT);
+ sdhci_dumpregs(host);
+ return;
+ }
+@@ -1721,6 +1722,7 @@ static bool sdhci_send_command_retry(struct sdhci_host *host,
+ if (!timeout--) {
+ pr_err("%s: Controller never released inhibit bit(s).\n",
+ mmc_hostname(host->mmc));
++ sdhci_err_stats_inc(host, CTRL_TIMEOUT);
+ sdhci_dumpregs(host);
+ cmd->error = -EIO;
+ return false;
+@@ -1970,6 +1972,7 @@ void sdhci_enable_clk(struct sdhci_host *host, u16 clk)
+ if (timedout) {
+ pr_err("%s: Internal clock never stabilised.\n",
+ mmc_hostname(host->mmc));
++ sdhci_err_stats_inc(host, CTRL_TIMEOUT);
+ sdhci_dumpregs(host);
+ return;
+ }
+@@ -1992,6 +1995,7 @@ void sdhci_enable_clk(struct sdhci_host *host, u16 clk)
+ if (timedout) {
+ pr_err("%s: PLL clock never stabilised.\n",
+ mmc_hostname(host->mmc));
++ sdhci_err_stats_inc(host, CTRL_TIMEOUT);
+ sdhci_dumpregs(host);
+ return;
+ }
+@@ -3192,6 +3196,7 @@ static void sdhci_timeout_timer(struct timer_list *t)
+ if (host->cmd && !sdhci_data_line_cmd(host->cmd)) {
+ pr_err("%s: Timeout waiting for hardware cmd interrupt.\n",
+ mmc_hostname(host->mmc));
++ sdhci_err_stats_inc(host, REQ_TIMEOUT);
+ sdhci_dumpregs(host);
+
+ host->cmd->error = -ETIMEDOUT;
+@@ -3214,6 +3219,7 @@ static void sdhci_timeout_data_timer(struct timer_list *t)
+ (host->cmd && sdhci_data_line_cmd(host->cmd))) {
+ pr_err("%s: Timeout waiting for hardware interrupt.\n",
+ mmc_hostname(host->mmc));
++ sdhci_err_stats_inc(host, REQ_TIMEOUT);
+ sdhci_dumpregs(host);
+
+ if (host->data) {
+@@ -3265,17 +3271,21 @@ static void sdhci_cmd_irq(struct sdhci_host *host, u32 intmask, u32 *intmask_p)
+ return;
+ pr_err("%s: Got command interrupt 0x%08x even though no command operation was in progress.\n",
+ mmc_hostname(host->mmc), (unsigned)intmask);
++ sdhci_err_stats_inc(host, UNEXPECTED_IRQ);
+ sdhci_dumpregs(host);
+ return;
+ }
+
+ if (intmask & (SDHCI_INT_TIMEOUT | SDHCI_INT_CRC |
+ SDHCI_INT_END_BIT | SDHCI_INT_INDEX)) {
+- if (intmask & SDHCI_INT_TIMEOUT)
++ if (intmask & SDHCI_INT_TIMEOUT) {
+ host->cmd->error = -ETIMEDOUT;
+- else
++ sdhci_err_stats_inc(host, CMD_TIMEOUT);
++ } else {
+ host->cmd->error = -EILSEQ;
+-
++ if (!mmc_op_tuning(host->cmd->opcode))
++ sdhci_err_stats_inc(host, CMD_CRC);
++ }
+ /* Treat data command CRC error the same as data CRC error */
+ if (host->cmd->data &&
+ (intmask & (SDHCI_INT_CRC | SDHCI_INT_TIMEOUT)) ==
+@@ -3297,6 +3307,8 @@ static void sdhci_cmd_irq(struct sdhci_host *host, u32 intmask, u32 *intmask_p)
+ -ETIMEDOUT :
+ -EILSEQ;
+
++ sdhci_err_stats_inc(host, AUTO_CMD);
++
+ if (sdhci_auto_cmd23(host, mrq)) {
+ mrq->sbc->error = err;
+ __sdhci_finish_mrq(host, mrq);
+@@ -3367,6 +3379,7 @@ static void sdhci_data_irq(struct sdhci_host *host, u32 intmask)
+ if (intmask & SDHCI_INT_DATA_TIMEOUT) {
+ host->data_cmd = NULL;
+ data_cmd->error = -ETIMEDOUT;
++ sdhci_err_stats_inc(host, CMD_TIMEOUT);
+ __sdhci_finish_mrq(host, data_cmd->mrq);
+ return;
+ }
+@@ -3395,23 +3408,30 @@ static void sdhci_data_irq(struct sdhci_host *host, u32 intmask)
+
+ pr_err("%s: Got data interrupt 0x%08x even though no data operation was in progress.\n",
+ mmc_hostname(host->mmc), (unsigned)intmask);
++ sdhci_err_stats_inc(host, UNEXPECTED_IRQ);
+ sdhci_dumpregs(host);
+
+ return;
+ }
+
+- if (intmask & SDHCI_INT_DATA_TIMEOUT)
++ if (intmask & SDHCI_INT_DATA_TIMEOUT) {
+ host->data->error = -ETIMEDOUT;
+- else if (intmask & SDHCI_INT_DATA_END_BIT)
++ sdhci_err_stats_inc(host, DAT_TIMEOUT);
++ } else if (intmask & SDHCI_INT_DATA_END_BIT) {
+ host->data->error = -EILSEQ;
+- else if ((intmask & SDHCI_INT_DATA_CRC) &&
++ if (!mmc_op_tuning(SDHCI_GET_CMD(sdhci_readw(host, SDHCI_COMMAND))))
++ sdhci_err_stats_inc(host, DAT_CRC);
++ } else if ((intmask & SDHCI_INT_DATA_CRC) &&
+ SDHCI_GET_CMD(sdhci_readw(host, SDHCI_COMMAND))
+- != MMC_BUS_TEST_R)
++ != MMC_BUS_TEST_R) {
+ host->data->error = -EILSEQ;
+- else if (intmask & SDHCI_INT_ADMA_ERROR) {
++ if (!mmc_op_tuning(SDHCI_GET_CMD(sdhci_readw(host, SDHCI_COMMAND))))
++ sdhci_err_stats_inc(host, DAT_CRC);
++ } else if (intmask & SDHCI_INT_ADMA_ERROR) {
+ pr_err("%s: ADMA error: 0x%08x\n", mmc_hostname(host->mmc),
+ intmask);
+ sdhci_adma_show_error(host);
++ sdhci_err_stats_inc(host, ADMA);
+ host->data->error = -EIO;
+ if (host->ops->adma_workaround)
+ host->ops->adma_workaround(host, intmask);
+@@ -3609,6 +3629,7 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id)
+ if (unexpected) {
+ pr_err("%s: Unexpected interrupt 0x%08x.\n",
+ mmc_hostname(host->mmc), unexpected);
++ sdhci_err_stats_inc(host, UNEXPECTED_IRQ);
+ sdhci_dumpregs(host);
+ }
+
+@@ -3932,20 +3953,27 @@ bool sdhci_cqe_irq(struct sdhci_host *host, u32 intmask, int *cmd_error,
+ if (!host->cqe_on)
+ return false;
+
+- if (intmask & (SDHCI_INT_INDEX | SDHCI_INT_END_BIT | SDHCI_INT_CRC))
++ if (intmask & (SDHCI_INT_INDEX | SDHCI_INT_END_BIT | SDHCI_INT_CRC)) {
+ *cmd_error = -EILSEQ;
+- else if (intmask & SDHCI_INT_TIMEOUT)
++ if (!mmc_op_tuning(host->cmd->opcode))
++ sdhci_err_stats_inc(host, CMD_CRC);
++ } else if (intmask & SDHCI_INT_TIMEOUT) {
+ *cmd_error = -ETIMEDOUT;
+- else
++ sdhci_err_stats_inc(host, CMD_TIMEOUT);
++ } else
+ *cmd_error = 0;
+
+- if (intmask & (SDHCI_INT_DATA_END_BIT | SDHCI_INT_DATA_CRC))
++ if (intmask & (SDHCI_INT_DATA_END_BIT | SDHCI_INT_DATA_CRC)) {
+ *data_error = -EILSEQ;
+- else if (intmask & SDHCI_INT_DATA_TIMEOUT)
++ if (!mmc_op_tuning(host->cmd->opcode))
++ sdhci_err_stats_inc(host, DAT_CRC);
++ } else if (intmask & SDHCI_INT_DATA_TIMEOUT) {
+ *data_error = -ETIMEDOUT;
+- else if (intmask & SDHCI_INT_ADMA_ERROR)
++ sdhci_err_stats_inc(host, DAT_TIMEOUT);
++ } else if (intmask & SDHCI_INT_ADMA_ERROR) {
+ *data_error = -EIO;
+- else
++ sdhci_err_stats_inc(host, ADMA);
++ } else
+ *data_error = 0;
+
+ /* Clear selected interrupts. */
+@@ -3961,6 +3989,7 @@ bool sdhci_cqe_irq(struct sdhci_host *host, u32 intmask, int *cmd_error,
+ sdhci_writel(host, intmask, SDHCI_INT_STATUS);
+ pr_err("%s: CQE: Unexpected interrupt 0x%08x.\n",
+ mmc_hostname(host->mmc), intmask);
++ sdhci_err_stats_inc(host, UNEXPECTED_IRQ);
+ sdhci_dumpregs(host);
+ }
+
+diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
+index 4db57c3a8cd4b..ca5ae0f038804 100644
+--- a/drivers/mmc/host/sdhci.h
++++ b/drivers/mmc/host/sdhci.h
+@@ -354,6 +354,9 @@ struct sdhci_adma2_64_desc {
+ */
+ #define MMC_CMD_TRANSFER_TIME (10 * NSEC_PER_MSEC) /* max 10 ms */
+
++#define sdhci_err_stats_inc(host, err_name) \
++ mmc_debugfs_err_stats_inc((host)->mmc, MMC_ERR_##err_name)
++
+ enum sdhci_cookie {
+ COOKIE_UNMAPPED,
+ COOKIE_PRE_MAPPED, /* mapped by sdhci_pre_req() */
+diff --git a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h
+index 545578fb814b0..6f7993803ee78 100644
+--- a/include/linux/mmc/mmc.h
++++ b/include/linux/mmc/mmc.h
+@@ -99,6 +99,12 @@ static inline bool mmc_op_multi(u32 opcode)
+ opcode == MMC_READ_MULTIPLE_BLOCK;
+ }
+
++static inline bool mmc_op_tuning(u32 opcode)
++{
++ return opcode == MMC_SEND_TUNING_BLOCK ||
++ opcode == MMC_SEND_TUNING_BLOCK_HS200;
++}
++
+ /*
+ * MMC_SWITCH argument format:
+ *
+--
+2.43.0
+
--- /dev/null
+From eca9f5fdf549298e1d1f912b9fe02f41f955d81e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 25 Aug 2021 18:33:45 +0900
+Subject: mmc: sdhci: Change the code to check auto_cmd23
+
+From: ChanWoo Lee <cw9316.lee@samsung.com>
+
+[ Upstream commit 38929d4f0d811df399c99398ce0599f546369bd4 ]
+
+It is replaced with a function that is already declared.
+//[1/5] mmc: sdhci: Add helpers for the auto-CMD23 flag
+//20200412090349.1607-2-adrian.hunter@intel.com
+
+Signed-off-by: ChanWoo Lee <cw9316.lee@samsung.com>
+Acked-by: Adrian Hunter <adrian.hunter@intel.com>
+Link: https://lore.kernel.org/r/20210825093345.14706-1-cw9316.lee@samsung.com
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Stable-dep-of: b3855668d98c ("mmc: sdhci: Add support for "Tuning Error" interrupts")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mmc/host/sdhci.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
+index bad01cc6823f6..688248287e8d5 100644
+--- a/drivers/mmc/host/sdhci.c
++++ b/drivers/mmc/host/sdhci.c
+@@ -3297,7 +3297,7 @@ static void sdhci_cmd_irq(struct sdhci_host *host, u32 intmask, u32 *intmask_p)
+ -ETIMEDOUT :
+ -EILSEQ;
+
+- if (mrq->sbc && (host->flags & SDHCI_AUTO_CMD23)) {
++ if (sdhci_auto_cmd23(host, mrq)) {
+ mrq->sbc->error = err;
+ __sdhci_finish_mrq(host, mrq);
+ return;
+--
+2.43.0
+
--- /dev/null
+From fdc83976105c0bab3139980b1d2bcbe91081f4b6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 18 Nov 2021 19:33:11 +0530
+Subject: PCI: Add PCI_ERROR_RESPONSE and related definitions
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Naveen Naidu <naveennaidu479@gmail.com>
+
+[ Upstream commit 57bdeef4716689d9b0e3571034d65cf420f6efcd ]
+
+A config or MMIO read from a PCI device that doesn't exist or doesn't
+respond causes a PCI error. There's no real data to return to satisfy the
+CPU read, so most hardware fabricates ~0 data.
+
+Add a PCI_ERROR_RESPONSE definition for that and use it where appropriate
+to make these checks consistent and easier to find.
+
+Also add helper definitions PCI_SET_ERROR_RESPONSE() and
+PCI_POSSIBLE_ERROR() to make the code more readable.
+
+Suggested-by: Bjorn Helgaas <bhelgaas@google.com>
+Link: https://lore.kernel.org/r/55563bf4dfc5d3fdc96695373c659d099bf175b1.1637243717.git.naveennaidu479@gmail.com
+Signed-off-by: Naveen Naidu <naveennaidu479@gmail.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Reviewed-by: Pali Rohár <pali@kernel.org>
+Stable-dep-of: c625dabbf1c4 ("x86/amd_nb: Check for invalid SMN reads")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/pci.h | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/include/linux/pci.h b/include/linux/pci.h
+index 5b24a6fbfa0be..30bc462fb1964 100644
+--- a/include/linux/pci.h
++++ b/include/linux/pci.h
+@@ -148,6 +148,15 @@ enum pci_interrupt_pin {
+ /* The number of legacy PCI INTx interrupts */
+ #define PCI_NUM_INTX 4
+
++/*
++ * Reading from a device that doesn't respond typically returns ~0. A
++ * successful read from a device may also return ~0, so you need additional
++ * information to reliably identify errors.
++ */
++#define PCI_ERROR_RESPONSE (~0ULL)
++#define PCI_SET_ERROR_RESPONSE(val) (*(val) = ((typeof(*(val))) PCI_ERROR_RESPONSE))
++#define PCI_POSSIBLE_ERROR(val) ((val) == ((typeof(val)) PCI_ERROR_RESPONSE))
++
+ /*
+ * pci_power_t values must match the bits in the Capabilities PME_Support
+ * and Control/Status PowerState fields in the Power Management capability.
+--
+2.43.0
+
--- /dev/null
+From c4dea5d7d9b6bedde730fddc6aca8eace744b240 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 May 2024 10:39:48 +0000
+Subject: perf/core: Fix missing wakeup when waiting for context reference
+
+From: Haifeng Xu <haifeng.xu@shopee.com>
+
+[ Upstream commit 74751ef5c1912ebd3e65c3b65f45587e05ce5d36 ]
+
+In our production environment, we found many hung tasks which are
+blocked for more than 18 hours. Their call traces are like this:
+
+[346278.191038] __schedule+0x2d8/0x890
+[346278.191046] schedule+0x4e/0xb0
+[346278.191049] perf_event_free_task+0x220/0x270
+[346278.191056] ? init_wait_var_entry+0x50/0x50
+[346278.191060] copy_process+0x663/0x18d0
+[346278.191068] kernel_clone+0x9d/0x3d0
+[346278.191072] __do_sys_clone+0x5d/0x80
+[346278.191076] __x64_sys_clone+0x25/0x30
+[346278.191079] do_syscall_64+0x5c/0xc0
+[346278.191083] ? syscall_exit_to_user_mode+0x27/0x50
+[346278.191086] ? do_syscall_64+0x69/0xc0
+[346278.191088] ? irqentry_exit_to_user_mode+0x9/0x20
+[346278.191092] ? irqentry_exit+0x19/0x30
+[346278.191095] ? exc_page_fault+0x89/0x160
+[346278.191097] ? asm_exc_page_fault+0x8/0x30
+[346278.191102] entry_SYSCALL_64_after_hwframe+0x44/0xae
+
+The task was waiting for the refcount become to 1, but from the vmcore,
+we found the refcount has already been 1. It seems that the task didn't
+get woken up by perf_event_release_kernel() and got stuck forever. The
+below scenario may cause the problem.
+
+Thread A Thread B
+... ...
+perf_event_free_task perf_event_release_kernel
+ ...
+ acquire event->child_mutex
+ ...
+ get_ctx
+ ... release event->child_mutex
+ acquire ctx->mutex
+ ...
+ perf_free_event (acquire/release event->child_mutex)
+ ...
+ release ctx->mutex
+ wait_var_event
+ acquire ctx->mutex
+ acquire event->child_mutex
+ # move existing events to free_list
+ release event->child_mutex
+ release ctx->mutex
+ put_ctx
+... ...
+
+In this case, all events of the ctx have been freed, so we couldn't
+find the ctx in free_list and Thread A will miss the wakeup. It's thus
+necessary to add a wakeup after dropping the reference.
+
+Fixes: 1cf8dfe8a661 ("perf/core: Fix race between close() and fork()")
+Signed-off-by: Haifeng Xu <haifeng.xu@shopee.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Reviewed-by: Frederic Weisbecker <frederic@kernel.org>
+Acked-by: Mark Rutland <mark.rutland@arm.com>
+Cc: stable@vger.kernel.org
+Link: https://lkml.kernel.org/r/20240513103948.33570-1-haifeng.xu@shopee.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/events/core.c | 13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+diff --git a/kernel/events/core.c b/kernel/events/core.c
+index e0b47bed86750..3a191bec69aca 100644
+--- a/kernel/events/core.c
++++ b/kernel/events/core.c
+@@ -5128,6 +5128,7 @@ int perf_event_release_kernel(struct perf_event *event)
+ again:
+ mutex_lock(&event->child_mutex);
+ list_for_each_entry(child, &event->child_list, child_list) {
++ void *var = NULL;
+
+ /*
+ * Cannot change, child events are not migrated, see the
+@@ -5168,11 +5169,23 @@ int perf_event_release_kernel(struct perf_event *event)
+ * this can't be the last reference.
+ */
+ put_event(event);
++ } else {
++ var = &ctx->refcount;
+ }
+
+ mutex_unlock(&event->child_mutex);
+ mutex_unlock(&ctx->mutex);
+ put_ctx(ctx);
++
++ if (var) {
++ /*
++ * If perf_event_free_task() has deleted all events from the
++ * ctx while the child_mutex got released above, make sure to
++ * notify about the preceding put_ctx().
++ */
++ smp_mb(); /* pairs with wait_var_event() */
++ wake_up_var(var);
++ }
+ goto again;
+ }
+ mutex_unlock(&event->child_mutex);
+--
+2.43.0
+
--- /dev/null
+From 2b3ed759e93fb5bc86744856a0cbe80f1b980e49 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Dec 2020 19:10:25 -0800
+Subject: PM: hibernate: make direct map manipulations more explicit
+
+From: Mike Rapoport <rppt@linux.ibm.com>
+
+[ Upstream commit 2abf962a8d42b32f5ffeb827826290b799c85f86 ]
+
+When DEBUG_PAGEALLOC or ARCH_HAS_SET_DIRECT_MAP is enabled a page may be
+not present in the direct map and has to be explicitly mapped before it
+could be copied.
+
+Introduce hibernate_map_page() and hibernation_unmap_page() that will
+explicitly use set_direct_map_{default,invalid}_noflush() for
+ARCH_HAS_SET_DIRECT_MAP case and debug_pagealloc_{map,unmap}_pages() for
+DEBUG_PAGEALLOC case.
+
+The remapping of the pages in safe_copy_page() presumes that it only
+changes protection bits in an existing PTE and so it is safe to ignore
+return value of set_direct_map_{default,invalid}_noflush().
+
+Still, add a pr_warn() so that future changes in set_memory APIs will not
+silently break hibernation.
+
+Link: https://lkml.kernel.org/r/20201109192128.960-3-rppt@kernel.org
+Signed-off-by: Mike Rapoport <rppt@linux.ibm.com>
+Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Reviewed-by: David Hildenbrand <david@redhat.com>
+Acked-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
+Acked-by: Vlastimil Babka <vbabka@suse.cz>
+Cc: Albert Ou <aou@eecs.berkeley.edu>
+Cc: Andy Lutomirski <luto@kernel.org>
+Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
+Cc: Borislav Petkov <bp@alien8.de>
+Cc: Catalin Marinas <catalin.marinas@arm.com>
+Cc: Christian Borntraeger <borntraeger@de.ibm.com>
+Cc: Christoph Lameter <cl@linux.com>
+Cc: Dave Hansen <dave.hansen@linux.intel.com>
+Cc: David Rientjes <rientjes@google.com>
+Cc: "David S. Miller" <davem@davemloft.net>
+Cc: "Edgecombe, Rick P" <rick.p.edgecombe@intel.com>
+Cc: Heiko Carstens <hca@linux.ibm.com>
+Cc: "H. Peter Anvin" <hpa@zytor.com>
+Cc: Ingo Molnar <mingo@redhat.com>
+Cc: Joonsoo Kim <iamjoonsoo.kim@lge.com>
+Cc: Len Brown <len.brown@intel.com>
+Cc: Michael Ellerman <mpe@ellerman.id.au>
+Cc: Palmer Dabbelt <palmer@dabbelt.com>
+Cc: Paul Mackerras <paulus@samba.org>
+Cc: Paul Walmsley <paul.walmsley@sifive.com>
+Cc: Pavel Machek <pavel@ucw.cz>
+Cc: Pekka Enberg <penberg@kernel.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: Vasily Gorbik <gor@linux.ibm.com>
+Cc: Will Deacon <will@kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Stable-dep-of: fb1cf0878328 ("riscv: rewrite __kernel_map_pages() to fix sleeping in invalid context")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/mm.h | 12 ------------
+ kernel/power/snapshot.c | 38 ++++++++++++++++++++++++++++++++++++--
+ 2 files changed, 36 insertions(+), 14 deletions(-)
+
+diff --git a/include/linux/mm.h b/include/linux/mm.h
+index 4b9c1b3656a49..61ed8b20ea704 100644
+--- a/include/linux/mm.h
++++ b/include/linux/mm.h
+@@ -2958,16 +2958,6 @@ static inline bool debug_pagealloc_enabled_static(void)
+ #if defined(CONFIG_DEBUG_PAGEALLOC) || defined(CONFIG_ARCH_HAS_SET_DIRECT_MAP)
+ extern void __kernel_map_pages(struct page *page, int numpages, int enable);
+
+-/*
+- * When called in DEBUG_PAGEALLOC context, the call should most likely be
+- * guarded by debug_pagealloc_enabled() or debug_pagealloc_enabled_static()
+- */
+-static inline void
+-kernel_map_pages(struct page *page, int numpages, int enable)
+-{
+- __kernel_map_pages(page, numpages, enable);
+-}
+-
+ static inline void debug_pagealloc_map_pages(struct page *page, int numpages)
+ {
+ if (debug_pagealloc_enabled_static())
+@@ -2984,8 +2974,6 @@ static inline void debug_pagealloc_unmap_pages(struct page *page, int numpages)
+ extern bool kernel_page_present(struct page *page);
+ #endif /* CONFIG_HIBERNATION */
+ #else /* CONFIG_DEBUG_PAGEALLOC || CONFIG_ARCH_HAS_SET_DIRECT_MAP */
+-static inline void
+-kernel_map_pages(struct page *page, int numpages, int enable) {}
+ static inline void debug_pagealloc_map_pages(struct page *page, int numpages) {}
+ static inline void debug_pagealloc_unmap_pages(struct page *page, int numpages) {}
+ #ifdef CONFIG_HIBERNATION
+diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c
+index c1bdaae07f4c7..e84fb16f30b9d 100644
+--- a/kernel/power/snapshot.c
++++ b/kernel/power/snapshot.c
+@@ -76,6 +76,40 @@ static inline void hibernate_restore_protect_page(void *page_address) {}
+ static inline void hibernate_restore_unprotect_page(void *page_address) {}
+ #endif /* CONFIG_STRICT_KERNEL_RWX && CONFIG_ARCH_HAS_SET_MEMORY */
+
++
++/*
++ * The calls to set_direct_map_*() should not fail because remapping a page
++ * here means that we only update protection bits in an existing PTE.
++ * It is still worth to have a warning here if something changes and this
++ * will no longer be the case.
++ */
++static inline void hibernate_map_page(struct page *page)
++{
++ if (IS_ENABLED(CONFIG_ARCH_HAS_SET_DIRECT_MAP)) {
++ int ret = set_direct_map_default_noflush(page);
++
++ if (ret)
++ pr_warn_once("Failed to remap page\n");
++ } else {
++ debug_pagealloc_map_pages(page, 1);
++ }
++}
++
++static inline void hibernate_unmap_page(struct page *page)
++{
++ if (IS_ENABLED(CONFIG_ARCH_HAS_SET_DIRECT_MAP)) {
++ unsigned long addr = (unsigned long)page_address(page);
++ int ret = set_direct_map_invalid_noflush(page);
++
++ if (ret)
++ pr_warn_once("Failed to remap page\n");
++
++ flush_tlb_kernel_range(addr, addr + PAGE_SIZE);
++ } else {
++ debug_pagealloc_unmap_pages(page, 1);
++ }
++}
++
+ static int swsusp_page_is_free(struct page *);
+ static void swsusp_set_page_forbidden(struct page *);
+ static void swsusp_unset_page_forbidden(struct page *);
+@@ -1348,9 +1382,9 @@ static void safe_copy_page(void *dst, struct page *s_page)
+ if (kernel_page_present(s_page)) {
+ do_copy_page(dst, page_address(s_page));
+ } else {
+- kernel_map_pages(s_page, 1, 1);
++ hibernate_map_page(s_page);
+ do_copy_page(dst, page_address(s_page));
+- kernel_map_pages(s_page, 1, 0);
++ hibernate_unmap_page(s_page);
+ }
+ }
+
+--
+2.43.0
+
--- /dev/null
+From bc79e5e15d18874e0201c83360478dd85d5f46b6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 15 Apr 2024 19:00:23 +0300
+Subject: pmdomain: ti-sci: Fix duplicate PD referrals
+
+From: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
+
+[ Upstream commit 670c900f69645db394efb38934b3344d8804171a ]
+
+When the dts file has multiple referrers to a single PD (e.g.
+simple-framebuffer and dss nodes both point to the DSS power-domain) the
+ti-sci driver will create two power domains, both with the same ID, and
+that will cause problems as one of the power domains will hide the other
+one.
+
+Fix this checking if a PD with the ID has already been created, and only
+create a PD for new IDs.
+
+Fixes: efa5c01cd7ee ("soc: ti: ti_sci_pm_domains: switch to use multiple genpds instead of one")
+Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/r/20240415-ti-sci-pd-v1-1-a0e56b8ad897@ideasonboard.com
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soc/ti/ti_sci_pm_domains.c | 20 +++++++++++++++++++-
+ 1 file changed, 19 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/soc/ti/ti_sci_pm_domains.c b/drivers/soc/ti/ti_sci_pm_domains.c
+index a33ec7eaf23d1..17984a7bffba5 100644
+--- a/drivers/soc/ti/ti_sci_pm_domains.c
++++ b/drivers/soc/ti/ti_sci_pm_domains.c
+@@ -114,6 +114,18 @@ static const struct of_device_id ti_sci_pm_domain_matches[] = {
+ };
+ MODULE_DEVICE_TABLE(of, ti_sci_pm_domain_matches);
+
++static bool ti_sci_pm_idx_exists(struct ti_sci_genpd_provider *pd_provider, u32 idx)
++{
++ struct ti_sci_pm_domain *pd;
++
++ list_for_each_entry(pd, &pd_provider->pd_list, node) {
++ if (pd->idx == idx)
++ return true;
++ }
++
++ return false;
++}
++
+ static int ti_sci_pm_domain_probe(struct platform_device *pdev)
+ {
+ struct device *dev = &pdev->dev;
+@@ -153,8 +165,14 @@ static int ti_sci_pm_domain_probe(struct platform_device *pdev)
+ break;
+
+ if (args.args_count >= 1 && args.np == dev->of_node) {
+- if (args.args[0] > max_id)
++ if (args.args[0] > max_id) {
+ max_id = args.args[0];
++ } else {
++ if (ti_sci_pm_idx_exists(pd_provider, args.args[0])) {
++ index++;
++ continue;
++ }
++ }
+
+ pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL);
+ if (!pd)
+--
+2.43.0
+
--- /dev/null
+From f80c71927ec39acde8f37af5842c00b846f2893a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 21 May 2024 23:45:50 +0100
+Subject: r8169: Fix possible ring buffer corruption on fragmented Tx packets.
+
+From: Ken Milmore <ken.milmore@gmail.com>
+
+[ Upstream commit c71e3a5cffd5309d7f84444df03d5b72600cc417 ]
+
+An issue was found on the RTL8125b when transmitting small fragmented
+packets, whereby invalid entries were inserted into the transmit ring
+buffer, subsequently leading to calls to dma_unmap_single() with a null
+address.
+
+This was caused by rtl8169_start_xmit() not noticing changes to nr_frags
+which may occur when small packets are padded (to work around hardware
+quirks) in rtl8169_tso_csum_v2().
+
+To fix this, postpone inspecting nr_frags until after any padding has been
+applied.
+
+Fixes: 9020845fb5d6 ("r8169: improve rtl8169_start_xmit")
+Cc: stable@vger.kernel.org
+Signed-off-by: Ken Milmore <ken.milmore@gmail.com>
+Reviewed-by: Heiner Kallweit <hkallweit1@gmail.com>
+Link: https://lore.kernel.org/r/27ead18b-c23d-4f49-a020-1fc482c5ac95@gmail.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/realtek/r8169_main.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c
+index dd4404efdb8d6..d24eb5ee152a5 100644
+--- a/drivers/net/ethernet/realtek/r8169_main.c
++++ b/drivers/net/ethernet/realtek/r8169_main.c
+@@ -4278,11 +4278,11 @@ static void rtl8169_doorbell(struct rtl8169_private *tp)
+ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb,
+ struct net_device *dev)
+ {
+- unsigned int frags = skb_shinfo(skb)->nr_frags;
+ struct rtl8169_private *tp = netdev_priv(dev);
+ unsigned int entry = tp->cur_tx % NUM_TX_DESC;
+ struct TxDesc *txd_first, *txd_last;
+ bool stop_queue, door_bell;
++ unsigned int frags;
+ u32 opts[2];
+
+ if (unlikely(!rtl_tx_slots_avail(tp))) {
+@@ -4305,6 +4305,7 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb,
+
+ txd_first = tp->TxDescArray + entry;
+
++ frags = skb_shinfo(skb)->nr_frags;
+ if (frags) {
+ if (rtl8169_xmit_frags(tp, skb, opts, entry))
+ goto err_dma_1;
+--
+2.43.0
+
--- /dev/null
+From 9e7264d0481da6e57af83dffd7f6d21d6c37b042 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 14 Nov 2020 21:49:53 +0100
+Subject: r8169: improve rtl8169_start_xmit
+
+From: Heiner Kallweit <hkallweit1@gmail.com>
+
+[ Upstream commit 41294e6a434d4f19e957c55b275ea0324f275009 ]
+
+Improve the following in rtl8169_start_xmit:
+- tp->cur_tx can be accessed in parallel by rtl_tx(), therefore
+ annotate the race by using WRITE_ONCE
+- avoid checking stop_queue a second time by moving the doorbell check
+- netif_stop_queue() uses atomic operation set_bit() that includes a
+ full memory barrier on some platforms, therefore use
+ smp_mb__after_atomic to avoid overhead
+
+Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
+Link: https://lore.kernel.org/r/80085451-3eaf-507a-c7c0-08d607c46fbc@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: c71e3a5cffd5 ("r8169: Fix possible ring buffer corruption on fragmented Tx packets.")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/realtek/r8169_main.c | 15 ++++++---------
+ 1 file changed, 6 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c
+index 0847b64fbb2f4..b678fd1436a4c 100644
+--- a/drivers/net/ethernet/realtek/r8169_main.c
++++ b/drivers/net/ethernet/realtek/r8169_main.c
+@@ -4331,7 +4331,7 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb,
+ /* rtl_tx needs to see descriptor changes before updated tp->cur_tx */
+ smp_wmb();
+
+- tp->cur_tx += frags + 1;
++ WRITE_ONCE(tp->cur_tx, tp->cur_tx + frags + 1);
+
+ stop_queue = !rtl_tx_slots_avail(tp, MAX_SKB_FRAGS);
+ if (unlikely(stop_queue)) {
+@@ -4340,13 +4340,6 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb,
+ */
+ smp_wmb();
+ netif_stop_queue(dev);
+- door_bell = true;
+- }
+-
+- if (door_bell)
+- rtl8169_doorbell(tp);
+-
+- if (unlikely(stop_queue)) {
+ /* Sync with rtl_tx:
+ * - publish queue status and cur_tx ring index (write barrier)
+ * - refresh dirty_tx ring index (read barrier).
+@@ -4354,11 +4347,15 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb,
+ * status and forget to wake up queue, a racing rtl_tx thread
+ * can't.
+ */
+- smp_mb();
++ smp_mb__after_atomic();
+ if (rtl_tx_slots_avail(tp, MAX_SKB_FRAGS))
+ netif_start_queue(dev);
++ door_bell = true;
+ }
+
++ if (door_bell)
++ rtl8169_doorbell(tp);
++
+ return NETDEV_TX_OK;
+
+ err_dma_1:
+--
+2.43.0
+
--- /dev/null
+From 3015c2d0b0241d1ef7ae6c44c2f7661e9abdbf5f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Nov 2020 22:56:29 +0100
+Subject: r8169: improve rtl_tx
+
+From: Heiner Kallweit <hkallweit1@gmail.com>
+
+[ Upstream commit ca1ab89cd2d654661f559bd83ad9fc7323cb6c86 ]
+
+We can simplify the for() condition and eliminate variable tx_left.
+The change also considers that tp->cur_tx may be incremented by a
+racing rtl8169_start_xmit().
+In addition replace the write to tp->dirty_tx and the following
+smp_mb() with an equivalent call to smp_store_mb(). This implicitly
+adds a WRITE_ONCE() to the write.
+
+Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
+Link: https://lore.kernel.org/r/c2e19e5e-3d3f-d663-af32-13c3374f5def@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: c71e3a5cffd5 ("r8169: Fix possible ring buffer corruption on fragmented Tx packets.")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/realtek/r8169_main.c | 7 +++----
+ 1 file changed, 3 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c
+index 84c8362a65cd1..0847b64fbb2f4 100644
+--- a/drivers/net/ethernet/realtek/r8169_main.c
++++ b/drivers/net/ethernet/realtek/r8169_main.c
+@@ -4469,11 +4469,11 @@ static void rtl8169_pcierr_interrupt(struct net_device *dev)
+ static void rtl_tx(struct net_device *dev, struct rtl8169_private *tp,
+ int budget)
+ {
+- unsigned int dirty_tx, tx_left, bytes_compl = 0, pkts_compl = 0;
++ unsigned int dirty_tx, bytes_compl = 0, pkts_compl = 0;
+
+ dirty_tx = tp->dirty_tx;
+
+- for (tx_left = READ_ONCE(tp->cur_tx) - dirty_tx; tx_left; tx_left--) {
++ while (READ_ONCE(tp->cur_tx) != dirty_tx) {
+ unsigned int entry = dirty_tx % NUM_TX_DESC;
+ struct sk_buff *skb = tp->tx_skb[entry].skb;
+ u32 status;
+@@ -4497,7 +4497,6 @@ static void rtl_tx(struct net_device *dev, struct rtl8169_private *tp,
+
+ rtl_inc_priv_stats(&tp->tx_stats, pkts_compl, bytes_compl);
+
+- tp->dirty_tx = dirty_tx;
+ /* Sync with rtl8169_start_xmit:
+ * - publish dirty_tx ring index (write barrier)
+ * - refresh cur_tx ring index and queue status (read barrier)
+@@ -4505,7 +4504,7 @@ static void rtl_tx(struct net_device *dev, struct rtl8169_private *tp,
+ * a racing xmit thread can only have a right view of the
+ * ring status.
+ */
+- smp_mb();
++ smp_store_mb(tp->dirty_tx, dirty_tx);
+ if (netif_queue_stopped(dev) &&
+ rtl_tx_slots_avail(tp, MAX_SKB_FRAGS)) {
+ netif_wake_queue(dev);
+--
+2.43.0
+
--- /dev/null
+From e9bff0caaadd4f0e1166c6cd0aab930885693ff8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 17 Nov 2020 21:34:09 +0100
+Subject: r8169: remove not needed check in rtl8169_start_xmit
+
+From: Heiner Kallweit <hkallweit1@gmail.com>
+
+[ Upstream commit bd4bdeb4f29027199c68104fbdfa07ad45390cc1 ]
+
+In rtl_tx() the released descriptors are zero'ed by
+rtl8169_unmap_tx_skb(). And in the beginning of rtl8169_start_xmit()
+we check that enough descriptors are free, therefore there's no way
+the DescOwn bit can be set here.
+
+Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
+Link: https://lore.kernel.org/r/6965d665-6c50-90c5-70e6-0bb335d4ea47@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: c71e3a5cffd5 ("r8169: Fix possible ring buffer corruption on fragmented Tx packets.")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/realtek/r8169_main.c | 7 ++-----
+ 1 file changed, 2 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c
+index dbf885f4dd01d..dd4404efdb8d6 100644
+--- a/drivers/net/ethernet/realtek/r8169_main.c
++++ b/drivers/net/ethernet/realtek/r8169_main.c
+@@ -4285,17 +4285,12 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb,
+ bool stop_queue, door_bell;
+ u32 opts[2];
+
+- txd_first = tp->TxDescArray + entry;
+-
+ if (unlikely(!rtl_tx_slots_avail(tp))) {
+ if (net_ratelimit())
+ netdev_err(dev, "BUG! Tx Ring full when queue awake!\n");
+ goto err_stop_0;
+ }
+
+- if (unlikely(le32_to_cpu(txd_first->opts1) & DescOwn))
+- goto err_stop_0;
+-
+ opts[1] = rtl8169_tx_vlan_tag(skb);
+ opts[0] = 0;
+
+@@ -4308,6 +4303,8 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb,
+ entry, false)))
+ goto err_dma_0;
+
++ txd_first = tp->TxDescArray + entry;
++
+ if (frags) {
+ if (rtl8169_xmit_frags(tp, skb, opts, entry))
+ goto err_dma_1;
+--
+2.43.0
+
--- /dev/null
+From 684bcfdfcfc2755fccd490750028e3fea4e96a40 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 16 Nov 2020 17:03:14 +0100
+Subject: r8169: remove nr_frags argument from rtl_tx_slots_avail
+
+From: Heiner Kallweit <hkallweit1@gmail.com>
+
+[ Upstream commit 83c317d7b36bb3858cf1cb86d2635ec3f3bd6ea3 ]
+
+The only time when nr_frags isn't SKB_MAX_FRAGS is when entering
+rtl8169_start_xmit(). However we can use SKB_MAX_FRAGS also here
+because when queue isn't stopped there should always be room for
+MAX_SKB_FRAGS + 1 descriptors.
+
+Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
+Link: https://lore.kernel.org/r/3d1f2ad7-31d5-2cac-4f4a-394f8a3cab63@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: c71e3a5cffd5 ("r8169: Fix possible ring buffer corruption on fragmented Tx packets.")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/realtek/r8169_main.c | 15 ++++++---------
+ 1 file changed, 6 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c
+index b678fd1436a4c..dbf885f4dd01d 100644
+--- a/drivers/net/ethernet/realtek/r8169_main.c
++++ b/drivers/net/ethernet/realtek/r8169_main.c
+@@ -4247,13 +4247,12 @@ static bool rtl8169_tso_csum_v2(struct rtl8169_private *tp,
+ return true;
+ }
+
+-static bool rtl_tx_slots_avail(struct rtl8169_private *tp,
+- unsigned int nr_frags)
++static bool rtl_tx_slots_avail(struct rtl8169_private *tp)
+ {
+ unsigned int slots_avail = tp->dirty_tx + NUM_TX_DESC - tp->cur_tx;
+
+ /* A skbuff with nr_frags needs nr_frags+1 entries in the tx queue */
+- return slots_avail > nr_frags;
++ return slots_avail > MAX_SKB_FRAGS;
+ }
+
+ /* Versions RTL8102e and from RTL8168c onwards support csum_v2 */
+@@ -4288,7 +4287,7 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb,
+
+ txd_first = tp->TxDescArray + entry;
+
+- if (unlikely(!rtl_tx_slots_avail(tp, frags))) {
++ if (unlikely(!rtl_tx_slots_avail(tp))) {
+ if (net_ratelimit())
+ netdev_err(dev, "BUG! Tx Ring full when queue awake!\n");
+ goto err_stop_0;
+@@ -4333,7 +4332,7 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb,
+
+ WRITE_ONCE(tp->cur_tx, tp->cur_tx + frags + 1);
+
+- stop_queue = !rtl_tx_slots_avail(tp, MAX_SKB_FRAGS);
++ stop_queue = !rtl_tx_slots_avail(tp);
+ if (unlikely(stop_queue)) {
+ /* Avoid wrongly optimistic queue wake-up: rtl_tx thread must
+ * not miss a ring update when it notices a stopped queue.
+@@ -4348,7 +4347,7 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb,
+ * can't.
+ */
+ smp_mb__after_atomic();
+- if (rtl_tx_slots_avail(tp, MAX_SKB_FRAGS))
++ if (rtl_tx_slots_avail(tp))
+ netif_start_queue(dev);
+ door_bell = true;
+ }
+@@ -4502,10 +4501,8 @@ static void rtl_tx(struct net_device *dev, struct rtl8169_private *tp,
+ * ring status.
+ */
+ smp_store_mb(tp->dirty_tx, dirty_tx);
+- if (netif_queue_stopped(dev) &&
+- rtl_tx_slots_avail(tp, MAX_SKB_FRAGS)) {
++ if (netif_queue_stopped(dev) && rtl_tx_slots_avail(tp))
+ netif_wake_queue(dev);
+- }
+ /*
+ * 8168 hack: TxPoll requests are lost when the Tx packets are
+ * too close. Let's kick an extra TxPoll request when a burst
+--
+2.43.0
+
--- /dev/null
+From fa50bbd7b5166ac8d67069dd278938a046792afa Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 29 Oct 2020 18:56:06 +0100
+Subject: r8169: remove unneeded memory barrier in rtl_tx
+
+From: Heiner Kallweit <hkallweit1@gmail.com>
+
+[ Upstream commit 3a689e34973e8717cd57991c6fcf527dc56062b5 ]
+
+tp->dirty_tx isn't changed outside rtl_tx(). Therefore I see no need
+to guarantee a specific order of reading tp->dirty_tx and tp->cur_tx.
+Having said that we can remove the memory barrier.
+In addition use READ_ONCE() when reading tp->cur_tx because it can
+change in parallel to rtl_tx().
+
+Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
+Link: https://lore.kernel.org/r/2264563a-fa9e-11b0-2c42-31bc6b8e2790@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: c71e3a5cffd5 ("r8169: Fix possible ring buffer corruption on fragmented Tx packets.")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/realtek/r8169_main.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c
+index c29d43c5f4504..84c8362a65cd1 100644
+--- a/drivers/net/ethernet/realtek/r8169_main.c
++++ b/drivers/net/ethernet/realtek/r8169_main.c
+@@ -4472,9 +4472,8 @@ static void rtl_tx(struct net_device *dev, struct rtl8169_private *tp,
+ unsigned int dirty_tx, tx_left, bytes_compl = 0, pkts_compl = 0;
+
+ dirty_tx = tp->dirty_tx;
+- smp_rmb();
+
+- for (tx_left = tp->cur_tx - dirty_tx; tx_left > 0; tx_left--) {
++ for (tx_left = READ_ONCE(tp->cur_tx) - dirty_tx; tx_left; tx_left--) {
+ unsigned int entry = dirty_tx % NUM_TX_DESC;
+ struct sk_buff *skb = tp->tx_skb[entry].skb;
+ u32 status;
+--
+2.43.0
+
--- /dev/null
+From ddcb8b6b7964f14a0ce198d9332eff01a9aabde9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 21 May 2023 22:23:35 +0900
+Subject: Revert "kheaders: substituting --sort in archive creation"
+
+From: Masahiro Yamada <masahiroy@kernel.org>
+
+[ Upstream commit 49c386ebbb43394ff4773ce24f726f6afc4c30c8 ]
+
+This reverts commit 700dea5a0bea9f64eba89fae7cb2540326fdfdc1.
+
+The reason for that commit was --sort=ORDER introduced in
+tar 1.28 (2014). More than 3 years have passed since then.
+
+Requiring GNU tar 1.28 should be fine now because we require
+GCC 5.1 (2015).
+
+Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
+Reviewed-by: Nicolas Schier <nicolas@fjasle.eu>
+Stable-dep-of: 3bd27a847a3a ("kheaders: explicitly define file modes for archived headers")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/gen_kheaders.sh | 9 +++------
+ 1 file changed, 3 insertions(+), 6 deletions(-)
+
+diff --git a/kernel/gen_kheaders.sh b/kernel/gen_kheaders.sh
+index c1510f0ab3ea5..d7e827c6cd2d2 100755
+--- a/kernel/gen_kheaders.sh
++++ b/kernel/gen_kheaders.sh
+@@ -83,12 +83,9 @@ find $cpio_dir -type f -print0 |
+ xargs -0 -P8 -n1 perl -pi -e 'BEGIN {undef $/;}; s/\/\*((?!SPDX).)*?\*\///smg;'
+
+ # Create archive and try to normalize metadata for reproducibility.
+-# For compatibility with older versions of tar, files are fed to tar
+-# pre-sorted, as --sort=name might not be available.
+-find $cpio_dir -printf "./%P\n" | LC_ALL=C sort | \
+- tar "${KBUILD_BUILD_TIMESTAMP:+--mtime=$KBUILD_BUILD_TIMESTAMP}" \
+- --owner=0 --group=0 --numeric-owner --no-recursion \
+- -I $XZ -cf $tarfile -C $cpio_dir/ -T - > /dev/null
++tar "${KBUILD_BUILD_TIMESTAMP:+--mtime=$KBUILD_BUILD_TIMESTAMP}" \
++ --owner=0 --group=0 --sort=name --numeric-owner \
++ -I $XZ -cf $tarfile -C $cpio_dir/ . > /dev/null
+
+ echo $headers_md5 > kernel/kheaders.md5
+ echo "$this_file_md5" >> kernel/kheaders.md5
+--
+2.43.0
+
--- /dev/null
+From f4a9ab6c094bec464d2264ab51a88ce2fe172dd7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 May 2024 07:50:40 +0200
+Subject: riscv: rewrite __kernel_map_pages() to fix sleeping in invalid
+ context
+
+From: Nam Cao <namcao@linutronix.de>
+
+[ Upstream commit fb1cf0878328fe75d47f0aed0a65b30126fcefc4 ]
+
+__kernel_map_pages() is a debug function which clears the valid bit in page
+table entry for deallocated pages to detect illegal memory accesses to
+freed pages.
+
+This function set/clear the valid bit using __set_memory(). __set_memory()
+acquires init_mm's semaphore, and this operation may sleep. This is
+problematic, because __kernel_map_pages() can be called in atomic context,
+and thus is illegal to sleep. An example warning that this causes:
+
+BUG: sleeping function called from invalid context at kernel/locking/rwsem.c:1578
+in_atomic(): 1, irqs_disabled(): 0, non_block: 0, pid: 2, name: kthreadd
+preempt_count: 2, expected: 0
+CPU: 0 PID: 2 Comm: kthreadd Not tainted 6.9.0-g1d4c6d784ef6 #37
+Hardware name: riscv-virtio,qemu (DT)
+Call Trace:
+[<ffffffff800060dc>] dump_backtrace+0x1c/0x24
+[<ffffffff8091ef6e>] show_stack+0x2c/0x38
+[<ffffffff8092baf8>] dump_stack_lvl+0x5a/0x72
+[<ffffffff8092bb24>] dump_stack+0x14/0x1c
+[<ffffffff8003b7ac>] __might_resched+0x104/0x10e
+[<ffffffff8003b7f4>] __might_sleep+0x3e/0x62
+[<ffffffff8093276a>] down_write+0x20/0x72
+[<ffffffff8000cf00>] __set_memory+0x82/0x2fa
+[<ffffffff8000d324>] __kernel_map_pages+0x5a/0xd4
+[<ffffffff80196cca>] __alloc_pages_bulk+0x3b2/0x43a
+[<ffffffff8018ee82>] __vmalloc_node_range+0x196/0x6ba
+[<ffffffff80011904>] copy_process+0x72c/0x17ec
+[<ffffffff80012ab4>] kernel_clone+0x60/0x2fe
+[<ffffffff80012f62>] kernel_thread+0x82/0xa0
+[<ffffffff8003552c>] kthreadd+0x14a/0x1be
+[<ffffffff809357de>] ret_from_fork+0xe/0x1c
+
+Rewrite this function with apply_to_existing_page_range(). It is fine to
+not have any locking, because __kernel_map_pages() works with pages being
+allocated/deallocated and those pages are not changed by anyone else in the
+meantime.
+
+Fixes: 5fde3db5eb02 ("riscv: add ARCH_SUPPORTS_DEBUG_PAGEALLOC support")
+Signed-off-by: Nam Cao <namcao@linutronix.de>
+Cc: stable@vger.kernel.org
+Reviewed-by: Alexandre Ghiti <alexghiti@rivosinc.com>
+Link: https://lore.kernel.org/r/1289ecba9606a19917bc12b6c27da8aa23e1e5ae.1715750938.git.namcao@linutronix.de
+Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/riscv/mm/pageattr.c | 28 ++++++++++++++++++++++------
+ 1 file changed, 22 insertions(+), 6 deletions(-)
+
+diff --git a/arch/riscv/mm/pageattr.c b/arch/riscv/mm/pageattr.c
+index ae63a0227e2fb..ce4b73b4d0e42 100644
+--- a/arch/riscv/mm/pageattr.c
++++ b/arch/riscv/mm/pageattr.c
+@@ -185,16 +185,32 @@ int set_direct_map_default_noflush(struct page *page)
+ }
+
+ #ifdef CONFIG_DEBUG_PAGEALLOC
++static int debug_pagealloc_set_page(pte_t *pte, unsigned long addr, void *data)
++{
++ int enable = *(int *)data;
++
++ unsigned long val = pte_val(ptep_get(pte));
++
++ if (enable)
++ val |= _PAGE_PRESENT;
++ else
++ val &= ~_PAGE_PRESENT;
++
++ set_pte(pte, __pte(val));
++
++ return 0;
++}
++
+ void __kernel_map_pages(struct page *page, int numpages, int enable)
+ {
+ if (!debug_pagealloc_enabled())
+ return;
+
+- if (enable)
+- __set_memory((unsigned long)page_address(page), numpages,
+- __pgprot(_PAGE_PRESENT), __pgprot(0));
+- else
+- __set_memory((unsigned long)page_address(page), numpages,
+- __pgprot(0), __pgprot(_PAGE_PRESENT));
++ unsigned long start = (unsigned long)page_address(page);
++ unsigned long size = PAGE_SIZE * numpages;
++
++ apply_to_existing_page_range(&init_mm, start, size, debug_pagealloc_set_page, &enable);
++
++ flush_tlb_kernel_range(start, start + size);
+ }
+ #endif
+--
+2.43.0
+
--- /dev/null
+From 70f9b084e3d05f362789fad368fd80150b6cf2be Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 19 Nov 2021 11:22:33 -0800
+Subject: rtlwifi: rtl8192de: Style clean-ups
+
+From: Kees Cook <keescook@chromium.org>
+
+[ Upstream commit 69831173fcbbfebb7aa2d76523deaf0b87b8eddd ]
+
+Clean up some style issues:
+- Use ARRAY_SIZE() even though it's a u8 array.
+- Remove redundant CHANNEL_MAX_NUMBER_2G define.
+Additionally fix some dead code WARNs.
+
+Acked-by: Ping-Ke Shih <pkshih@realtek.com>
+Link: https://lore.kernel.org/lkml/57d0d1b6064342309f680f692192556c@realtek.com/
+Signed-off-by: Kees Cook <keescook@chromium.org>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+Link: https://lore.kernel.org/r/20211119192233.1021063-1-keescook@chromium.org
+Stable-dep-of: de4d4be4fa64 ("wifi: rtlwifi: rtl8192de: Fix 5 GHz TX power")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../wireless/realtek/rtlwifi/rtl8192de/phy.c | 17 +++++++----------
+ drivers/net/wireless/realtek/rtlwifi/wifi.h | 1 -
+ 2 files changed, 7 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192de/phy.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/phy.c
+index af0c7d74b3f5a..da9acebbe237a 100644
+--- a/drivers/net/wireless/realtek/rtlwifi/rtl8192de/phy.c
++++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/phy.c
+@@ -892,7 +892,7 @@ static u8 _rtl92c_phy_get_rightchnlplace(u8 chnl)
+ u8 place = chnl;
+
+ if (chnl > 14) {
+- for (place = 14; place < sizeof(channel5g); place++) {
++ for (place = 14; place < ARRAY_SIZE(channel5g); place++) {
+ if (channel5g[place] == chnl) {
+ place++;
+ break;
+@@ -1359,7 +1359,7 @@ u8 rtl92d_get_rightchnlplace_for_iqk(u8 chnl)
+ u8 place = chnl;
+
+ if (chnl > 14) {
+- for (place = 14; place < sizeof(channel_all); place++) {
++ for (place = 14; place < ARRAY_SIZE(channel_all); place++) {
+ if (channel_all[place] == chnl)
+ return place - 13;
+ }
+@@ -2417,7 +2417,7 @@ static bool _rtl92d_is_legal_5g_channel(struct ieee80211_hw *hw, u8 channel)
+
+ int i;
+
+- for (i = 0; i < sizeof(channel5g); i++)
++ for (i = 0; i < ARRAY_SIZE(channel5g); i++)
+ if (channel == channel5g[i])
+ return true;
+ return false;
+@@ -2681,9 +2681,8 @@ void rtl92d_phy_reset_iqk_result(struct ieee80211_hw *hw)
+ u8 i;
+
+ rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,
+- "settings regs %d default regs %d\n",
+- (int)(sizeof(rtlphy->iqk_matrix) /
+- sizeof(struct iqk_matrix_regs)),
++ "settings regs %zu default regs %d\n",
++ ARRAY_SIZE(rtlphy->iqk_matrix),
+ IQK_MATRIX_REG_NUM);
+ /* 0xe94, 0xe9c, 0xea4, 0xeac, 0xeb4, 0xebc, 0xec4, 0xecc */
+ for (i = 0; i < IQK_MATRIX_SETTINGS_NUM; i++) {
+@@ -2850,16 +2849,14 @@ u8 rtl92d_phy_sw_chnl(struct ieee80211_hw *hw)
+ case BAND_ON_5G:
+ /* Get first channel error when change between
+ * 5G and 2.4G band. */
+- if (channel <= 14)
++ if (WARN_ONCE(channel <= 14, "rtl8192de: 5G but channel<=14\n"))
+ return 0;
+- WARN_ONCE((channel <= 14), "rtl8192de: 5G but channel<=14\n");
+ break;
+ case BAND_ON_2_4G:
+ /* Get first channel error when change between
+ * 5G and 2.4G band. */
+- if (channel > 14)
++ if (WARN_ONCE(channel > 14, "rtl8192de: 2G but channel>14\n"))
+ return 0;
+- WARN_ONCE((channel > 14), "rtl8192de: 2G but channel>14\n");
+ break;
+ default:
+ WARN_ONCE(true, "rtl8192de: Invalid WirelessMode(%#x)!!\n",
+diff --git a/drivers/net/wireless/realtek/rtlwifi/wifi.h b/drivers/net/wireless/realtek/rtlwifi/wifi.h
+index a89e232d6963f..c997d8bfda975 100644
+--- a/drivers/net/wireless/realtek/rtlwifi/wifi.h
++++ b/drivers/net/wireless/realtek/rtlwifi/wifi.h
+@@ -108,7 +108,6 @@
+ #define CHANNEL_GROUP_IDX_5GM 6
+ #define CHANNEL_GROUP_IDX_5GH 9
+ #define CHANNEL_GROUP_MAX_5G 9
+-#define CHANNEL_MAX_NUMBER_2G 14
+ #define AVG_THERMAL_NUM 8
+ #define AVG_THERMAL_NUM_88E 4
+ #define AVG_THERMAL_NUM_8723BE 4
+--
+2.43.0
+
--- /dev/null
+From dd53b6a67fdd1af2fbfb0333570ef8689f774427 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 May 2024 10:09:32 +0200
+Subject: s390/cpacf: Make use of invalid opcode produce a link error
+
+From: Harald Freudenberger <freude@linux.ibm.com>
+
+[ Upstream commit 32e8bd6423fc127d2b37bdcf804fd76af3bbec79 ]
+
+Instead of calling BUG() at runtime introduce and use a prototype for a
+non-existing function to produce a link error during compile when a not
+supported opcode is used with the __cpacf_query() or __cpacf_check_opcode()
+inline functions.
+
+Suggested-by: Heiko Carstens <hca@linux.ibm.com>
+Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
+Reviewed-by: Holger Dengler <dengler@linux.ibm.com>
+Reviewed-by: Juergen Christ <jchrist@linux.ibm.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/s390/include/asm/cpacf.h | 12 ++++++++++--
+ 1 file changed, 10 insertions(+), 2 deletions(-)
+
+diff --git a/arch/s390/include/asm/cpacf.h b/arch/s390/include/asm/cpacf.h
+index fa31f71cf5746..0f6ff2008a159 100644
+--- a/arch/s390/include/asm/cpacf.h
++++ b/arch/s390/include/asm/cpacf.h
+@@ -161,6 +161,13 @@
+
+ typedef struct { unsigned char bytes[16]; } cpacf_mask_t;
+
++/*
++ * Prototype for a not existing function to produce a link
++ * error if __cpacf_query() or __cpacf_check_opcode() is used
++ * with an invalid compile time const opcode.
++ */
++void __cpacf_bad_opcode(void);
++
+ static __always_inline void __cpacf_query_rre(u32 opc, u8 r1, u8 r2,
+ cpacf_mask_t *mask)
+ {
+@@ -232,7 +239,7 @@ static __always_inline void __cpacf_query(unsigned int opcode,
+ __cpacf_query_rre(CPACF_PRNO, 2, 4, mask);
+ break;
+ default:
+- BUG();
++ __cpacf_bad_opcode();
+ }
+ }
+
+@@ -257,7 +264,8 @@ static __always_inline int __cpacf_check_opcode(unsigned int opcode)
+ case CPACF_KMA:
+ return test_facility(146); /* check for MSA8 */
+ default:
+- BUG();
++ __cpacf_bad_opcode();
++ return 0;
+ }
+ }
+
+--
+2.43.0
+
kcov-don-t-lose-track-of-remote-references-during-softirqs.patch
i2c-ocores-set-iack-bit-after-core-is-enabled.patch
dt-bindings-i2c-google-cros-ec-i2c-tunnel-correct-path-to-i2c-controller-schema.patch
+arm-dts-samsung-smdkv310-fix-keypad-no-autorepeat.patch
+arm-dts-samsung-exynos4412-origen-fix-keypad-no-auto.patch
+arm-dts-samsung-smdk4412-fix-keypad-no-autorepeat.patch
+mmc-host-factor-out-clearing-the-retune-state.patch
+mmc-core-only-print-retune-error-when-we-don-t-check.patch
+mmc-sdhci-change-the-code-to-check-auto_cmd23.patch
+mmc-core-capture-emmc-and-sd-card-errors.patch
+mmc-sdhci-capture-emmc-and-sd-card-errors.patch
+mmc-sdhci-add-support-for-tuning-error-interrupts.patch
+rtlwifi-rtl8192de-style-clean-ups.patch
+wifi-rtlwifi-rtl8192de-fix-5-ghz-tx-power.patch
+pmdomain-ti-sci-fix-duplicate-pd-referrals.patch
+knfsd-lookup-can-return-an-illegal-error-value.patch
+spmi-hisi-spmi-controller-do-not-override-device-ide.patch
+bcache-fix-variable-length-array-abuse-in-btree_iter.patch
+s390-cpacf-make-use-of-invalid-opcode-produce-a-link.patch
+tracing-add-module_description-to-preemptirq_delay_t.patch
+x86-cpu-vfm-add-new-macros-to-work-with-vendor-famil.patch
+x86-cpu-fix-x86_match_cpu-to-match-just-x86_vendor_i.patch
+drm-amdgpu-update-new-memory-types-in-atomfirmware-h.patch
+drm-amdgpu-atomfirmware-add-edp-and-integrated-info-.patch
+drm-amdgpu-drop-config_drm_amd_dc_dcn3_01-from-atomf.patch
+drm-amdgpu-fix-vram-type-and-bandwidth-error-for-ddr.patch
+drm-amdgpu-update-atomfirmware-for-dcn3.1-phy-tuning.patch
+drm-amdgpu-atomfirmware-add-intergrated-info-v2.3-ta.patch
+mm-introduce-debug_pagealloc_-map-unmap-_pages-helpe.patch
+pm-hibernate-make-direct-map-manipulations-more-expl.patch
+arch-mm-restore-dependency-of-__kernel_map_pages-on-.patch
+riscv-rewrite-__kernel_map_pages-to-fix-sleeping-in-.patch
+r8169-remove-unneeded-memory-barrier-in-rtl_tx.patch
+r8169-improve-rtl_tx.patch
+r8169-improve-rtl8169_start_xmit.patch
+r8169-remove-nr_frags-argument-from-rtl_tx_slots_ava.patch
+r8169-remove-not-needed-check-in-rtl8169_start_xmit.patch
+r8169-fix-possible-ring-buffer-corruption-on-fragmen.patch
+revert-kheaders-substituting-sort-in-archive-creatio.patch
+kheaders-explicitly-define-file-modes-for-archived-h.patch
+perf-core-fix-missing-wakeup-when-waiting-for-contex.patch
+pci-add-pci_error_response-and-related-definitions.patch
+x86-amd_nb-check-for-invalid-smn-reads.patch
+cifs-missed-ref-counting-smb-session-in-find.patch
+smb-client-fix-deadlock-in-smb2_find_smb_tcon.patch
--- /dev/null
+From 4b813b47f06cf31e2847a760e9b8346d79c82f12 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Jun 2024 13:13:13 -0300
+Subject: smb: client: fix deadlock in smb2_find_smb_tcon()
+
+From: Enzo Matsumiya <ematsumiya@suse.de>
+
+[ Upstream commit 02c418774f76a0a36a6195c9dbf8971eb4130a15 ]
+
+Unlock cifs_tcp_ses_lock before calling cifs_put_smb_ses() to avoid such
+deadlock.
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Enzo Matsumiya <ematsumiya@suse.de>
+Reviewed-by: Shyam Prasad N <sprasad@microsoft.com>
+Reviewed-by: Paulo Alcantara (Red Hat) <pc@manguebit.com>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/cifs/smb2transport.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/fs/cifs/smb2transport.c b/fs/cifs/smb2transport.c
+index f40b8de2aeeb3..adb324234b444 100644
+--- a/fs/cifs/smb2transport.c
++++ b/fs/cifs/smb2transport.c
+@@ -207,8 +207,8 @@ smb2_find_smb_tcon(struct TCP_Server_Info *server, __u64 ses_id, __u32 tid)
+ }
+ tcon = smb2_find_smb_sess_tcon_unlocked(ses, tid);
+ if (!tcon) {
+- cifs_put_smb_ses(ses);
+ spin_unlock(&cifs_tcp_ses_lock);
++ cifs_put_smb_ses(ses);
+ return NULL;
+ }
+ spin_unlock(&cifs_tcp_ses_lock);
+--
+2.43.0
+
--- /dev/null
+From 6467ad91444ce5d8bb9e2825a19de776254c6cc6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 7 May 2024 14:07:41 -0700
+Subject: spmi: hisi-spmi-controller: Do not override device identifier
+
+From: Vamshi Gajjela <vamshigajjela@google.com>
+
+[ Upstream commit eda4923d78d634482227c0b189d9b7ca18824146 ]
+
+'nr' member of struct spmi_controller, which serves as an identifier
+for the controller/bus. This value is a dynamic ID assigned in
+spmi_controller_alloc, and overriding it from the driver results in an
+ida_free error "ida_free called for id=xx which is not allocated".
+
+Signed-off-by: Vamshi Gajjela <vamshigajjela@google.com>
+Fixes: 70f59c90c819 ("staging: spmi: add Hikey 970 SPMI controller driver")
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/r/20240228185116.1269-1-vamshigajjela@google.com
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Link: https://lore.kernel.org/r/20240507210809.3479953-5-sboyd@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/staging/hikey9xx/hisi-spmi-controller.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/drivers/staging/hikey9xx/hisi-spmi-controller.c b/drivers/staging/hikey9xx/hisi-spmi-controller.c
+index 29f226503668d..eee3dcf96ee79 100644
+--- a/drivers/staging/hikey9xx/hisi-spmi-controller.c
++++ b/drivers/staging/hikey9xx/hisi-spmi-controller.c
+@@ -303,7 +303,6 @@ static int spmi_controller_probe(struct platform_device *pdev)
+
+ spin_lock_init(&spmi_controller->lock);
+
+- ctrl->nr = spmi_controller->channel;
+ ctrl->dev.parent = pdev->dev.parent;
+ ctrl->dev.of_node = of_node_get(pdev->dev.of_node);
+
+--
+2.43.0
+
--- /dev/null
+From fd90e721156d4ffff7c693841b22747861fcaf39 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 18 May 2024 15:54:49 -0700
+Subject: tracing: Add MODULE_DESCRIPTION() to preemptirq_delay_test
+
+From: Jeff Johnson <quic_jjohnson@quicinc.com>
+
+[ Upstream commit 23748e3e0fbfe471eff5ce439921629f6a427828 ]
+
+Fix the 'make W=1' warning:
+
+WARNING: modpost: missing MODULE_DESCRIPTION() in kernel/trace/preemptirq_delay_test.o
+
+Link: https://lore.kernel.org/linux-trace-kernel/20240518-md-preemptirq_delay_test-v1-1-387d11b30d85@quicinc.com
+
+Cc: stable@vger.kernel.org
+Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Fixes: f96e8577da10 ("lib: Add module for testing preemptoff/irqsoff latency tracers")
+Acked-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
+Signed-off-by: Jeff Johnson <quic_jjohnson@quicinc.com>
+Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/trace/preemptirq_delay_test.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/kernel/trace/preemptirq_delay_test.c b/kernel/trace/preemptirq_delay_test.c
+index 312d1a0ca3b60..1a4f2f4249961 100644
+--- a/kernel/trace/preemptirq_delay_test.c
++++ b/kernel/trace/preemptirq_delay_test.c
+@@ -201,4 +201,5 @@ static void __exit preemptirq_delay_exit(void)
+
+ module_init(preemptirq_delay_init)
+ module_exit(preemptirq_delay_exit)
++MODULE_DESCRIPTION("Preempt / IRQ disable delay thread to test latency tracers");
+ MODULE_LICENSE("GPL v2");
+--
+2.43.0
+
--- /dev/null
+From 25291a6445861783b1ff057c07d16714ae9c0508 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 25 Apr 2024 21:09:21 +0300
+Subject: wifi: rtlwifi: rtl8192de: Fix 5 GHz TX power
+
+From: Bitterblue Smith <rtl8821cerfe2@gmail.com>
+
+[ Upstream commit de4d4be4fa64ed7b4aa1c613061015bd8fa98b24 ]
+
+Different channels have different TX power settings. rtl8192de is using
+the TX power setting from the wrong channel in the 5 GHz band because
+_rtl92c_phy_get_rightchnlplace expects an array which includes all the
+channel numbers, but it's using an array which includes only the 5 GHz
+channel numbers.
+
+Use the array channel_all (defined in rtl8192de/phy.c) instead of
+the incorrect channel5g (defined in core.c).
+
+Tested only with rtl8192du, which will use the same TX power code.
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>
+Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
+Link: https://msgid.link/c7653517-cf88-4f57-b79a-8edb0a8b32f0@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/realtek/rtlwifi/rtl8192de/phy.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192de/phy.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/phy.c
+index da9acebbe237a..ffe6d243c7649 100644
+--- a/drivers/net/wireless/realtek/rtlwifi/rtl8192de/phy.c
++++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/phy.c
+@@ -892,8 +892,8 @@ static u8 _rtl92c_phy_get_rightchnlplace(u8 chnl)
+ u8 place = chnl;
+
+ if (chnl > 14) {
+- for (place = 14; place < ARRAY_SIZE(channel5g); place++) {
+- if (channel5g[place] == chnl) {
++ for (place = 14; place < ARRAY_SIZE(channel_all); place++) {
++ if (channel_all[place] == chnl) {
+ place++;
+ break;
+ }
+--
+2.43.0
+
--- /dev/null
+From e22e28d0d7242b3c137222a03a548beeb4d142bf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 3 Apr 2023 16:42:44 +0000
+Subject: x86/amd_nb: Check for invalid SMN reads
+
+From: Yazen Ghannam <yazen.ghannam@amd.com>
+
+[ Upstream commit c625dabbf1c4a8e77e4734014f2fde7aa9071a1f ]
+
+AMD Zen-based systems use a System Management Network (SMN) that
+provides access to implementation-specific registers.
+
+SMN accesses are done indirectly through an index/data pair in PCI
+config space. The PCI config access may fail and return an error code.
+This would prevent the "read" value from being updated.
+
+However, the PCI config access may succeed, but the return value may be
+invalid. This is in similar fashion to PCI bad reads, i.e. return all
+bits set.
+
+Most systems will return 0 for SMN addresses that are not accessible.
+This is in line with AMD convention that unavailable registers are
+Read-as-Zero/Writes-Ignored.
+
+However, some systems will return a "PCI Error Response" instead. This
+value, along with an error code of 0 from the PCI config access, will
+confuse callers of the amd_smn_read() function.
+
+Check for this condition, clear the return value, and set a proper error
+code.
+
+Fixes: ddfe43cdc0da ("x86/amd_nb: Add SMN and Indirect Data Fabric access for AMD Fam17h")
+Signed-off-by: Yazen Ghannam <yazen.ghannam@amd.com>
+Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/r/20230403164244.471141-1-yazen.ghannam@amd.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/kernel/amd_nb.c | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/arch/x86/kernel/amd_nb.c b/arch/x86/kernel/amd_nb.c
+index 18f6b7c4bd79f..16cd56627574d 100644
+--- a/arch/x86/kernel/amd_nb.c
++++ b/arch/x86/kernel/amd_nb.c
+@@ -164,7 +164,14 @@ static int __amd_smn_rw(u16 node, u32 address, u32 *value, bool write)
+
+ int amd_smn_read(u16 node, u32 address, u32 *value)
+ {
+- return __amd_smn_rw(node, address, value, false);
++ int err = __amd_smn_rw(node, address, value, false);
++
++ if (PCI_POSSIBLE_ERROR(*value)) {
++ err = -ENODEV;
++ *value = 0;
++ }
++
++ return err;
+ }
+ EXPORT_SYMBOL_GPL(amd_smn_read);
+
+--
+2.43.0
+
--- /dev/null
+From 7e96ff8a1d96627c5bdc77bb4b8f22e4c4ab5ca0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 20 May 2024 15:45:33 -0700
+Subject: x86/cpu: Fix x86_match_cpu() to match just X86_VENDOR_INTEL
+
+From: Tony Luck <tony.luck@intel.com>
+
+[ Upstream commit 93022482b2948a9a7e9b5a2bb685f2e1cb4c3348 ]
+
+Code in v6.9 arch/x86/kernel/smpboot.c was changed by commit
+
+ 4db64279bc2b ("x86/cpu: Switch to new Intel CPU model defines") from:
+
+ static const struct x86_cpu_id intel_cod_cpu[] = {
+ X86_MATCH_INTEL_FAM6_MODEL(HASWELL_X, 0), /* COD */
+ X86_MATCH_INTEL_FAM6_MODEL(BROADWELL_X, 0), /* COD */
+ X86_MATCH_INTEL_FAM6_MODEL(ANY, 1), /* SNC */ <--- 443
+ {}
+ };
+
+ static bool match_llc(struct cpuinfo_x86 *c, struct cpuinfo_x86 *o)
+ {
+ const struct x86_cpu_id *id = x86_match_cpu(intel_cod_cpu);
+
+to:
+
+ static const struct x86_cpu_id intel_cod_cpu[] = {
+ X86_MATCH_VFM(INTEL_HASWELL_X, 0), /* COD */
+ X86_MATCH_VFM(INTEL_BROADWELL_X, 0), /* COD */
+ X86_MATCH_VFM(INTEL_ANY, 1), /* SNC */
+ {}
+ };
+
+ static bool match_llc(struct cpuinfo_x86 *c, struct cpuinfo_x86 *o)
+ {
+ const struct x86_cpu_id *id = x86_match_cpu(intel_cod_cpu);
+
+On an Intel CPU with SNC enabled this code previously matched the rule on line
+443 to avoid printing messages about insane cache configuration. The new code
+did not match any rules.
+
+Expanding the macros for the intel_cod_cpu[] array shows that the old is
+equivalent to:
+
+ static const struct x86_cpu_id intel_cod_cpu[] = {
+ [0] = { .vendor = 0, .family = 6, .model = 0x3F, .steppings = 0, .feature = 0, .driver_data = 0 },
+ [1] = { .vendor = 0, .family = 6, .model = 0x4F, .steppings = 0, .feature = 0, .driver_data = 0 },
+ [2] = { .vendor = 0, .family = 6, .model = 0x00, .steppings = 0, .feature = 0, .driver_data = 1 },
+ [3] = { .vendor = 0, .family = 0, .model = 0x00, .steppings = 0, .feature = 0, .driver_data = 0 }
+ }
+
+while the new code expands to:
+
+ static const struct x86_cpu_id intel_cod_cpu[] = {
+ [0] = { .vendor = 0, .family = 6, .model = 0x3F, .steppings = 0, .feature = 0, .driver_data = 0 },
+ [1] = { .vendor = 0, .family = 6, .model = 0x4F, .steppings = 0, .feature = 0, .driver_data = 0 },
+ [2] = { .vendor = 0, .family = 0, .model = 0x00, .steppings = 0, .feature = 0, .driver_data = 1 },
+ [3] = { .vendor = 0, .family = 0, .model = 0x00, .steppings = 0, .feature = 0, .driver_data = 0 }
+ }
+
+Looking at the code for x86_match_cpu():
+
+ const struct x86_cpu_id *x86_match_cpu(const struct x86_cpu_id *match)
+ {
+ const struct x86_cpu_id *m;
+ struct cpuinfo_x86 *c = &boot_cpu_data;
+
+ for (m = match;
+ m->vendor | m->family | m->model | m->steppings | m->feature;
+ m++) {
+ ...
+ }
+ return NULL;
+
+it is clear that there was no match because the ANY entry in the table (array
+index 2) is now the loop termination condition (all of vendor, family, model,
+steppings, and feature are zero).
+
+So this code was working before because the "ANY" check was looking for any
+Intel CPU in family 6. But fails now because the family is a wild card. So the
+root cause is that x86_match_cpu() has never been able to match on a rule with
+just X86_VENDOR_INTEL and all other fields set to wildcards.
+
+Add a new flags field to struct x86_cpu_id that has a bit set to indicate that
+this entry in the array is valid. Update X86_MATCH*() macros to set that bit.
+Change the end-marker check in x86_match_cpu() to just check the flags field
+for this bit.
+
+Backporter notes: The commit in Fixes is really the one that is broken:
+you can't have m->vendor as part of the loop termination conditional in
+x86_match_cpu() because it can happen - as it has happened above
+- that that whole conditional is 0 albeit vendor == 0 is a valid case
+- X86_VENDOR_INTEL is 0.
+
+However, the only case where the above happens is the SNC check added by
+4db64279bc2b1 so you only need this fix if you have backported that
+other commit
+
+ 4db64279bc2b ("x86/cpu: Switch to new Intel CPU model defines")
+
+Fixes: 644e9cbbe3fc ("Add driver auto probing for x86 features v4")
+Suggested-by: Thomas Gleixner <tglx@linutronix.de>
+Suggested-by: Borislav Petkov <bp@alien8.de>
+Signed-off-by: Tony Luck <tony.luck@intel.com>
+Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
+Cc: <stable+noautosel@kernel.org> # see above
+Link: https://lore.kernel.org/r/20240517144312.GBZkdtAOuJZCvxhFbJ@fat_crate.local
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/include/asm/cpu_device_id.h | 5 +++++
+ arch/x86/kernel/cpu/match.c | 4 +---
+ include/linux/mod_devicetable.h | 2 ++
+ 3 files changed, 8 insertions(+), 3 deletions(-)
+
+diff --git a/arch/x86/include/asm/cpu_device_id.h b/arch/x86/include/asm/cpu_device_id.h
+index dd7b9463696f5..e8e3dbe7f1730 100644
+--- a/arch/x86/include/asm/cpu_device_id.h
++++ b/arch/x86/include/asm/cpu_device_id.h
+@@ -53,6 +53,9 @@
+ #define X86_CENTAUR_FAM6_C7_D 0xd
+ #define X86_CENTAUR_FAM6_NANO 0xf
+
++/* x86_cpu_id::flags */
++#define X86_CPU_ID_FLAG_ENTRY_VALID BIT(0)
++
+ #define X86_STEPPINGS(mins, maxs) GENMASK(maxs, mins)
+ /**
+ * X86_MATCH_VENDOR_FAM_MODEL_STEPPINGS_FEATURE - Base macro for CPU matching
+@@ -79,6 +82,7 @@
+ .model = _model, \
+ .steppings = _steppings, \
+ .feature = _feature, \
++ .flags = X86_CPU_ID_FLAG_ENTRY_VALID, \
+ .driver_data = (unsigned long) _data \
+ }
+
+@@ -89,6 +93,7 @@
+ .model = _model, \
+ .steppings = _steppings, \
+ .feature = _feature, \
++ .flags = X86_CPU_ID_FLAG_ENTRY_VALID, \
+ .driver_data = (unsigned long) _data \
+ }
+
+diff --git a/arch/x86/kernel/cpu/match.c b/arch/x86/kernel/cpu/match.c
+index ad6776081e60d..ae71b8ef909c9 100644
+--- a/arch/x86/kernel/cpu/match.c
++++ b/arch/x86/kernel/cpu/match.c
+@@ -39,9 +39,7 @@ const struct x86_cpu_id *x86_match_cpu(const struct x86_cpu_id *match)
+ const struct x86_cpu_id *m;
+ struct cpuinfo_x86 *c = &boot_cpu_data;
+
+- for (m = match;
+- m->vendor | m->family | m->model | m->steppings | m->feature;
+- m++) {
++ for (m = match; m->flags & X86_CPU_ID_FLAG_ENTRY_VALID; m++) {
+ if (m->vendor != X86_VENDOR_ANY && c->x86_vendor != m->vendor)
+ continue;
+ if (m->family != X86_FAMILY_ANY && c->x86 != m->family)
+diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h
+index 5b08a473cdba4..18be4459aaf72 100644
+--- a/include/linux/mod_devicetable.h
++++ b/include/linux/mod_devicetable.h
+@@ -669,6 +669,8 @@ struct x86_cpu_id {
+ __u16 model;
+ __u16 steppings;
+ __u16 feature; /* bit index */
++ /* Solely for kernel-internal use: DO NOT EXPORT to userspace! */
++ __u16 flags;
+ kernel_ulong_t driver_data;
+ };
+
+--
+2.43.0
+
--- /dev/null
+From bc4cc86e41e7006ffb799e8a85872f2845e949d3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 16 Apr 2024 14:19:04 -0700
+Subject: x86/cpu/vfm: Add new macros to work with (vendor/family/model) values
+
+From: Tony Luck <tony.luck@intel.com>
+
+[ Upstream commit e6dfdc2e89a0adedf455814c91b977d6a584cc88 ]
+
+To avoid adding a slew of new macros for each new Intel CPU family
+switch over from providing CPU model number #defines to a new
+scheme that encodes vendor, family, and model in a single number.
+
+ [ bp: s/casted/cast/g ]
+
+Signed-off-by: Tony Luck <tony.luck@intel.com>
+Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
+Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
+Link: https://lore.kernel.org/r/20240416211941.9369-3-tony.luck@intel.com
+Stable-dep-of: 93022482b294 ("x86/cpu: Fix x86_match_cpu() to match just X86_VENDOR_INTEL")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/include/asm/cpu_device_id.h | 93 ++++++++++++++++++++++++++++
+ 1 file changed, 93 insertions(+)
+
+diff --git a/arch/x86/include/asm/cpu_device_id.h b/arch/x86/include/asm/cpu_device_id.h
+index eb8fcede9e3bf..dd7b9463696f5 100644
+--- a/arch/x86/include/asm/cpu_device_id.h
++++ b/arch/x86/include/asm/cpu_device_id.h
+@@ -2,6 +2,39 @@
+ #ifndef _ASM_X86_CPU_DEVICE_ID
+ #define _ASM_X86_CPU_DEVICE_ID
+
++/*
++ * Can't use <linux/bitfield.h> because it generates expressions that
++ * cannot be used in structure initializers. Bitfield construction
++ * here must match the union in struct cpuinfo_86:
++ * union {
++ * struct {
++ * __u8 x86_model;
++ * __u8 x86;
++ * __u8 x86_vendor;
++ * __u8 x86_reserved;
++ * };
++ * __u32 x86_vfm;
++ * };
++ */
++#define VFM_MODEL_BIT 0
++#define VFM_FAMILY_BIT 8
++#define VFM_VENDOR_BIT 16
++#define VFM_RSVD_BIT 24
++
++#define VFM_MODEL_MASK GENMASK(VFM_FAMILY_BIT - 1, VFM_MODEL_BIT)
++#define VFM_FAMILY_MASK GENMASK(VFM_VENDOR_BIT - 1, VFM_FAMILY_BIT)
++#define VFM_VENDOR_MASK GENMASK(VFM_RSVD_BIT - 1, VFM_VENDOR_BIT)
++
++#define VFM_MODEL(vfm) (((vfm) & VFM_MODEL_MASK) >> VFM_MODEL_BIT)
++#define VFM_FAMILY(vfm) (((vfm) & VFM_FAMILY_MASK) >> VFM_FAMILY_BIT)
++#define VFM_VENDOR(vfm) (((vfm) & VFM_VENDOR_MASK) >> VFM_VENDOR_BIT)
++
++#define VFM_MAKE(_vendor, _family, _model) ( \
++ ((_model) << VFM_MODEL_BIT) | \
++ ((_family) << VFM_FAMILY_BIT) | \
++ ((_vendor) << VFM_VENDOR_BIT) \
++)
++
+ /*
+ * Declare drivers belonging to specific x86 CPUs
+ * Similar in spirit to pci_device_id and related PCI functions
+@@ -49,6 +82,16 @@
+ .driver_data = (unsigned long) _data \
+ }
+
++#define X86_MATCH_VENDORID_FAM_MODEL_STEPPINGS_FEATURE(_vendor, _family, _model, \
++ _steppings, _feature, _data) { \
++ .vendor = _vendor, \
++ .family = _family, \
++ .model = _model, \
++ .steppings = _steppings, \
++ .feature = _feature, \
++ .driver_data = (unsigned long) _data \
++}
++
+ /**
+ * X86_MATCH_VENDOR_FAM_MODEL_FEATURE - Macro for CPU matching
+ * @_vendor: The vendor name, e.g. INTEL, AMD, HYGON, ..., ANY
+@@ -164,6 +207,56 @@
+ X86_MATCH_VENDOR_FAM_MODEL_STEPPINGS_FEATURE(INTEL, 6, INTEL_FAM6_##model, \
+ steppings, X86_FEATURE_ANY, data)
+
++/**
++ * X86_MATCH_VFM - Match encoded vendor/family/model
++ * @vfm: Encoded 8-bits each for vendor, family, model
++ * @data: Driver specific data or NULL. The internal storage
++ * format is unsigned long. The supplied value, pointer
++ * etc. is cast to unsigned long internally.
++ *
++ * Stepping and feature are set to wildcards
++ */
++#define X86_MATCH_VFM(vfm, data) \
++ X86_MATCH_VENDORID_FAM_MODEL_STEPPINGS_FEATURE( \
++ VFM_VENDOR(vfm), \
++ VFM_FAMILY(vfm), \
++ VFM_MODEL(vfm), \
++ X86_STEPPING_ANY, X86_FEATURE_ANY, data)
++
++/**
++ * X86_MATCH_VFM_STEPPINGS - Match encoded vendor/family/model/stepping
++ * @vfm: Encoded 8-bits each for vendor, family, model
++ * @steppings: Bitmask of steppings to match
++ * @data: Driver specific data or NULL. The internal storage
++ * format is unsigned long. The supplied value, pointer
++ * etc. is cast to unsigned long internally.
++ *
++ * feature is set to wildcard
++ */
++#define X86_MATCH_VFM_STEPPINGS(vfm, steppings, data) \
++ X86_MATCH_VENDORID_FAM_MODEL_STEPPINGS_FEATURE( \
++ VFM_VENDOR(vfm), \
++ VFM_FAMILY(vfm), \
++ VFM_MODEL(vfm), \
++ steppings, X86_FEATURE_ANY, data)
++
++/**
++ * X86_MATCH_VFM_FEATURE - Match encoded vendor/family/model/feature
++ * @vfm: Encoded 8-bits each for vendor, family, model
++ * @feature: A X86_FEATURE bit
++ * @data: Driver specific data or NULL. The internal storage
++ * format is unsigned long. The supplied value, pointer
++ * etc. is cast to unsigned long internally.
++ *
++ * Steppings is set to wildcard
++ */
++#define X86_MATCH_VFM_FEATURE(vfm, feature, data) \
++ X86_MATCH_VENDORID_FAM_MODEL_STEPPINGS_FEATURE( \
++ VFM_VENDOR(vfm), \
++ VFM_FAMILY(vfm), \
++ VFM_MODEL(vfm), \
++ X86_STEPPING_ANY, feature, data)
++
+ /*
+ * Match specific microcode revisions.
+ *
+--
+2.43.0
+