From: "Mike Pagano" <mpagano@gentoo.org>
To: gentoo-commits@lists.gentoo.org
Subject: [gentoo-commits] proj/linux-patches:6.11 commit in: /
Date: Fri, 22 Nov 2024 17:46:30 +0000 (UTC) [thread overview]
Message-ID: <1732297578.80fc1f5354a1d26cad5e58fd20b089999eef1cc7.mpagano@gentoo> (raw)
commit: 80fc1f5354a1d26cad5e58fd20b089999eef1cc7
Author: Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Fri Nov 22 17:46:18 2024 +0000
Commit: Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Fri Nov 22 17:46:18 2024 +0000
URL: https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=80fc1f53
Linux patch 6.11.10
Signed-off-by: Mike Pagano <mpagano <AT> gentoo.org>
0000_README | 4 +
1009_linux-6.11.10.patch | 4469 ++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 4473 insertions(+)
diff --git a/0000_README b/0000_README
index 3c22b167..ac3dcb33 100644
--- a/0000_README
+++ b/0000_README
@@ -79,6 +79,10 @@ Patch: 1008_linux-6.11.9.patch
From: https://www.kernel.org
Desc: Linux 6.11.9
+Patch: 1009_linux-6.11.10.patch
+From: https://www.kernel.org
+Desc: Linux 6.11.10
+
Patch: 1510_fs-enable-link-security-restrictions-by-default.patch
From: http://sources.debian.net/src/linux/3.16.7-ckt4-3/debian/patches/debian/fs-enable-link-security-restrictions-by-default.patch/
Desc: Enable link security restrictions by default.
diff --git a/1009_linux-6.11.10.patch b/1009_linux-6.11.10.patch
new file mode 100644
index 00000000..08a334ab
--- /dev/null
+++ b/1009_linux-6.11.10.patch
@@ -0,0 +1,4469 @@
+diff --git a/Makefile b/Makefile
+index 3e48c8d84540bc..4b075e003b2d61 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,7 +1,7 @@
+ # SPDX-License-Identifier: GPL-2.0
+ VERSION = 6
+ PATCHLEVEL = 11
+-SUBLEVEL = 9
++SUBLEVEL = 10
+ EXTRAVERSION =
+ NAME = Baby Opossum Posse
+
+diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
+index 173159e93c99c4..a1e5cdc1b336ae 100644
+--- a/arch/arm/Kconfig
++++ b/arch/arm/Kconfig
+@@ -1597,6 +1597,9 @@ config ATAGS_PROC
+ config ARCH_SUPPORTS_CRASH_DUMP
+ def_bool y
+
++config ARCH_DEFAULT_CRASH_DUMP
++ def_bool y
++
+ config AUTO_ZRELADDR
+ bool "Auto calculation of the decompressed kernel image address" if !ARCH_MULTIPLATFORM
+ default !(ARCH_FOOTBRIDGE || ARCH_RPC || ARCH_SA1100)
+diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
+index 1ec35f065617e4..28873cda464f51 100644
+--- a/arch/arm/kernel/head.S
++++ b/arch/arm/kernel/head.S
+@@ -252,11 +252,15 @@ __create_page_tables:
+ */
+ add r0, r4, #KERNEL_OFFSET >> (SECTION_SHIFT - PMD_ENTRY_ORDER)
+ ldr r6, =(_end - 1)
++
++ /* For XIP, kernel_sec_start/kernel_sec_end are currently in RO memory */
++#ifndef CONFIG_XIP_KERNEL
+ adr_l r5, kernel_sec_start @ _pa(kernel_sec_start)
+ #if defined CONFIG_CPU_ENDIAN_BE8 || defined CONFIG_CPU_ENDIAN_BE32
+ str r8, [r5, #4] @ Save physical start of kernel (BE)
+ #else
+ str r8, [r5] @ Save physical start of kernel (LE)
++#endif
+ #endif
+ orr r3, r8, r7 @ Add the MMU flags
+ add r6, r4, r6, lsr #(SECTION_SHIFT - PMD_ENTRY_ORDER)
+@@ -264,6 +268,7 @@ __create_page_tables:
+ add r3, r3, #1 << SECTION_SHIFT
+ cmp r0, r6
+ bls 1b
++#ifndef CONFIG_XIP_KERNEL
+ eor r3, r3, r7 @ Remove the MMU flags
+ adr_l r5, kernel_sec_end @ _pa(kernel_sec_end)
+ #if defined CONFIG_CPU_ENDIAN_BE8 || defined CONFIG_CPU_ENDIAN_BE32
+@@ -271,8 +276,7 @@ __create_page_tables:
+ #else
+ str r3, [r5] @ Save physical end of kernel (LE)
+ #endif
+-
+-#ifdef CONFIG_XIP_KERNEL
++#else
+ /*
+ * Map the kernel image separately as it is not located in RAM.
+ */
+diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
+index 480e307501bb4b..6ea645939573fb 100644
+--- a/arch/arm/kernel/traps.c
++++ b/arch/arm/kernel/traps.c
+@@ -570,6 +570,7 @@ static int bad_syscall(int n, struct pt_regs *regs)
+ static inline int
+ __do_cache_op(unsigned long start, unsigned long end)
+ {
++ unsigned int ua_flags;
+ int ret;
+
+ do {
+@@ -578,7 +579,9 @@ __do_cache_op(unsigned long start, unsigned long end)
+ if (fatal_signal_pending(current))
+ return 0;
+
++ ua_flags = uaccess_save_and_enable();
+ ret = flush_icache_user_range(start, start + chunk);
++ uaccess_restore(ua_flags);
+ if (ret)
+ return ret;
+
+diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
+index 3f774856ca6763..b6ad0a8810e427 100644
+--- a/arch/arm/mm/mmu.c
++++ b/arch/arm/mm/mmu.c
+@@ -1402,18 +1402,6 @@ static void __init devicemaps_init(const struct machine_desc *mdesc)
+ create_mapping(&map);
+ }
+
+- /*
+- * Map the kernel if it is XIP.
+- * It is always first in the modulearea.
+- */
+-#ifdef CONFIG_XIP_KERNEL
+- map.pfn = __phys_to_pfn(CONFIG_XIP_PHYS_ADDR & SECTION_MASK);
+- map.virtual = MODULES_VADDR;
+- map.length = ((unsigned long)_exiprom - map.virtual + ~SECTION_MASK) & SECTION_MASK;
+- map.type = MT_ROM;
+- create_mapping(&map);
+-#endif
+-
+ /*
+ * Map the cache flushing regions.
+ */
+@@ -1603,12 +1591,27 @@ static void __init map_kernel(void)
+ * This will only persist until we turn on proper memory management later on
+ * and we remap the whole kernel with page granularity.
+ */
++#ifdef CONFIG_XIP_KERNEL
++ phys_addr_t kernel_nx_start = kernel_sec_start;
++#else
+ phys_addr_t kernel_x_start = kernel_sec_start;
+ phys_addr_t kernel_x_end = round_up(__pa(__init_end), SECTION_SIZE);
+ phys_addr_t kernel_nx_start = kernel_x_end;
++#endif
+ phys_addr_t kernel_nx_end = kernel_sec_end;
+ struct map_desc map;
+
++ /*
++ * Map the kernel if it is XIP.
++ * It is always first in the modulearea.
++ */
++#ifdef CONFIG_XIP_KERNEL
++ map.pfn = __phys_to_pfn(CONFIG_XIP_PHYS_ADDR & SECTION_MASK);
++ map.virtual = MODULES_VADDR;
++ map.length = ((unsigned long)_exiprom - map.virtual + ~SECTION_MASK) & SECTION_MASK;
++ map.type = MT_ROM;
++ create_mapping(&map);
++#else
+ map.pfn = __phys_to_pfn(kernel_x_start);
+ map.virtual = __phys_to_virt(kernel_x_start);
+ map.length = kernel_x_end - kernel_x_start;
+@@ -1618,7 +1621,7 @@ static void __init map_kernel(void)
+ /* If the nx part is small it may end up covered by the tail of the RWX section */
+ if (kernel_x_end == kernel_nx_end)
+ return;
+-
++#endif
+ map.pfn = __phys_to_pfn(kernel_nx_start);
+ map.virtual = __phys_to_virt(kernel_nx_start);
+ map.length = kernel_nx_end - kernel_nx_start;
+@@ -1762,6 +1765,11 @@ void __init paging_init(const struct machine_desc *mdesc)
+ {
+ void *zero_page;
+
++#ifdef CONFIG_XIP_KERNEL
++ /* Store the kernel RW RAM region start/end in these variables */
++ kernel_sec_start = CONFIG_PHYS_OFFSET & SECTION_MASK;
++ kernel_sec_end = round_up(__pa(_end), SECTION_SIZE);
++#endif
+ pr_debug("physical kernel sections: 0x%08llx-0x%08llx\n",
+ kernel_sec_start, kernel_sec_end);
+
+diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
+index 402ae0297993c2..7d92c0a9c43d42 100644
+--- a/arch/arm64/Kconfig
++++ b/arch/arm64/Kconfig
+@@ -1559,6 +1559,9 @@ config ARCH_DEFAULT_KEXEC_IMAGE_VERIFY_SIG
+ config ARCH_SUPPORTS_CRASH_DUMP
+ def_bool y
+
++config ARCH_DEFAULT_CRASH_DUMP
++ def_bool y
++
+ config ARCH_HAS_GENERIC_CRASHKERNEL_RESERVATION
+ def_bool CRASH_RESERVE
+
+diff --git a/arch/arm64/include/asm/mman.h b/arch/arm64/include/asm/mman.h
+index 5966ee4a61542e..ef35c52aabd66d 100644
+--- a/arch/arm64/include/asm/mman.h
++++ b/arch/arm64/include/asm/mman.h
+@@ -3,6 +3,8 @@
+ #define __ASM_MMAN_H__
+
+ #include <linux/compiler.h>
++#include <linux/fs.h>
++#include <linux/shmem_fs.h>
+ #include <linux/types.h>
+ #include <uapi/asm/mman.h>
+
+@@ -21,19 +23,21 @@ static inline unsigned long arch_calc_vm_prot_bits(unsigned long prot,
+ }
+ #define arch_calc_vm_prot_bits(prot, pkey) arch_calc_vm_prot_bits(prot, pkey)
+
+-static inline unsigned long arch_calc_vm_flag_bits(unsigned long flags)
++static inline unsigned long arch_calc_vm_flag_bits(struct file *file,
++ unsigned long flags)
+ {
+ /*
+ * Only allow MTE on anonymous mappings as these are guaranteed to be
+ * backed by tags-capable memory. The vm_flags may be overridden by a
+ * filesystem supporting MTE (RAM-based).
+ */
+- if (system_supports_mte() && (flags & MAP_ANONYMOUS))
++ if (system_supports_mte() &&
++ ((flags & MAP_ANONYMOUS) || shmem_file(file)))
+ return VM_MTE_ALLOWED;
+
+ return 0;
+ }
+-#define arch_calc_vm_flag_bits(flags) arch_calc_vm_flag_bits(flags)
++#define arch_calc_vm_flag_bits(file, flags) arch_calc_vm_flag_bits(file, flags)
+
+ static inline bool arch_validate_prot(unsigned long prot,
+ unsigned long addr __always_unused)
+diff --git a/arch/loongarch/Kconfig b/arch/loongarch/Kconfig
+index 70f169210b523f..ce232ddcd27d70 100644
+--- a/arch/loongarch/Kconfig
++++ b/arch/loongarch/Kconfig
+@@ -599,6 +599,9 @@ config ARCH_SUPPORTS_KEXEC
+ config ARCH_SUPPORTS_CRASH_DUMP
+ def_bool y
+
++config ARCH_DEFAULT_CRASH_DUMP
++ def_bool y
++
+ config ARCH_SELECTS_CRASH_DUMP
+ def_bool y
+ depends on CRASH_DUMP
+diff --git a/arch/loongarch/include/asm/kasan.h b/arch/loongarch/include/asm/kasan.h
+index c6bce5fbff57b0..7f52bd31b9d4f5 100644
+--- a/arch/loongarch/include/asm/kasan.h
++++ b/arch/loongarch/include/asm/kasan.h
+@@ -25,6 +25,7 @@
+ /* 64-bit segment value. */
+ #define XKPRANGE_UC_SEG (0x8000)
+ #define XKPRANGE_CC_SEG (0x9000)
++#define XKPRANGE_WC_SEG (0xa000)
+ #define XKVRANGE_VC_SEG (0xffff)
+
+ /* Cached */
+@@ -41,20 +42,28 @@
+ #define XKPRANGE_UC_SHADOW_SIZE (XKPRANGE_UC_SIZE >> KASAN_SHADOW_SCALE_SHIFT)
+ #define XKPRANGE_UC_SHADOW_END (XKPRANGE_UC_KASAN_OFFSET + XKPRANGE_UC_SHADOW_SIZE)
+
++/* WriteCombine */
++#define XKPRANGE_WC_START WRITECOMBINE_BASE
++#define XKPRANGE_WC_SIZE XRANGE_SIZE
++#define XKPRANGE_WC_KASAN_OFFSET XKPRANGE_UC_SHADOW_END
++#define XKPRANGE_WC_SHADOW_SIZE (XKPRANGE_WC_SIZE >> KASAN_SHADOW_SCALE_SHIFT)
++#define XKPRANGE_WC_SHADOW_END (XKPRANGE_WC_KASAN_OFFSET + XKPRANGE_WC_SHADOW_SIZE)
++
+ /* VMALLOC (Cached or UnCached) */
+ #define XKVRANGE_VC_START MODULES_VADDR
+ #define XKVRANGE_VC_SIZE round_up(KFENCE_AREA_END - MODULES_VADDR + 1, PGDIR_SIZE)
+-#define XKVRANGE_VC_KASAN_OFFSET XKPRANGE_UC_SHADOW_END
++#define XKVRANGE_VC_KASAN_OFFSET XKPRANGE_WC_SHADOW_END
+ #define XKVRANGE_VC_SHADOW_SIZE (XKVRANGE_VC_SIZE >> KASAN_SHADOW_SCALE_SHIFT)
+ #define XKVRANGE_VC_SHADOW_END (XKVRANGE_VC_KASAN_OFFSET + XKVRANGE_VC_SHADOW_SIZE)
+
+ /* KAsan shadow memory start right after vmalloc. */
+ #define KASAN_SHADOW_START round_up(KFENCE_AREA_END, PGDIR_SIZE)
+ #define KASAN_SHADOW_SIZE (XKVRANGE_VC_SHADOW_END - XKPRANGE_CC_KASAN_OFFSET)
+-#define KASAN_SHADOW_END round_up(KASAN_SHADOW_START + KASAN_SHADOW_SIZE, PGDIR_SIZE)
++#define KASAN_SHADOW_END (round_up(KASAN_SHADOW_START + KASAN_SHADOW_SIZE, PGDIR_SIZE) - 1)
+
+ #define XKPRANGE_CC_SHADOW_OFFSET (KASAN_SHADOW_START + XKPRANGE_CC_KASAN_OFFSET)
+ #define XKPRANGE_UC_SHADOW_OFFSET (KASAN_SHADOW_START + XKPRANGE_UC_KASAN_OFFSET)
++#define XKPRANGE_WC_SHADOW_OFFSET (KASAN_SHADOW_START + XKPRANGE_WC_KASAN_OFFSET)
+ #define XKVRANGE_VC_SHADOW_OFFSET (KASAN_SHADOW_START + XKVRANGE_VC_KASAN_OFFSET)
+
+ extern bool kasan_early_stage;
+diff --git a/arch/loongarch/kernel/paravirt.c b/arch/loongarch/kernel/paravirt.c
+index 9c9b75b76f62f2..867fa816726cf3 100644
+--- a/arch/loongarch/kernel/paravirt.c
++++ b/arch/loongarch/kernel/paravirt.c
+@@ -50,11 +50,18 @@ static u64 paravt_steal_clock(int cpu)
+ }
+
+ #ifdef CONFIG_SMP
++static struct smp_ops native_ops;
++
+ static void pv_send_ipi_single(int cpu, unsigned int action)
+ {
+ int min, old;
+ irq_cpustat_t *info = &per_cpu(irq_stat, cpu);
+
++ if (unlikely(action == ACTION_BOOT_CPU)) {
++ native_ops.send_ipi_single(cpu, action);
++ return;
++ }
++
+ old = atomic_fetch_or(BIT(action), &info->message);
+ if (old)
+ return;
+@@ -74,6 +81,11 @@ static void pv_send_ipi_mask(const struct cpumask *mask, unsigned int action)
+ if (cpumask_empty(mask))
+ return;
+
++ if (unlikely(action == ACTION_BOOT_CPU)) {
++ native_ops.send_ipi_mask(mask, action);
++ return;
++ }
++
+ action = BIT(action);
+ for_each_cpu(i, mask) {
+ info = &per_cpu(irq_stat, i);
+@@ -141,6 +153,8 @@ static void pv_init_ipi(void)
+ {
+ int r, swi;
+
++ /* Init native ipi irq for ACTION_BOOT_CPU */
++ native_ops.init_ipi();
+ swi = get_percpu_irq(INT_SWI0);
+ if (swi < 0)
+ panic("SWI0 IRQ mapping failed\n");
+@@ -179,6 +193,7 @@ int __init pv_ipi_init(void)
+ return 0;
+
+ #ifdef CONFIG_SMP
++ native_ops = mp_ops;
+ mp_ops.init_ipi = pv_init_ipi;
+ mp_ops.send_ipi_single = pv_send_ipi_single;
+ mp_ops.send_ipi_mask = pv_send_ipi_mask;
+diff --git a/arch/loongarch/kernel/smp.c b/arch/loongarch/kernel/smp.c
+index ca405ab86aaef6..b1329fe01fae90 100644
+--- a/arch/loongarch/kernel/smp.c
++++ b/arch/loongarch/kernel/smp.c
+@@ -296,7 +296,7 @@ static void __init fdt_smp_setup(void)
+ __cpu_number_map[cpuid] = cpu;
+ __cpu_logical_map[cpu] = cpuid;
+
+- early_numa_add_cpu(cpu, 0);
++ early_numa_add_cpu(cpuid, 0);
+ set_cpuid_to_node(cpuid, 0);
+ }
+
+diff --git a/arch/loongarch/mm/kasan_init.c b/arch/loongarch/mm/kasan_init.c
+index 427d6b1aec09e7..d2681272d8f0f3 100644
+--- a/arch/loongarch/mm/kasan_init.c
++++ b/arch/loongarch/mm/kasan_init.c
+@@ -13,6 +13,13 @@
+
+ static pgd_t kasan_pg_dir[PTRS_PER_PGD] __initdata __aligned(PAGE_SIZE);
+
++#ifdef __PAGETABLE_P4D_FOLDED
++#define __pgd_none(early, pgd) (0)
++#else
++#define __pgd_none(early, pgd) (early ? (pgd_val(pgd) == 0) : \
++(__pa(pgd_val(pgd)) == (unsigned long)__pa(kasan_early_shadow_p4d)))
++#endif
++
+ #ifdef __PAGETABLE_PUD_FOLDED
+ #define __p4d_none(early, p4d) (0)
+ #else
+@@ -55,6 +62,9 @@ void *kasan_mem_to_shadow(const void *addr)
+ case XKPRANGE_UC_SEG:
+ offset = XKPRANGE_UC_SHADOW_OFFSET;
+ break;
++ case XKPRANGE_WC_SEG:
++ offset = XKPRANGE_WC_SHADOW_OFFSET;
++ break;
+ case XKVRANGE_VC_SEG:
+ offset = XKVRANGE_VC_SHADOW_OFFSET;
+ break;
+@@ -79,6 +89,8 @@ const void *kasan_shadow_to_mem(const void *shadow_addr)
+
+ if (addr >= XKVRANGE_VC_SHADOW_OFFSET)
+ return (void *)(((addr - XKVRANGE_VC_SHADOW_OFFSET) << KASAN_SHADOW_SCALE_SHIFT) + XKVRANGE_VC_START);
++ else if (addr >= XKPRANGE_WC_SHADOW_OFFSET)
++ return (void *)(((addr - XKPRANGE_WC_SHADOW_OFFSET) << KASAN_SHADOW_SCALE_SHIFT) + XKPRANGE_WC_START);
+ else if (addr >= XKPRANGE_UC_SHADOW_OFFSET)
+ return (void *)(((addr - XKPRANGE_UC_SHADOW_OFFSET) << KASAN_SHADOW_SCALE_SHIFT) + XKPRANGE_UC_START);
+ else if (addr >= XKPRANGE_CC_SHADOW_OFFSET)
+@@ -142,6 +154,19 @@ static pud_t *__init kasan_pud_offset(p4d_t *p4dp, unsigned long addr, int node,
+ return pud_offset(p4dp, addr);
+ }
+
++static p4d_t *__init kasan_p4d_offset(pgd_t *pgdp, unsigned long addr, int node, bool early)
++{
++ if (__pgd_none(early, pgdp_get(pgdp))) {
++ phys_addr_t p4d_phys = early ?
++ __pa_symbol(kasan_early_shadow_p4d) : kasan_alloc_zeroed_page(node);
++ if (!early)
++ memcpy(__va(p4d_phys), kasan_early_shadow_p4d, sizeof(kasan_early_shadow_p4d));
++ pgd_populate(&init_mm, pgdp, (p4d_t *)__va(p4d_phys));
++ }
++
++ return p4d_offset(pgdp, addr);
++}
++
+ static void __init kasan_pte_populate(pmd_t *pmdp, unsigned long addr,
+ unsigned long end, int node, bool early)
+ {
+@@ -178,19 +203,19 @@ static void __init kasan_pud_populate(p4d_t *p4dp, unsigned long addr,
+ do {
+ next = pud_addr_end(addr, end);
+ kasan_pmd_populate(pudp, addr, next, node, early);
+- } while (pudp++, addr = next, addr != end);
++ } while (pudp++, addr = next, addr != end && __pud_none(early, READ_ONCE(*pudp)));
+ }
+
+ static void __init kasan_p4d_populate(pgd_t *pgdp, unsigned long addr,
+ unsigned long end, int node, bool early)
+ {
+ unsigned long next;
+- p4d_t *p4dp = p4d_offset(pgdp, addr);
++ p4d_t *p4dp = kasan_p4d_offset(pgdp, addr, node, early);
+
+ do {
+ next = p4d_addr_end(addr, end);
+ kasan_pud_populate(p4dp, addr, next, node, early);
+- } while (p4dp++, addr = next, addr != end);
++ } while (p4dp++, addr = next, addr != end && __p4d_none(early, READ_ONCE(*p4dp)));
+ }
+
+ static void __init kasan_pgd_populate(unsigned long addr, unsigned long end,
+@@ -218,7 +243,7 @@ static void __init kasan_map_populate(unsigned long start, unsigned long end,
+ asmlinkage void __init kasan_early_init(void)
+ {
+ BUILD_BUG_ON(!IS_ALIGNED(KASAN_SHADOW_START, PGDIR_SIZE));
+- BUILD_BUG_ON(!IS_ALIGNED(KASAN_SHADOW_END, PGDIR_SIZE));
++ BUILD_BUG_ON(!IS_ALIGNED(KASAN_SHADOW_END + 1, PGDIR_SIZE));
+ }
+
+ static inline void kasan_set_pgd(pgd_t *pgdp, pgd_t pgdval)
+@@ -233,7 +258,7 @@ static void __init clear_pgds(unsigned long start, unsigned long end)
+ * swapper_pg_dir. pgd_clear() can't be used
+ * here because it's nop on 2,3-level pagetable setups
+ */
+- for (; start < end; start += PGDIR_SIZE)
++ for (; start < end; start = pgd_addr_end(start, end))
+ kasan_set_pgd((pgd_t *)pgd_offset_k(start), __pgd(0));
+ }
+
+@@ -242,6 +267,17 @@ void __init kasan_init(void)
+ u64 i;
+ phys_addr_t pa_start, pa_end;
+
++ /*
++ * If PGDIR_SIZE is too large for cpu_vabits, KASAN_SHADOW_END will
++ * overflow UINTPTR_MAX and then looks like a user space address.
++ * For example, PGDIR_SIZE of CONFIG_4KB_4LEVEL is 2^39, which is too
++ * large for Loongson-2K series whose cpu_vabits = 39.
++ */
++ if (KASAN_SHADOW_END < vm_map_base) {
++ pr_warn("PGDIR_SIZE too large for cpu_vabits, KernelAddressSanitizer disabled.\n");
++ return;
++ }
++
+ /*
+ * PGD was populated as invalid_pmd_table or invalid_pud_table
+ * in pagetable_init() which depends on how many levels of page
+diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
+index 60077e57693563..b547f4304d0c3d 100644
+--- a/arch/mips/Kconfig
++++ b/arch/mips/Kconfig
+@@ -2881,6 +2881,9 @@ config ARCH_SUPPORTS_KEXEC
+ config ARCH_SUPPORTS_CRASH_DUMP
+ def_bool y
+
++config ARCH_DEFAULT_CRASH_DUMP
++ def_bool y
++
+ config PHYSICAL_START
+ hex "Physical address where the kernel is loaded"
+ default "0xffffffff84000000"
+diff --git a/arch/parisc/include/asm/mman.h b/arch/parisc/include/asm/mman.h
+index 89b6beeda0b869..663f587dc78965 100644
+--- a/arch/parisc/include/asm/mman.h
++++ b/arch/parisc/include/asm/mman.h
+@@ -2,6 +2,7 @@
+ #ifndef __ASM_MMAN_H__
+ #define __ASM_MMAN_H__
+
++#include <linux/fs.h>
+ #include <uapi/asm/mman.h>
+
+ /* PARISC cannot allow mdwe as it needs writable stacks */
+@@ -11,7 +12,7 @@ static inline bool arch_memory_deny_write_exec_supported(void)
+ }
+ #define arch_memory_deny_write_exec_supported arch_memory_deny_write_exec_supported
+
+-static inline unsigned long arch_calc_vm_flag_bits(unsigned long flags)
++static inline unsigned long arch_calc_vm_flag_bits(struct file *file, unsigned long flags)
+ {
+ /*
+ * The stack on parisc grows upwards, so if userspace requests memory
+@@ -23,6 +24,6 @@ static inline unsigned long arch_calc_vm_flag_bits(unsigned long flags)
+
+ return 0;
+ }
+-#define arch_calc_vm_flag_bits(flags) arch_calc_vm_flag_bits(flags)
++#define arch_calc_vm_flag_bits(file, flags) arch_calc_vm_flag_bits(file, flags)
+
+ #endif /* __ASM_MMAN_H__ */
+diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
+index d7b09b064a8ac5..0f3c1f958eace0 100644
+--- a/arch/powerpc/Kconfig
++++ b/arch/powerpc/Kconfig
+@@ -682,6 +682,10 @@ config RELOCATABLE_TEST
+ config ARCH_SUPPORTS_CRASH_DUMP
+ def_bool PPC64 || PPC_BOOK3S_32 || PPC_85xx || (44x && !SMP)
+
++config ARCH_DEFAULT_CRASH_DUMP
++ bool
++ default y if !PPC_BOOK3S_32
++
+ config ARCH_SELECTS_CRASH_DUMP
+ def_bool y
+ depends on CRASH_DUMP
+diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
+index 6651a5cbdc2717..e513eb642557a3 100644
+--- a/arch/riscv/Kconfig
++++ b/arch/riscv/Kconfig
+@@ -884,6 +884,9 @@ config ARCH_SUPPORTS_KEXEC_PURGATORY
+ config ARCH_SUPPORTS_CRASH_DUMP
+ def_bool y
+
++config ARCH_DEFAULT_CRASH_DUMP
++ def_bool y
++
+ config ARCH_HAS_GENERIC_CRASHKERNEL_RESERVATION
+ def_bool CRASH_RESERVE
+
+diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
+index c60e699e99f5b3..fff371b89e4181 100644
+--- a/arch/s390/Kconfig
++++ b/arch/s390/Kconfig
+@@ -275,6 +275,9 @@ config ARCH_SUPPORTS_CRASH_DUMP
+ This option also enables s390 zfcpdump.
+ See also <file:Documentation/arch/s390/zfcpdump.rst>
+
++config ARCH_DEFAULT_CRASH_DUMP
++ def_bool y
++
+ menu "Processor type and features"
+
+ config HAVE_MARCH_Z10_FEATURES
+diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
+index 1aa3c4a0c5b276..3a6338962636ae 100644
+--- a/arch/sh/Kconfig
++++ b/arch/sh/Kconfig
+@@ -549,6 +549,9 @@ config ARCH_SUPPORTS_KEXEC
+ config ARCH_SUPPORTS_CRASH_DUMP
+ def_bool BROKEN_ON_SMP
+
++config ARCH_DEFAULT_CRASH_DUMP
++ def_bool y
++
+ config ARCH_SUPPORTS_KEXEC_JUMP
+ def_bool y
+
+diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
+index 4e0b05a6bb5c36..ca70367ac54407 100644
+--- a/arch/x86/Kconfig
++++ b/arch/x86/Kconfig
+@@ -2087,6 +2087,9 @@ config ARCH_SUPPORTS_KEXEC_JUMP
+ config ARCH_SUPPORTS_CRASH_DUMP
+ def_bool X86_64 || (X86_32 && HIGHMEM)
+
++config ARCH_DEFAULT_CRASH_DUMP
++ def_bool y
++
+ config ARCH_SUPPORTS_CRASH_HOTPLUG
+ def_bool y
+
+diff --git a/arch/x86/Makefile b/arch/x86/Makefile
+index 801fd85c3ef693..5fb0cc6c16420e 100644
+--- a/arch/x86/Makefile
++++ b/arch/x86/Makefile
+@@ -138,9 +138,10 @@ ifeq ($(CONFIG_X86_32),y)
+
+ ifeq ($(CONFIG_STACKPROTECTOR),y)
+ ifeq ($(CONFIG_SMP),y)
+- KBUILD_CFLAGS += -mstack-protector-guard-reg=fs -mstack-protector-guard-symbol=__stack_chk_guard
++ KBUILD_CFLAGS += -mstack-protector-guard-reg=fs \
++ -mstack-protector-guard-symbol=__ref_stack_chk_guard
+ else
+- KBUILD_CFLAGS += -mstack-protector-guard=global
++ KBUILD_CFLAGS += -mstack-protector-guard=global
+ endif
+ endif
+ else
+diff --git a/arch/x86/entry/entry.S b/arch/x86/entry/entry.S
+index 324686bca36813..b7ea3e8e9eccd5 100644
+--- a/arch/x86/entry/entry.S
++++ b/arch/x86/entry/entry.S
+@@ -51,3 +51,19 @@ EXPORT_SYMBOL_GPL(mds_verw_sel);
+ .popsection
+
+ THUNK warn_thunk_thunk, __warn_thunk
++
++#ifndef CONFIG_X86_64
++/*
++ * Clang's implementation of TLS stack cookies requires the variable in
++ * question to be a TLS variable. If the variable happens to be defined as an
++ * ordinary variable with external linkage in the same compilation unit (which
++ * amounts to the whole of vmlinux with LTO enabled), Clang will drop the
++ * segment register prefix from the references, resulting in broken code. Work
++ * around this by avoiding the symbol used in -mstack-protector-guard-symbol=
++ * entirely in the C code, and use an alias emitted by the linker script
++ * instead.
++ */
++#ifdef CONFIG_STACKPROTECTOR
++EXPORT_SYMBOL(__ref_stack_chk_guard);
++#endif
++#endif
+diff --git a/arch/x86/include/asm/asm-prototypes.h b/arch/x86/include/asm/asm-prototypes.h
+index 25466c4d213481..3674006e39744e 100644
+--- a/arch/x86/include/asm/asm-prototypes.h
++++ b/arch/x86/include/asm/asm-prototypes.h
+@@ -20,3 +20,6 @@
+ extern void cmpxchg8b_emu(void);
+ #endif
+
++#if defined(__GENKSYMS__) && defined(CONFIG_STACKPROTECTOR)
++extern unsigned long __ref_stack_chk_guard;
++#endif
+diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c
+index f01b72052f7908..2b8ca66793fb03 100644
+--- a/arch/x86/kernel/cpu/amd.c
++++ b/arch/x86/kernel/cpu/amd.c
+@@ -924,6 +924,17 @@ static void init_amd_zen4(struct cpuinfo_x86 *c)
+ {
+ if (!cpu_has(c, X86_FEATURE_HYPERVISOR))
+ msr_set_bit(MSR_ZEN4_BP_CFG, MSR_ZEN4_BP_CFG_SHARED_BTB_FIX_BIT);
++
++ /*
++ * These Zen4 SoCs advertise support for virtualized VMLOAD/VMSAVE
++ * in some BIOS versions but they can lead to random host reboots.
++ */
++ switch (c->x86_model) {
++ case 0x18 ... 0x1f:
++ case 0x60 ... 0x7f:
++ clear_cpu_cap(c, X86_FEATURE_V_VMSAVE_VMLOAD);
++ break;
++ }
+ }
+
+ static void init_amd_zen5(struct cpuinfo_x86 *c)
+diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
+index b7d97f97cd9822..c472282ab40fd2 100644
+--- a/arch/x86/kernel/cpu/common.c
++++ b/arch/x86/kernel/cpu/common.c
+@@ -2084,8 +2084,10 @@ void syscall_init(void)
+
+ #ifdef CONFIG_STACKPROTECTOR
+ DEFINE_PER_CPU(unsigned long, __stack_chk_guard);
++#ifndef CONFIG_SMP
+ EXPORT_PER_CPU_SYMBOL(__stack_chk_guard);
+ #endif
++#endif
+
+ #endif /* CONFIG_X86_64 */
+
+diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S
+index 6fb8d7ba9b50aa..37b13394df7ab0 100644
+--- a/arch/x86/kernel/vmlinux.lds.S
++++ b/arch/x86/kernel/vmlinux.lds.S
+@@ -492,6 +492,9 @@ SECTIONS
+ . = ASSERT((_end - LOAD_OFFSET <= KERNEL_IMAGE_SIZE),
+ "kernel image bigger than KERNEL_IMAGE_SIZE");
+
++/* needed for Clang - see arch/x86/entry/entry.S */
++PROVIDE(__ref_stack_chk_guard = __stack_chk_guard);
++
+ #ifdef CONFIG_X86_64
+ /*
+ * Per-cpu symbols which need to be offset from __per_cpu_load
+diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
+index b1269e2bb76161..ed18109ef220c6 100644
+--- a/arch/x86/kvm/lapic.c
++++ b/arch/x86/kvm/lapic.c
+@@ -2629,19 +2629,26 @@ void kvm_apic_update_apicv(struct kvm_vcpu *vcpu)
+ {
+ struct kvm_lapic *apic = vcpu->arch.apic;
+
+- if (apic->apicv_active) {
+- /* irr_pending is always true when apicv is activated. */
+- apic->irr_pending = true;
++ /*
++ * When APICv is enabled, KVM must always search the IRR for a pending
++ * IRQ, as other vCPUs and devices can set IRR bits even if the vCPU
++ * isn't running. If APICv is disabled, KVM _should_ search the IRR
++ * for a pending IRQ. But KVM currently doesn't ensure *all* hardware,
++ * e.g. CPUs and IOMMUs, has seen the change in state, i.e. searching
++ * the IRR at this time could race with IRQ delivery from hardware that
++ * still sees APICv as being enabled.
++ *
++ * FIXME: Ensure other vCPUs and devices observe the change in APICv
++ * state prior to updating KVM's metadata caches, so that KVM
++ * can safely search the IRR and set irr_pending accordingly.
++ */
++ apic->irr_pending = true;
++
++ if (apic->apicv_active)
+ apic->isr_count = 1;
+- } else {
+- /*
+- * Don't clear irr_pending, searching the IRR can race with
+- * updates from the CPU as APICv is still active from hardware's
+- * perspective. The flag will be cleared as appropriate when
+- * KVM injects the interrupt.
+- */
++ else
+ apic->isr_count = count_vectors(apic->regs + APIC_ISR);
+- }
++
+ apic->highest_isr_cache = -1;
+ }
+
+diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c
+index 2392a7ef254df2..52bb847372fb4d 100644
+--- a/arch/x86/kvm/vmx/nested.c
++++ b/arch/x86/kvm/vmx/nested.c
+@@ -1197,11 +1197,14 @@ static void nested_vmx_transition_tlb_flush(struct kvm_vcpu *vcpu,
+ kvm_hv_nested_transtion_tlb_flush(vcpu, enable_ept);
+
+ /*
+- * If vmcs12 doesn't use VPID, L1 expects linear and combined mappings
+- * for *all* contexts to be flushed on VM-Enter/VM-Exit, i.e. it's a
+- * full TLB flush from the guest's perspective. This is required even
+- * if VPID is disabled in the host as KVM may need to synchronize the
+- * MMU in response to the guest TLB flush.
++ * If VPID is disabled, then guest TLB accesses use VPID=0, i.e. the
++ * same VPID as the host, and so architecturally, linear and combined
++ * mappings for VPID=0 must be flushed at VM-Enter and VM-Exit. KVM
++ * emulates L2 sharing L1's VPID=0 by using vpid01 while running L2,
++ * and so KVM must also emulate TLB flush of VPID=0, i.e. vpid01. This
++ * is required if VPID is disabled in KVM, as a TLB flush (there are no
++ * VPIDs) still occurs from L1's perspective, and KVM may need to
++ * synchronize the MMU in response to the guest TLB flush.
+ *
+ * Note, using TLB_FLUSH_GUEST is correct even if nested EPT is in use.
+ * EPT is a special snowflake, as guest-physical mappings aren't
+@@ -2291,6 +2294,17 @@ static void prepare_vmcs02_early_rare(struct vcpu_vmx *vmx,
+
+ vmcs_write64(VMCS_LINK_POINTER, INVALID_GPA);
+
++ /*
++ * If VPID is disabled, then guest TLB accesses use VPID=0, i.e. the
++ * same VPID as the host. Emulate this behavior by using vpid01 for L2
++ * if VPID is disabled in vmcs12. Note, if VPID is disabled, VM-Enter
++ * and VM-Exit are architecturally required to flush VPID=0, but *only*
++ * VPID=0. I.e. using vpid02 would be ok (so long as KVM emulates the
++ * required flushes), but doing so would cause KVM to over-flush. E.g.
++ * if L1 runs L2 X with VPID12=1, then runs L2 Y with VPID12 disabled,
++ * and then runs L2 X again, then KVM can and should retain TLB entries
++ * for VPID12=1.
++ */
+ if (enable_vpid) {
+ if (nested_cpu_has_vpid(vmcs12) && vmx->nested.vpid02)
+ vmcs_write16(VIRTUAL_PROCESSOR_ID, vmx->nested.vpid02);
+@@ -5890,6 +5904,12 @@ static int handle_invvpid(struct kvm_vcpu *vcpu)
+ return nested_vmx_fail(vcpu,
+ VMXERR_INVALID_OPERAND_TO_INVEPT_INVVPID);
+
++ /*
++ * Always flush the effective vpid02, i.e. never flush the current VPID
++ * and never explicitly flush vpid01. INVVPID targets a VPID, not a
++ * VMCS, and so whether or not the current vmcs12 has VPID enabled is
++ * irrelevant (and there may not be a loaded vmcs12).
++ */
+ vpid02 = nested_get_vpid02(vcpu);
+ switch (type) {
+ case VMX_VPID_EXTENT_INDIVIDUAL_ADDR:
+diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
+index 733a0c45d1a612..5455106b6d9c59 100644
+--- a/arch/x86/kvm/vmx/vmx.c
++++ b/arch/x86/kvm/vmx/vmx.c
+@@ -217,9 +217,11 @@ module_param(ple_window_shrink, uint, 0444);
+ static unsigned int ple_window_max = KVM_VMX_DEFAULT_PLE_WINDOW_MAX;
+ module_param(ple_window_max, uint, 0444);
+
+-/* Default is SYSTEM mode, 1 for host-guest mode */
++/* Default is SYSTEM mode, 1 for host-guest mode (which is BROKEN) */
+ int __read_mostly pt_mode = PT_MODE_SYSTEM;
++#ifdef CONFIG_BROKEN
+ module_param(pt_mode, int, S_IRUGO);
++#endif
+
+ struct x86_pmu_lbr __ro_after_init vmx_lbr_caps;
+
+@@ -3220,7 +3222,7 @@ void vmx_flush_tlb_all(struct kvm_vcpu *vcpu)
+
+ static inline int vmx_get_current_vpid(struct kvm_vcpu *vcpu)
+ {
+- if (is_guest_mode(vcpu))
++ if (is_guest_mode(vcpu) && nested_cpu_has_vpid(get_vmcs12(vcpu)))
+ return nested_get_vpid02(vcpu);
+ return to_vmx(vcpu)->vpid;
+ }
+diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c
+index aa7d279321ea0c..2c102dc164e197 100644
+--- a/arch/x86/mm/ioremap.c
++++ b/arch/x86/mm/ioremap.c
+@@ -655,7 +655,8 @@ static bool memremap_is_setup_data(resource_size_t phys_addr,
+ paddr_next = data->next;
+ len = data->len;
+
+- if ((phys_addr > paddr) && (phys_addr < (paddr + len))) {
++ if ((phys_addr > paddr) &&
++ (phys_addr < (paddr + sizeof(struct setup_data) + len))) {
+ memunmap(data);
+ return true;
+ }
+@@ -717,7 +718,8 @@ static bool __init early_memremap_is_setup_data(resource_size_t phys_addr,
+ paddr_next = data->next;
+ len = data->len;
+
+- if ((phys_addr > paddr) && (phys_addr < (paddr + len))) {
++ if ((phys_addr > paddr) &&
++ (phys_addr < (paddr + sizeof(struct setup_data) + len))) {
+ early_memunmap(data, sizeof(*data));
+ return true;
+ }
+diff --git a/drivers/bluetooth/btintel.c b/drivers/bluetooth/btintel.c
+index 1ccbb515751533..24d2f4f37d0fd5 100644
+--- a/drivers/bluetooth/btintel.c
++++ b/drivers/bluetooth/btintel.c
+@@ -3288,13 +3288,12 @@ static int btintel_diagnostics(struct hci_dev *hdev, struct sk_buff *skb)
+ case INTEL_TLV_TEST_EXCEPTION:
+ /* Generate devcoredump from exception */
+ if (!hci_devcd_init(hdev, skb->len)) {
+- hci_devcd_append(hdev, skb);
++ hci_devcd_append(hdev, skb_clone(skb, GFP_ATOMIC));
+ hci_devcd_complete(hdev);
+ } else {
+ bt_dev_err(hdev, "Failed to generate devcoredump");
+- kfree_skb(skb);
+ }
+- return 0;
++ break;
+ default:
+ bt_dev_err(hdev, "Invalid exception type %02X", tlv->val[0]);
+ }
+diff --git a/drivers/char/tpm/tpm2-sessions.c b/drivers/char/tpm/tpm2-sessions.c
+index c8fdfe901dfb7c..adbf47967707d7 100644
+--- a/drivers/char/tpm/tpm2-sessions.c
++++ b/drivers/char/tpm/tpm2-sessions.c
+@@ -948,10 +948,13 @@ static int tpm2_load_null(struct tpm_chip *chip, u32 *null_key)
+ /* Deduce from the name change TPM interference: */
+ dev_err(&chip->dev, "null key integrity check failed\n");
+ tpm2_flush_context(chip, tmp_null_key);
+- chip->flags |= TPM_CHIP_FLAG_DISABLE;
+
+ err:
+- return rc ? -ENODEV : 0;
++ if (rc) {
++ chip->flags |= TPM_CHIP_FLAG_DISABLE;
++ rc = -ENODEV;
++ }
++ return rc;
+ }
+
+ /**
+diff --git a/drivers/firmware/arm_scmi/perf.c b/drivers/firmware/arm_scmi/perf.c
+index 4b7f1cbb9b04d6..408f1652886292 100644
+--- a/drivers/firmware/arm_scmi/perf.c
++++ b/drivers/firmware/arm_scmi/perf.c
+@@ -373,7 +373,7 @@ static int iter_perf_levels_update_state(struct scmi_iterator_state *st,
+ return 0;
+ }
+
+-static inline void
++static inline int
+ process_response_opp(struct device *dev, struct perf_dom_info *dom,
+ struct scmi_opp *opp, unsigned int loop_idx,
+ const struct scmi_msg_resp_perf_describe_levels *r)
+@@ -386,12 +386,16 @@ process_response_opp(struct device *dev, struct perf_dom_info *dom,
+ le16_to_cpu(r->opp[loop_idx].transition_latency_us);
+
+ ret = xa_insert(&dom->opps_by_lvl, opp->perf, opp, GFP_KERNEL);
+- if (ret)
+- dev_warn(dev, "Failed to add opps_by_lvl at %d for %s - ret:%d\n",
++ if (ret) {
++ dev_info(dev, FW_BUG "Failed to add opps_by_lvl at %d for %s - ret:%d\n",
+ opp->perf, dom->info.name, ret);
++ return ret;
++ }
++
++ return 0;
+ }
+
+-static inline void
++static inline int
+ process_response_opp_v4(struct device *dev, struct perf_dom_info *dom,
+ struct scmi_opp *opp, unsigned int loop_idx,
+ const struct scmi_msg_resp_perf_describe_levels_v4 *r)
+@@ -404,9 +408,11 @@ process_response_opp_v4(struct device *dev, struct perf_dom_info *dom,
+ le16_to_cpu(r->opp[loop_idx].transition_latency_us);
+
+ ret = xa_insert(&dom->opps_by_lvl, opp->perf, opp, GFP_KERNEL);
+- if (ret)
+- dev_warn(dev, "Failed to add opps_by_lvl at %d for %s - ret:%d\n",
++ if (ret) {
++ dev_info(dev, FW_BUG "Failed to add opps_by_lvl at %d for %s - ret:%d\n",
+ opp->perf, dom->info.name, ret);
++ return ret;
++ }
+
+ /* Note that PERF v4 reports always five 32-bit words */
+ opp->indicative_freq = le32_to_cpu(r->opp[loop_idx].indicative_freq);
+@@ -415,13 +421,21 @@ process_response_opp_v4(struct device *dev, struct perf_dom_info *dom,
+
+ ret = xa_insert(&dom->opps_by_idx, opp->level_index, opp,
+ GFP_KERNEL);
+- if (ret)
++ if (ret) {
+ dev_warn(dev,
+ "Failed to add opps_by_idx at %d for %s - ret:%d\n",
+ opp->level_index, dom->info.name, ret);
+
++ /* Cleanup by_lvl too */
++ xa_erase(&dom->opps_by_lvl, opp->perf);
++
++ return ret;
++ }
++
+ hash_add(dom->opps_by_freq, &opp->hash, opp->indicative_freq);
+ }
++
++ return 0;
+ }
+
+ static int
+@@ -429,16 +443,22 @@ iter_perf_levels_process_response(const struct scmi_protocol_handle *ph,
+ const void *response,
+ struct scmi_iterator_state *st, void *priv)
+ {
++ int ret;
+ struct scmi_opp *opp;
+ struct scmi_perf_ipriv *p = priv;
+
+- opp = &p->perf_dom->opp[st->desc_index + st->loop_idx];
++ opp = &p->perf_dom->opp[p->perf_dom->opp_count];
+ if (PROTOCOL_REV_MAJOR(p->version) <= 0x3)
+- process_response_opp(ph->dev, p->perf_dom, opp, st->loop_idx,
+- response);
++ ret = process_response_opp(ph->dev, p->perf_dom, opp,
++ st->loop_idx, response);
+ else
+- process_response_opp_v4(ph->dev, p->perf_dom, opp, st->loop_idx,
+- response);
++ ret = process_response_opp_v4(ph->dev, p->perf_dom, opp,
++ st->loop_idx, response);
++
++ /* Skip BAD duplicates received from firmware */
++ if (ret)
++ return ret == -EBUSY ? 0 : ret;
++
+ p->perf_dom->opp_count++;
+
+ dev_dbg(ph->dev, "Level %d Power %d Latency %dus Ifreq %d Index %d\n",
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
+index e32161f6b67a37..11c5e43fc2fab7 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
+@@ -180,7 +180,8 @@ void amdgpu_bo_placement_from_domain(struct amdgpu_bo *abo, u32 domain)
+ * When GTT is just an alternative to VRAM make sure that we
+ * only use it as fallback and still try to fill up VRAM first.
+ */
+- if (domain & abo->preferred_domains & AMDGPU_GEM_DOMAIN_VRAM)
++ if (domain & abo->preferred_domains & AMDGPU_GEM_DOMAIN_VRAM &&
++ !(adev->flags & AMD_IS_APU))
+ places[c].flags |= TTM_PL_FLAG_FALLBACK;
+ c++;
+ }
+diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
+index b73136d390cc03..6dfa58741afe7a 100644
+--- a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
++++ b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
+@@ -1124,8 +1124,10 @@ static void gmc_v9_0_get_coherence_flags(struct amdgpu_device *adev,
+ uint64_t *flags)
+ {
+ struct amdgpu_device *bo_adev = amdgpu_ttm_adev(bo->tbo.bdev);
+- bool is_vram = bo->tbo.resource->mem_type == TTM_PL_VRAM;
+- bool coherent = bo->flags & (AMDGPU_GEM_CREATE_COHERENT | AMDGPU_GEM_CREATE_EXT_COHERENT);
++ bool is_vram = bo->tbo.resource &&
++ bo->tbo.resource->mem_type == TTM_PL_VRAM;
++ bool coherent = bo->flags & (AMDGPU_GEM_CREATE_COHERENT |
++ AMDGPU_GEM_CREATE_EXT_COHERENT);
+ bool ext_coherent = bo->flags & AMDGPU_GEM_CREATE_EXT_COHERENT;
+ bool uncached = bo->flags & AMDGPU_GEM_CREATE_UNCACHED;
+ struct amdgpu_vm *vm = mapping->bo_va->base.vm;
+@@ -1133,6 +1135,8 @@ static void gmc_v9_0_get_coherence_flags(struct amdgpu_device *adev,
+ bool snoop = false;
+ bool is_local;
+
++ dma_resv_assert_held(bo->tbo.base.resv);
++
+ switch (amdgpu_ip_version(adev, GC_HWIP, 0)) {
+ case IP_VERSION(9, 4, 1):
+ case IP_VERSION(9, 4, 2):
+@@ -1251,9 +1255,8 @@ static void gmc_v9_0_get_vm_pte(struct amdgpu_device *adev,
+ *flags &= ~AMDGPU_PTE_VALID;
+ }
+
+- if (bo && bo->tbo.resource)
+- gmc_v9_0_get_coherence_flags(adev, mapping->bo_va->base.bo,
+- mapping, flags);
++ if ((*flags & AMDGPU_PTE_VALID) && bo)
++ gmc_v9_0_get_coherence_flags(adev, bo, mapping, flags);
+ }
+
+ static void gmc_v9_0_override_vm_pte_flags(struct amdgpu_device *adev,
+diff --git a/drivers/gpu/drm/amd/amdgpu/mes_v12_0.c b/drivers/gpu/drm/amd/amdgpu/mes_v12_0.c
+index 62d792ed0323aa..0383d1f95780a4 100644
+--- a/drivers/gpu/drm/amd/amdgpu/mes_v12_0.c
++++ b/drivers/gpu/drm/amd/amdgpu/mes_v12_0.c
+@@ -524,7 +524,7 @@ static int mes_v12_0_set_hw_resources_1(struct amdgpu_mes *mes, int pipe)
+ mes_set_hw_res_1_pkt.header.type = MES_API_TYPE_SCHEDULER;
+ mes_set_hw_res_1_pkt.header.opcode = MES_SCH_API_SET_HW_RSRC_1;
+ mes_set_hw_res_1_pkt.header.dwsize = API_FRAME_SIZE_IN_DWORDS;
+- mes_set_hw_res_1_pkt.mes_kiq_unmap_timeout = 100;
++ mes_set_hw_res_1_pkt.mes_kiq_unmap_timeout = 0xa;
+
+ return mes_v12_0_submit_pkt_and_poll_completion(mes, pipe,
+ &mes_set_hw_res_1_pkt, sizeof(mes_set_hw_res_1_pkt),
+diff --git a/drivers/gpu/drm/amd/amdgpu/nbio_v7_7.c b/drivers/gpu/drm/amd/amdgpu/nbio_v7_7.c
+index fb37e354a9d5c2..1ac730328516ff 100644
+--- a/drivers/gpu/drm/amd/amdgpu/nbio_v7_7.c
++++ b/drivers/gpu/drm/amd/amdgpu/nbio_v7_7.c
+@@ -247,6 +247,12 @@ static void nbio_v7_7_init_registers(struct amdgpu_device *adev)
+ if (def != data)
+ WREG32_SOC15(NBIO, 0, regBIF0_PCIE_MST_CTRL_3, data);
+
++ switch (adev->ip_versions[NBIO_HWIP][0]) {
++ case IP_VERSION(7, 7, 0):
++ data = RREG32_SOC15(NBIO, 0, regRCC_DEV0_EPF5_STRAP4) & ~BIT(23);
++ WREG32_SOC15(NBIO, 0, regRCC_DEV0_EPF5_STRAP4, data);
++ break;
++ }
+ }
+
+ static void nbio_v7_7_update_medium_grain_clock_gating(struct amdgpu_device *adev,
+diff --git a/drivers/gpu/drm/amd/amdgpu/nv.c b/drivers/gpu/drm/amd/amdgpu/nv.c
+index 4938e6b340e9e4..73065a85e0d264 100644
+--- a/drivers/gpu/drm/amd/amdgpu/nv.c
++++ b/drivers/gpu/drm/amd/amdgpu/nv.c
+@@ -67,8 +67,8 @@ static const struct amd_ip_funcs nv_common_ip_funcs;
+
+ /* Navi */
+ static const struct amdgpu_video_codec_info nv_video_codecs_encode_array[] = {
+- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 2304, 0)},
+- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 4096, 2304, 0)},
++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4096, 0)},
++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 4096, 4096, 0)},
+ };
+
+ static const struct amdgpu_video_codecs nv_video_codecs_encode = {
+@@ -94,8 +94,8 @@ static const struct amdgpu_video_codecs nv_video_codecs_decode = {
+
+ /* Sienna Cichlid */
+ static const struct amdgpu_video_codec_info sc_video_codecs_encode_array[] = {
+- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 2160, 0)},
+- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 7680, 4352, 0)},
++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4096, 0)},
++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 8192, 4352, 0)},
+ };
+
+ static const struct amdgpu_video_codecs sc_video_codecs_encode = {
+@@ -136,8 +136,8 @@ static const struct amdgpu_video_codecs sc_video_codecs_decode_vcn1 = {
+
+ /* SRIOV Sienna Cichlid, not const since data is controlled by host */
+ static struct amdgpu_video_codec_info sriov_sc_video_codecs_encode_array[] = {
+- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 2160, 0)},
+- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 7680, 4352, 0)},
++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4096, 0)},
++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 8192, 4352, 0)},
+ };
+
+ static struct amdgpu_video_codec_info sriov_sc_video_codecs_decode_array_vcn0[] = {
+diff --git a/drivers/gpu/drm/amd/amdgpu/soc15.c b/drivers/gpu/drm/amd/amdgpu/soc15.c
+index 8d16dacdc17203..307185c0e1b8f2 100644
+--- a/drivers/gpu/drm/amd/amdgpu/soc15.c
++++ b/drivers/gpu/drm/amd/amdgpu/soc15.c
+@@ -90,8 +90,8 @@ static const struct amd_ip_funcs soc15_common_ip_funcs;
+ /* Vega, Raven, Arcturus */
+ static const struct amdgpu_video_codec_info vega_video_codecs_encode_array[] =
+ {
+- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 2304, 0)},
+- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 4096, 2304, 0)},
++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4096, 0)},
++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 4096, 4096, 0)},
+ };
+
+ static const struct amdgpu_video_codecs vega_video_codecs_encode =
+diff --git a/drivers/gpu/drm/amd/amdgpu/soc21.c b/drivers/gpu/drm/amd/amdgpu/soc21.c
+index d30ad7d56def9c..bba35880badb9f 100644
+--- a/drivers/gpu/drm/amd/amdgpu/soc21.c
++++ b/drivers/gpu/drm/amd/amdgpu/soc21.c
+@@ -49,13 +49,13 @@ static const struct amd_ip_funcs soc21_common_ip_funcs;
+
+ /* SOC21 */
+ static const struct amdgpu_video_codec_info vcn_4_0_0_video_codecs_encode_array_vcn0[] = {
+- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 2304, 0)},
++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4096, 0)},
+ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 8192, 4352, 0)},
+ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_AV1, 8192, 4352, 0)},
+ };
+
+ static const struct amdgpu_video_codec_info vcn_4_0_0_video_codecs_encode_array_vcn1[] = {
+- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 2304, 0)},
++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4096, 0)},
+ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 8192, 4352, 0)},
+ };
+
+@@ -96,14 +96,14 @@ static const struct amdgpu_video_codecs vcn_4_0_0_video_codecs_decode_vcn1 = {
+
+ /* SRIOV SOC21, not const since data is controlled by host */
+ static struct amdgpu_video_codec_info sriov_vcn_4_0_0_video_codecs_encode_array_vcn0[] = {
+- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 2304, 0)},
+- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 4096, 2304, 0)},
++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4096, 0)},
++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 8192, 4352, 0)},
+ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_AV1, 8192, 4352, 0)},
+ };
+
+ static struct amdgpu_video_codec_info sriov_vcn_4_0_0_video_codecs_encode_array_vcn1[] = {
+- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 2304, 0)},
+- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 4096, 2304, 0)},
++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4096, 0)},
++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 8192, 4352, 0)},
+ };
+
+ static struct amdgpu_video_codecs sriov_vcn_4_0_0_video_codecs_encode_vcn0 = {
+diff --git a/drivers/gpu/drm/amd/amdgpu/soc24.c b/drivers/gpu/drm/amd/amdgpu/soc24.c
+index fd4c3d4f838798..29a848f2466bb9 100644
+--- a/drivers/gpu/drm/amd/amdgpu/soc24.c
++++ b/drivers/gpu/drm/amd/amdgpu/soc24.c
+@@ -48,7 +48,7 @@
+ static const struct amd_ip_funcs soc24_common_ip_funcs;
+
+ static const struct amdgpu_video_codec_info vcn_5_0_0_video_codecs_encode_array_vcn0[] = {
+- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 2304, 0)},
++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4096, 0)},
+ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 8192, 4352, 0)},
+ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_AV1, 8192, 4352, 0)},
+ };
+diff --git a/drivers/gpu/drm/amd/amdgpu/vi.c b/drivers/gpu/drm/amd/amdgpu/vi.c
+index d39c670f622046..792b2eb6bbacea 100644
+--- a/drivers/gpu/drm/amd/amdgpu/vi.c
++++ b/drivers/gpu/drm/amd/amdgpu/vi.c
+@@ -136,15 +136,15 @@ static const struct amdgpu_video_codec_info polaris_video_codecs_encode_array[]
+ {
+ .codec_type = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC,
+ .max_width = 4096,
+- .max_height = 2304,
+- .max_pixels_per_frame = 4096 * 2304,
++ .max_height = 4096,
++ .max_pixels_per_frame = 4096 * 4096,
+ .max_level = 0,
+ },
+ {
+ .codec_type = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC,
+ .max_width = 4096,
+- .max_height = 2304,
+- .max_pixels_per_frame = 4096 * 2304,
++ .max_height = 4096,
++ .max_pixels_per_frame = 4096 * 4096,
+ .max_level = 0,
+ },
+ };
+diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+index 245a26cdfc5222..339bdfb7af2f81 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+@@ -6740,7 +6740,7 @@ create_stream_for_sink(struct drm_connector *connector,
+ if (stream->out_transfer_func.tf == TRANSFER_FUNCTION_GAMMA22)
+ tf = TRANSFER_FUNC_GAMMA_22;
+ mod_build_vsc_infopacket(stream, &stream->vsc_infopacket, stream->output_color_space, tf);
+- aconnector->psr_skip_count = AMDGPU_DM_PSR_ENTRY_DELAY;
++ aconnector->sr_skip_count = AMDGPU_DM_PSR_ENTRY_DELAY;
+
+ }
+ finish:
+@@ -8830,6 +8830,56 @@ static void amdgpu_dm_update_cursor(struct drm_plane *plane,
+ }
+ }
+
++static void amdgpu_dm_enable_self_refresh(struct amdgpu_crtc *acrtc_attach,
++ const struct dm_crtc_state *acrtc_state,
++ const u64 current_ts)
++{
++ struct psr_settings *psr = &acrtc_state->stream->link->psr_settings;
++ struct replay_settings *pr = &acrtc_state->stream->link->replay_settings;
++ struct amdgpu_dm_connector *aconn =
++ (struct amdgpu_dm_connector *)acrtc_state->stream->dm_stream_context;
++
++ if (acrtc_state->update_type > UPDATE_TYPE_FAST) {
++ if (pr->config.replay_supported && !pr->replay_feature_enabled)
++ amdgpu_dm_link_setup_replay(acrtc_state->stream->link, aconn);
++ else if (psr->psr_version != DC_PSR_VERSION_UNSUPPORTED &&
++ !psr->psr_feature_enabled)
++ if (!aconn->disallow_edp_enter_psr)
++ amdgpu_dm_link_setup_psr(acrtc_state->stream);
++ }
++
++ /* Decrement skip count when SR is enabled and we're doing fast updates. */
++ if (acrtc_state->update_type == UPDATE_TYPE_FAST &&
++ (psr->psr_feature_enabled || pr->config.replay_supported)) {
++ if (aconn->sr_skip_count > 0)
++ aconn->sr_skip_count--;
++
++ /* Allow SR when skip count is 0. */
++ acrtc_attach->dm_irq_params.allow_sr_entry = !aconn->sr_skip_count;
++
++ /*
++ * If sink supports PSR SU/Panel Replay, there is no need to rely on
++ * a vblank event disable request to enable PSR/RP. PSR SU/RP
++ * can be enabled immediately once OS demonstrates an
++ * adequate number of fast atomic commits to notify KMD
++ * of update events. See `vblank_control_worker()`.
++ */
++ if (acrtc_attach->dm_irq_params.allow_sr_entry &&
++#ifdef CONFIG_DRM_AMD_SECURE_DISPLAY
++ !amdgpu_dm_crc_window_is_activated(acrtc_state->base.crtc) &&
++#endif
++ (current_ts - psr->psr_dirty_rects_change_timestamp_ns) > 500000000) {
++ if (pr->replay_feature_enabled && !pr->replay_allow_active)
++ amdgpu_dm_replay_enable(acrtc_state->stream, true);
++ if (psr->psr_version >= DC_PSR_VERSION_SU_1 &&
++ !psr->psr_allow_active && !aconn->disallow_edp_enter_psr)
++ amdgpu_dm_psr_enable(acrtc_state->stream);
++ }
++ } else {
++ acrtc_attach->dm_irq_params.allow_sr_entry = false;
++ }
++}
++
+ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
+ struct drm_device *dev,
+ struct amdgpu_display_manager *dm,
+@@ -8983,7 +9033,7 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
+ * during the PSR-SU was disabled.
+ */
+ if (acrtc_state->stream->link->psr_settings.psr_version >= DC_PSR_VERSION_SU_1 &&
+- acrtc_attach->dm_irq_params.allow_psr_entry &&
++ acrtc_attach->dm_irq_params.allow_sr_entry &&
+ #ifdef CONFIG_DRM_AMD_SECURE_DISPLAY
+ !amdgpu_dm_crc_window_is_activated(acrtc_state->base.crtc) &&
+ #endif
+@@ -9158,9 +9208,12 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
+ bundle->stream_update.abm_level = &acrtc_state->abm_level;
+
+ mutex_lock(&dm->dc_lock);
+- if ((acrtc_state->update_type > UPDATE_TYPE_FAST) &&
+- acrtc_state->stream->link->psr_settings.psr_allow_active)
+- amdgpu_dm_psr_disable(acrtc_state->stream);
++ if (acrtc_state->update_type > UPDATE_TYPE_FAST) {
++ if (acrtc_state->stream->link->replay_settings.replay_allow_active)
++ amdgpu_dm_replay_disable(acrtc_state->stream);
++ if (acrtc_state->stream->link->psr_settings.psr_allow_active)
++ amdgpu_dm_psr_disable(acrtc_state->stream);
++ }
+ mutex_unlock(&dm->dc_lock);
+
+ /*
+@@ -9201,57 +9254,7 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
+ dm_update_pflip_irq_state(drm_to_adev(dev),
+ acrtc_attach);
+
+- if (acrtc_state->update_type > UPDATE_TYPE_FAST) {
+- if (acrtc_state->stream->link->replay_settings.config.replay_supported &&
+- !acrtc_state->stream->link->replay_settings.replay_feature_enabled) {
+- struct amdgpu_dm_connector *aconn =
+- (struct amdgpu_dm_connector *)acrtc_state->stream->dm_stream_context;
+- amdgpu_dm_link_setup_replay(acrtc_state->stream->link, aconn);
+- } else if (acrtc_state->stream->link->psr_settings.psr_version != DC_PSR_VERSION_UNSUPPORTED &&
+- !acrtc_state->stream->link->psr_settings.psr_feature_enabled) {
+-
+- struct amdgpu_dm_connector *aconn = (struct amdgpu_dm_connector *)
+- acrtc_state->stream->dm_stream_context;
+-
+- if (!aconn->disallow_edp_enter_psr)
+- amdgpu_dm_link_setup_psr(acrtc_state->stream);
+- }
+- }
+-
+- /* Decrement skip count when PSR is enabled and we're doing fast updates. */
+- if (acrtc_state->update_type == UPDATE_TYPE_FAST &&
+- acrtc_state->stream->link->psr_settings.psr_feature_enabled) {
+- struct amdgpu_dm_connector *aconn =
+- (struct amdgpu_dm_connector *)acrtc_state->stream->dm_stream_context;
+-
+- if (aconn->psr_skip_count > 0)
+- aconn->psr_skip_count--;
+-
+- /* Allow PSR when skip count is 0. */
+- acrtc_attach->dm_irq_params.allow_psr_entry = !aconn->psr_skip_count;
+-
+- /*
+- * If sink supports PSR SU, there is no need to rely on
+- * a vblank event disable request to enable PSR. PSR SU
+- * can be enabled immediately once OS demonstrates an
+- * adequate number of fast atomic commits to notify KMD
+- * of update events. See `vblank_control_worker()`.
+- */
+- if (acrtc_state->stream->link->psr_settings.psr_version >= DC_PSR_VERSION_SU_1 &&
+- acrtc_attach->dm_irq_params.allow_psr_entry &&
+-#ifdef CONFIG_DRM_AMD_SECURE_DISPLAY
+- !amdgpu_dm_crc_window_is_activated(acrtc_state->base.crtc) &&
+-#endif
+- !acrtc_state->stream->link->psr_settings.psr_allow_active &&
+- !aconn->disallow_edp_enter_psr &&
+- (timestamp_ns -
+- acrtc_state->stream->link->psr_settings.psr_dirty_rects_change_timestamp_ns) >
+- 500000000)
+- amdgpu_dm_psr_enable(acrtc_state->stream);
+- } else {
+- acrtc_attach->dm_irq_params.allow_psr_entry = false;
+- }
+-
++ amdgpu_dm_enable_self_refresh(acrtc_attach, acrtc_state, timestamp_ns);
+ mutex_unlock(&dm->dc_lock);
+ }
+
+@@ -12035,7 +12038,7 @@ static int parse_amd_vsdb(struct amdgpu_dm_connector *aconnector,
+ break;
+ }
+
+- while (j < EDID_LENGTH) {
++ while (j < EDID_LENGTH - sizeof(struct amd_vsdb_block)) {
+ struct amd_vsdb_block *amd_vsdb = (struct amd_vsdb_block *)&edid_ext[j];
+ unsigned int ieeeId = (amd_vsdb->ieee_id[2] << 16) | (amd_vsdb->ieee_id[1] << 8) | (amd_vsdb->ieee_id[0]);
+
+diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+index 2d7755e2b6c320..87a8d1d4f9a1b6 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+@@ -727,7 +727,7 @@ struct amdgpu_dm_connector {
+ /* Cached display modes */
+ struct drm_display_mode freesync_vid_base;
+
+- int psr_skip_count;
++ int sr_skip_count;
+ bool disallow_edp_enter_psr;
+
+ /* Record progress status of mst*/
+diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
+index 99014339aaa390..df3d124c4d7a10 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
+@@ -251,9 +251,10 @@ static void amdgpu_dm_crtc_vblank_control_worker(struct work_struct *work)
+ else if (dm->active_vblank_irq_count)
+ dm->active_vblank_irq_count--;
+
+- dc_allow_idle_optimizations(dm->dc, dm->active_vblank_irq_count == 0);
+-
+- DRM_DEBUG_KMS("Allow idle optimizations (MALL): %d\n", dm->active_vblank_irq_count == 0);
++ if (dm->active_vblank_irq_count > 0) {
++ DRM_DEBUG_KMS("Allow idle optimizations (MALL): false\n");
++ dc_allow_idle_optimizations(dm->dc, false);
++ }
+
+ /*
+ * Control PSR based on vblank requirements from OS
+@@ -265,11 +266,15 @@ static void amdgpu_dm_crtc_vblank_control_worker(struct work_struct *work)
+ * where the SU region is the full hactive*vactive region. See
+ * fill_dc_dirty_rects().
+ */
+- if (vblank_work->stream && vblank_work->stream->link) {
++ if (vblank_work->stream && vblank_work->stream->link && vblank_work->acrtc) {
+ amdgpu_dm_crtc_set_panel_sr_feature(
+ vblank_work, vblank_work->enable,
+- vblank_work->acrtc->dm_irq_params.allow_psr_entry ||
+- vblank_work->stream->link->replay_settings.replay_feature_enabled);
++ vblank_work->acrtc->dm_irq_params.allow_sr_entry);
++ }
++
++ if (dm->active_vblank_irq_count == 0) {
++ DRM_DEBUG_KMS("Allow idle optimizations (MALL): true\n");
++ dc_allow_idle_optimizations(dm->dc, true);
+ }
+
+ mutex_unlock(&dm->dc_lock);
+diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq_params.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq_params.h
+index 5c9303241aeb99..6a7ecc1e4602e7 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq_params.h
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq_params.h
+@@ -33,7 +33,7 @@ struct dm_irq_params {
+ struct mod_vrr_params vrr_params;
+ struct dc_stream_state *stream;
+ int active_planes;
+- bool allow_psr_entry;
++ bool allow_sr_entry;
+ struct mod_freesync_config freesync_config;
+
+ #ifdef CONFIG_DEBUG_FS
+diff --git a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c
+index be8fbb04ad98f8..c9a6de110b742f 100644
+--- a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c
++++ b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c
+@@ -3122,14 +3122,12 @@ static enum bp_result bios_parser_get_vram_info(
+ struct dc_vram_info *info)
+ {
+ struct bios_parser *bp = BP_FROM_DCB(dcb);
+- static enum bp_result result = BP_RESULT_BADBIOSTABLE;
++ enum bp_result result = BP_RESULT_BADBIOSTABLE;
+ struct atom_common_table_header *header;
+ struct atom_data_revision revision;
+
+ // vram info moved to umc_info for DCN4x
+- if (dcb->ctx->dce_version >= DCN_VERSION_4_01 &&
+- dcb->ctx->dce_version < DCN_VERSION_MAX &&
+- info && DATA_TABLES(umc_info)) {
++ if (info && DATA_TABLES(umc_info)) {
+ header = GET_IMAGE(struct atom_common_table_header,
+ DATA_TABLES(umc_info));
+
+diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_state.c b/drivers/gpu/drm/amd/display/dc/core/dc_state.c
+index 665157f8d4cbe2..0d801ce84c1acb 100644
+--- a/drivers/gpu/drm/amd/display/dc/core/dc_state.c
++++ b/drivers/gpu/drm/amd/display/dc/core/dc_state.c
+@@ -265,6 +265,9 @@ struct dc_state *dc_state_create_copy(struct dc_state *src_state)
+ dc_state_copy_internal(new_state, src_state);
+
+ #ifdef CONFIG_DRM_AMD_DC_FP
++ new_state->bw_ctx.dml2 = NULL;
++ new_state->bw_ctx.dml2_dc_power_source = NULL;
++
+ if (src_state->bw_ctx.dml2 &&
+ !dml2_create_copy(&new_state->bw_ctx.dml2, src_state->bw_ctx.dml2)) {
+ dc_state_release(new_state);
+diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_pmo/dml2_pmo_dcn4_fams2.c b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_pmo/dml2_pmo_dcn4_fams2.c
+index a8bebc60f05939..2c2c7322cb1615 100644
+--- a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_pmo/dml2_pmo_dcn4_fams2.c
++++ b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_pmo/dml2_pmo_dcn4_fams2.c
+@@ -30,6 +30,7 @@
+ #include "dml2_pmo_dcn4_fams2.h"
+
+ static const double MIN_VACTIVE_MARGIN_PCT = 0.25; // We need more than non-zero margin because DET buffer granularity can alter vactive latency hiding
++static const double MIN_BLANK_STUTTER_FACTOR = 3.0;
+
+ static const enum dml2_pmo_pstate_strategy base_strategy_list_1_display[][PMO_DCN4_MAX_DISPLAYS] = {
+ // VActive Preferred
+@@ -2004,6 +2005,7 @@ bool pmo_dcn4_fams2_init_for_stutter(struct dml2_pmo_init_for_stutter_in_out *in
+ struct dml2_pmo_instance *pmo = in_out->instance;
+ bool stutter_period_meets_z8_eco = true;
+ bool z8_stutter_optimization_too_expensive = false;
++ bool stutter_optimization_too_expensive = false;
+ double line_time_us, vblank_nom_time_us;
+
+ unsigned int i;
+@@ -2025,10 +2027,15 @@ bool pmo_dcn4_fams2_init_for_stutter(struct dml2_pmo_init_for_stutter_in_out *in
+ line_time_us = (double)in_out->base_display_config->display_config.stream_descriptors[i].timing.h_total / (in_out->base_display_config->display_config.stream_descriptors[i].timing.pixel_clock_khz * 1000) * 1000000;
+ vblank_nom_time_us = line_time_us * in_out->base_display_config->display_config.stream_descriptors[i].timing.vblank_nom;
+
+- if (vblank_nom_time_us < pmo->soc_bb->power_management_parameters.z8_stutter_exit_latency_us) {
++ if (vblank_nom_time_us < pmo->soc_bb->power_management_parameters.z8_stutter_exit_latency_us * MIN_BLANK_STUTTER_FACTOR) {
+ z8_stutter_optimization_too_expensive = true;
+ break;
+ }
++
++ if (vblank_nom_time_us < pmo->soc_bb->power_management_parameters.stutter_enter_plus_exit_latency_us * MIN_BLANK_STUTTER_FACTOR) {
++ stutter_optimization_too_expensive = true;
++ break;
++ }
+ }
+
+ pmo->scratch.pmo_dcn4.num_stutter_candidates = 0;
+@@ -2044,7 +2051,7 @@ bool pmo_dcn4_fams2_init_for_stutter(struct dml2_pmo_init_for_stutter_in_out *in
+ pmo->scratch.pmo_dcn4.z8_vblank_optimizable = false;
+ }
+
+- if (pmo->soc_bb->power_management_parameters.stutter_enter_plus_exit_latency_us > 0) {
++ if (!stutter_optimization_too_expensive && pmo->soc_bb->power_management_parameters.stutter_enter_plus_exit_latency_us > 0) {
+ pmo->scratch.pmo_dcn4.optimal_vblank_reserved_time_for_stutter_us[pmo->scratch.pmo_dcn4.num_stutter_candidates] = (unsigned int)pmo->soc_bb->power_management_parameters.stutter_enter_plus_exit_latency_us;
+ pmo->scratch.pmo_dcn4.num_stutter_candidates++;
+ }
+diff --git a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
+index ee1bcfaae3e3db..80e60ea2d11e3c 100644
+--- a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
++++ b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
+@@ -1259,33 +1259,26 @@ static int smu_sw_init(void *handle)
+ smu->watermarks_bitmap = 0;
+ smu->power_profile_mode = PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT;
+ smu->default_power_profile_mode = PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT;
+- smu->user_dpm_profile.user_workload_mask = 0;
+
+ atomic_set(&smu->smu_power.power_gate.vcn_gated, 1);
+ atomic_set(&smu->smu_power.power_gate.jpeg_gated, 1);
+ atomic_set(&smu->smu_power.power_gate.vpe_gated, 1);
+ atomic_set(&smu->smu_power.power_gate.umsch_mm_gated, 1);
+
+- smu->workload_priority[PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT] = 0;
+- smu->workload_priority[PP_SMC_POWER_PROFILE_FULLSCREEN3D] = 1;
+- smu->workload_priority[PP_SMC_POWER_PROFILE_POWERSAVING] = 2;
+- smu->workload_priority[PP_SMC_POWER_PROFILE_VIDEO] = 3;
+- smu->workload_priority[PP_SMC_POWER_PROFILE_VR] = 4;
+- smu->workload_priority[PP_SMC_POWER_PROFILE_COMPUTE] = 5;
+- smu->workload_priority[PP_SMC_POWER_PROFILE_CUSTOM] = 6;
++ smu->workload_prority[PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT] = 0;
++ smu->workload_prority[PP_SMC_POWER_PROFILE_FULLSCREEN3D] = 1;
++ smu->workload_prority[PP_SMC_POWER_PROFILE_POWERSAVING] = 2;
++ smu->workload_prority[PP_SMC_POWER_PROFILE_VIDEO] = 3;
++ smu->workload_prority[PP_SMC_POWER_PROFILE_VR] = 4;
++ smu->workload_prority[PP_SMC_POWER_PROFILE_COMPUTE] = 5;
++ smu->workload_prority[PP_SMC_POWER_PROFILE_CUSTOM] = 6;
+
+ if (smu->is_apu ||
+- !smu_is_workload_profile_available(smu, PP_SMC_POWER_PROFILE_FULLSCREEN3D)) {
+- smu->driver_workload_mask =
+- 1 << smu->workload_priority[PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT];
+- } else {
+- smu->driver_workload_mask =
+- 1 << smu->workload_priority[PP_SMC_POWER_PROFILE_FULLSCREEN3D];
+- smu->default_power_profile_mode = PP_SMC_POWER_PROFILE_FULLSCREEN3D;
+- }
++ !smu_is_workload_profile_available(smu, PP_SMC_POWER_PROFILE_FULLSCREEN3D))
++ smu->workload_mask = 1 << smu->workload_prority[PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT];
++ else
++ smu->workload_mask = 1 << smu->workload_prority[PP_SMC_POWER_PROFILE_FULLSCREEN3D];
+
+- smu->workload_mask = smu->driver_workload_mask |
+- smu->user_dpm_profile.user_workload_mask;
+ smu->workload_setting[0] = PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT;
+ smu->workload_setting[1] = PP_SMC_POWER_PROFILE_FULLSCREEN3D;
+ smu->workload_setting[2] = PP_SMC_POWER_PROFILE_POWERSAVING;
+@@ -2355,20 +2348,17 @@ static int smu_switch_power_profile(void *handle,
+ return -EINVAL;
+
+ if (!en) {
+- smu->driver_workload_mask &= ~(1 << smu->workload_priority[type]);
++ smu->workload_mask &= ~(1 << smu->workload_prority[type]);
+ index = fls(smu->workload_mask);
+ index = index > 0 && index <= WORKLOAD_POLICY_MAX ? index - 1 : 0;
+ workload[0] = smu->workload_setting[index];
+ } else {
+- smu->driver_workload_mask |= (1 << smu->workload_priority[type]);
++ smu->workload_mask |= (1 << smu->workload_prority[type]);
+ index = fls(smu->workload_mask);
+ index = index <= WORKLOAD_POLICY_MAX ? index - 1 : 0;
+ workload[0] = smu->workload_setting[index];
+ }
+
+- smu->workload_mask = smu->driver_workload_mask |
+- smu->user_dpm_profile.user_workload_mask;
+-
+ if (smu_dpm_ctx->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL &&
+ smu_dpm_ctx->dpm_level != AMD_DPM_FORCED_LEVEL_PERF_DETERMINISM)
+ smu_bump_power_profile_mode(smu, workload, 0);
+@@ -3059,23 +3049,12 @@ static int smu_set_power_profile_mode(void *handle,
+ uint32_t param_size)
+ {
+ struct smu_context *smu = handle;
+- int ret;
+
+ if (!smu->pm_enabled || !smu->adev->pm.dpm_enabled ||
+ !smu->ppt_funcs->set_power_profile_mode)
+ return -EOPNOTSUPP;
+
+- if (smu->user_dpm_profile.user_workload_mask &
+- (1 << smu->workload_priority[param[param_size]]))
+- return 0;
+-
+- smu->user_dpm_profile.user_workload_mask =
+- (1 << smu->workload_priority[param[param_size]]);
+- smu->workload_mask = smu->user_dpm_profile.user_workload_mask |
+- smu->driver_workload_mask;
+- ret = smu_bump_power_profile_mode(smu, param, param_size);
+-
+- return ret;
++ return smu_bump_power_profile_mode(smu, param, param_size);
+ }
+
+ static int smu_get_fan_control_mode(void *handle, u32 *fan_mode)
+diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h b/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h
+index d60d9a12a47ef7..b44a185d07e84c 100644
+--- a/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h
++++ b/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h
+@@ -240,7 +240,6 @@ struct smu_user_dpm_profile {
+ /* user clock state information */
+ uint32_t clk_mask[SMU_CLK_COUNT];
+ uint32_t clk_dependency;
+- uint32_t user_workload_mask;
+ };
+
+ #define SMU_TABLE_INIT(tables, table_id, s, a, d) \
+@@ -558,8 +557,7 @@ struct smu_context {
+ bool disable_uclk_switch;
+
+ uint32_t workload_mask;
+- uint32_t driver_workload_mask;
+- uint32_t workload_priority[WORKLOAD_POLICY_MAX];
++ uint32_t workload_prority[WORKLOAD_POLICY_MAX];
+ uint32_t workload_setting[WORKLOAD_POLICY_MAX];
+ uint32_t power_profile_mode;
+ uint32_t default_power_profile_mode;
+diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c
+index 31fe512028f460..c0f6b59369b7c4 100644
+--- a/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c
++++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c
+@@ -1455,6 +1455,7 @@ static int arcturus_set_power_profile_mode(struct smu_context *smu,
+ return -EINVAL;
+ }
+
++
+ if ((profile_mode == PP_SMC_POWER_PROFILE_CUSTOM) &&
+ (smu->smc_fw_version >= 0x360d00)) {
+ if (size != 10)
+@@ -1522,14 +1523,14 @@ static int arcturus_set_power_profile_mode(struct smu_context *smu,
+
+ ret = smu_cmn_send_smc_msg_with_param(smu,
+ SMU_MSG_SetWorkloadMask,
+- smu->workload_mask,
++ 1 << workload_type,
+ NULL);
+ if (ret) {
+ dev_err(smu->adev->dev, "Fail to set workload type %d\n", workload_type);
+ return ret;
+ }
+
+- smu_cmn_assign_power_profile(smu);
++ smu->power_profile_mode = profile_mode;
+
+ return 0;
+ }
+diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c
+index bb4ae529ae20ef..076620fa3ef5a8 100644
+--- a/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c
++++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c
+@@ -2081,13 +2081,10 @@ static int navi10_set_power_profile_mode(struct smu_context *smu, long *input, u
+ smu->power_profile_mode);
+ if (workload_type < 0)
+ return -EINVAL;
+-
+ ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetWorkloadMask,
+- smu->workload_mask, NULL);
++ 1 << workload_type, NULL);
+ if (ret)
+ dev_err(smu->adev->dev, "[%s] Failed to set work load mask!", __func__);
+- else
+- smu_cmn_assign_power_profile(smu);
+
+ return ret;
+ }
+diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c
+index ca94c52663c071..0d3e1a121b670a 100644
+--- a/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c
++++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c
+@@ -1786,13 +1786,10 @@ static int sienna_cichlid_set_power_profile_mode(struct smu_context *smu, long *
+ smu->power_profile_mode);
+ if (workload_type < 0)
+ return -EINVAL;
+-
+ ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetWorkloadMask,
+- smu->workload_mask, NULL);
++ 1 << workload_type, NULL);
+ if (ret)
+ dev_err(smu->adev->dev, "[%s] Failed to set work load mask!", __func__);
+- else
+- smu_cmn_assign_power_profile(smu);
+
+ return ret;
+ }
+diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c
+index 952ee22cbc90e0..1fe020f1f4dbe2 100644
+--- a/drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c
++++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c
+@@ -1079,7 +1079,7 @@ static int vangogh_set_power_profile_mode(struct smu_context *smu, long *input,
+ }
+
+ ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_ActiveProcessNotify,
+- smu->workload_mask,
++ 1 << workload_type,
+ NULL);
+ if (ret) {
+ dev_err_once(smu->adev->dev, "Fail to set workload type %d\n",
+@@ -1087,7 +1087,7 @@ static int vangogh_set_power_profile_mode(struct smu_context *smu, long *input,
+ return ret;
+ }
+
+- smu_cmn_assign_power_profile(smu);
++ smu->power_profile_mode = profile_mode;
+
+ return 0;
+ }
+diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu12/renoir_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu12/renoir_ppt.c
+index 62316a6707ef2f..cc0504b063fa3a 100644
+--- a/drivers/gpu/drm/amd/pm/swsmu/smu12/renoir_ppt.c
++++ b/drivers/gpu/drm/amd/pm/swsmu/smu12/renoir_ppt.c
+@@ -890,14 +890,14 @@ static int renoir_set_power_profile_mode(struct smu_context *smu, long *input, u
+ }
+
+ ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_ActiveProcessNotify,
+- smu->workload_mask,
++ 1 << workload_type,
+ NULL);
+ if (ret) {
+ dev_err_once(smu->adev->dev, "Fail to set workload type %d\n", workload_type);
+ return ret;
+ }
+
+- smu_cmn_assign_power_profile(smu);
++ smu->power_profile_mode = profile_mode;
+
+ return 0;
+ }
+diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
+index 5dd7ceca64feed..d53e162dcd8de2 100644
+--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
++++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
+@@ -2485,7 +2485,7 @@ static int smu_v13_0_0_set_power_profile_mode(struct smu_context *smu,
+ DpmActivityMonitorCoeffInt_t *activity_monitor =
+ &(activity_monitor_external.DpmActivityMonitorCoeffInt);
+ int workload_type, ret = 0;
+- u32 workload_mask;
++ u32 workload_mask, selected_workload_mask;
+
+ smu->power_profile_mode = input[size];
+
+@@ -2552,7 +2552,7 @@ static int smu_v13_0_0_set_power_profile_mode(struct smu_context *smu,
+ if (workload_type < 0)
+ return -EINVAL;
+
+- workload_mask = 1 << workload_type;
++ selected_workload_mask = workload_mask = 1 << workload_type;
+
+ /* Add optimizations for SMU13.0.0/10. Reuse the power saving profile */
+ if ((amdgpu_ip_version(smu->adev, MP1_HWIP, 0) == IP_VERSION(13, 0, 0) &&
+@@ -2567,22 +2567,12 @@ static int smu_v13_0_0_set_power_profile_mode(struct smu_context *smu,
+ workload_mask |= 1 << workload_type;
+ }
+
+- smu->workload_mask |= workload_mask;
+ ret = smu_cmn_send_smc_msg_with_param(smu,
+ SMU_MSG_SetWorkloadMask,
+- smu->workload_mask,
++ workload_mask,
+ NULL);
+- if (!ret) {
+- smu_cmn_assign_power_profile(smu);
+- if (smu->power_profile_mode == PP_SMC_POWER_PROFILE_POWERSAVING) {
+- workload_type = smu_cmn_to_asic_specific_index(smu,
+- CMN2ASIC_MAPPING_WORKLOAD,
+- PP_SMC_POWER_PROFILE_FULLSCREEN3D);
+- smu->power_profile_mode = smu->workload_mask & (1 << workload_type)
+- ? PP_SMC_POWER_PROFILE_FULLSCREEN3D
+- : PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT;
+- }
+- }
++ if (!ret)
++ smu->workload_mask = selected_workload_mask;
+
+ return ret;
+ }
+diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c
+index 9d0b19419de0ff..b891a5e0a3969a 100644
+--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c
++++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c
+@@ -2499,14 +2499,13 @@ static int smu_v13_0_7_set_power_profile_mode(struct smu_context *smu, long *inp
+ smu->power_profile_mode);
+ if (workload_type < 0)
+ return -EINVAL;
+-
+ ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetWorkloadMask,
+- smu->workload_mask, NULL);
++ 1 << workload_type, NULL);
+
+ if (ret)
+ dev_err(smu->adev->dev, "[%s] Failed to set work load mask!", __func__);
+ else
+- smu_cmn_assign_power_profile(smu);
++ smu->workload_mask = (1 << workload_type);
+
+ return ret;
+ }
+diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_0_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_0_ppt.c
+index 8798ebfcea8328..84f9b007b59f2e 100644
+--- a/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_0_ppt.c
++++ b/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_0_ppt.c
+@@ -1132,7 +1132,7 @@ static int smu_v14_0_common_get_dpm_level_count(struct smu_context *smu,
+ static int smu_v14_0_0_print_clk_levels(struct smu_context *smu,
+ enum smu_clk_type clk_type, char *buf)
+ {
+- int i, size = 0, ret = 0;
++ int i, idx, ret = 0, size = 0;
+ uint32_t cur_value = 0, value = 0, count = 0;
+ uint32_t min, max;
+
+@@ -1168,7 +1168,8 @@ static int smu_v14_0_0_print_clk_levels(struct smu_context *smu,
+ break;
+
+ for (i = 0; i < count; i++) {
+- ret = smu_v14_0_common_get_dpm_freq_by_index(smu, clk_type, i, &value);
++ idx = (clk_type == SMU_MCLK) ? (count - i - 1) : i;
++ ret = smu_v14_0_common_get_dpm_freq_by_index(smu, clk_type, idx, &value);
+ if (ret)
+ break;
+
+diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c
+index d9f0e7f81ed788..eaf80c5b3e4d06 100644
+--- a/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c
++++ b/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c
+@@ -1508,11 +1508,12 @@ static int smu_v14_0_2_set_power_profile_mode(struct smu_context *smu,
+ if (workload_type < 0)
+ return -EINVAL;
+
+- ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetWorkloadMask,
+- smu->workload_mask, NULL);
+-
++ ret = smu_cmn_send_smc_msg_with_param(smu,
++ SMU_MSG_SetWorkloadMask,
++ 1 << workload_type,
++ NULL);
+ if (!ret)
+- smu_cmn_assign_power_profile(smu);
++ smu->workload_mask = 1 << workload_type;
+
+ return ret;
+ }
+diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c b/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c
+index bdfc5e617333df..91ad434bcdaeb4 100644
+--- a/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c
++++ b/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c
+@@ -1138,14 +1138,6 @@ int smu_cmn_set_mp1_state(struct smu_context *smu,
+ return ret;
+ }
+
+-void smu_cmn_assign_power_profile(struct smu_context *smu)
+-{
+- uint32_t index;
+- index = fls(smu->workload_mask);
+- index = index > 0 && index <= WORKLOAD_POLICY_MAX ? index - 1 : 0;
+- smu->power_profile_mode = smu->workload_setting[index];
+-}
+-
+ bool smu_cmn_is_audio_func_enabled(struct amdgpu_device *adev)
+ {
+ struct pci_dev *p = NULL;
+diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.h b/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.h
+index 8a801e389659d1..1de685defe85b1 100644
+--- a/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.h
++++ b/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.h
+@@ -130,8 +130,6 @@ void smu_cmn_init_soft_gpu_metrics(void *table, uint8_t frev, uint8_t crev);
+ int smu_cmn_set_mp1_state(struct smu_context *smu,
+ enum pp_mp1_state mp1_state);
+
+-void smu_cmn_assign_power_profile(struct smu_context *smu);
+-
+ /*
+ * Helper function to make sysfs_emit_at() happy. Align buf to
+ * the current page boundary and record the offset.
+diff --git a/drivers/gpu/drm/bridge/tc358768.c b/drivers/gpu/drm/bridge/tc358768.c
+index 0e8813278a2fa5..bb1750a3dab0dc 100644
+--- a/drivers/gpu/drm/bridge/tc358768.c
++++ b/drivers/gpu/drm/bridge/tc358768.c
+@@ -125,6 +125,9 @@
+ #define TC358768_DSI_CONFW_MODE_CLR (6 << 29)
+ #define TC358768_DSI_CONFW_ADDR_DSI_CONTROL (0x3 << 24)
+
++/* TC358768_DSICMD_TX (0x0600) register */
++#define TC358768_DSI_CMDTX_DC_START BIT(0)
++
+ static const char * const tc358768_supplies[] = {
+ "vddc", "vddmipi", "vddio"
+ };
+@@ -229,6 +232,21 @@ static void tc358768_update_bits(struct tc358768_priv *priv, u32 reg, u32 mask,
+ tc358768_write(priv, reg, tmp);
+ }
+
++static void tc358768_dsicmd_tx(struct tc358768_priv *priv)
++{
++ u32 val;
++
++ /* start transfer */
++ tc358768_write(priv, TC358768_DSICMD_TX, TC358768_DSI_CMDTX_DC_START);
++ if (priv->error)
++ return;
++
++ /* wait transfer completion */
++ priv->error = regmap_read_poll_timeout(priv->regmap, TC358768_DSICMD_TX, val,
++ (val & TC358768_DSI_CMDTX_DC_START) == 0,
++ 100, 100000);
++}
++
+ static int tc358768_sw_reset(struct tc358768_priv *priv)
+ {
+ /* Assert Reset */
+@@ -516,8 +534,7 @@ static ssize_t tc358768_dsi_host_transfer(struct mipi_dsi_host *host,
+ }
+ }
+
+- /* start transfer */
+- tc358768_write(priv, TC358768_DSICMD_TX, 1);
++ tc358768_dsicmd_tx(priv);
+
+ ret = tc358768_clear_error(priv);
+ if (ret)
+diff --git a/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c b/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c
+index 551b0d7974ff13..5dc0ccd0763639 100644
+--- a/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c
++++ b/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c
+@@ -80,6 +80,7 @@ int intel_gsc_fw_get_binary_info(struct intel_uc_fw *gsc_fw, const void *data, s
+ const struct intel_gsc_cpd_header_v2 *cpd_header = NULL;
+ const struct intel_gsc_cpd_entry *cpd_entry = NULL;
+ const struct intel_gsc_manifest_header *manifest;
++ struct intel_uc_fw_ver min_ver = { 0 };
+ size_t min_size = sizeof(*layout);
+ int i;
+
+@@ -212,33 +213,46 @@ int intel_gsc_fw_get_binary_info(struct intel_uc_fw *gsc_fw, const void *data, s
+ }
+ }
+
+- if (IS_ARROWLAKE(gt->i915)) {
++ /*
++ * ARL SKUs require newer firmwares, but the blob is actually common
++ * across all MTL and ARL SKUs, so we need to do an explicit version check
++ * here rather than using a separate table entry. If a too old version
++ * is found, then just don't use GSC rather than aborting the driver load.
++ * Note that the major number in the GSC FW version is used to indicate
++ * the platform, so we expect it to always be 102 for MTL/ARL binaries.
++ */
++ if (IS_ARROWLAKE_S(gt->i915))
++ min_ver = (struct intel_uc_fw_ver){ 102, 0, 10, 1878 };
++ else if (IS_ARROWLAKE_H(gt->i915) || IS_ARROWLAKE_U(gt->i915))
++ min_ver = (struct intel_uc_fw_ver){ 102, 1, 15, 1926 };
++
++ if (IS_METEORLAKE(gt->i915) && gsc->release.major != 102) {
++ gt_info(gt, "Invalid GSC firmware for MTL/ARL, got %d.%d.%d.%d but need 102.x.x.x",
++ gsc->release.major, gsc->release.minor,
++ gsc->release.patch, gsc->release.build);
++ return -EINVAL;
++ }
++
++ if (min_ver.major) {
+ bool too_old = false;
+
+- /*
+- * ARL requires a newer firmware than MTL did (102.0.10.1878) but the
+- * firmware is actually common. So, need to do an explicit version check
+- * here rather than using a separate table entry. And if the older
+- * MTL-only version is found, then just don't use GSC rather than aborting
+- * the driver load.
+- */
+- if (gsc->release.major < 102) {
++ if (gsc->release.minor < min_ver.minor) {
+ too_old = true;
+- } else if (gsc->release.major == 102) {
+- if (gsc->release.minor == 0) {
+- if (gsc->release.patch < 10) {
++ } else if (gsc->release.minor == min_ver.minor) {
++ if (gsc->release.patch < min_ver.patch) {
++ too_old = true;
++ } else if (gsc->release.patch == min_ver.patch) {
++ if (gsc->release.build < min_ver.build)
+ too_old = true;
+- } else if (gsc->release.patch == 10) {
+- if (gsc->release.build < 1878)
+- too_old = true;
+- }
+ }
+ }
+
+ if (too_old) {
+- gt_info(gt, "GSC firmware too old for ARL, got %d.%d.%d.%d but need at least 102.0.10.1878",
++ gt_info(gt, "GSC firmware too old for ARL, got %d.%d.%d.%d but need at least %d.%d.%d.%d",
+ gsc->release.major, gsc->release.minor,
+- gsc->release.patch, gsc->release.build);
++ gsc->release.patch, gsc->release.build,
++ min_ver.major, min_ver.minor,
++ min_ver.patch, min_ver.build);
+ return -EINVAL;
+ }
+ }
+diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
+index 110340e02a0213..0c0c666f11ea20 100644
+--- a/drivers/gpu/drm/i915/i915_drv.h
++++ b/drivers/gpu/drm/i915/i915_drv.h
+@@ -546,8 +546,12 @@ IS_SUBPLATFORM(const struct drm_i915_private *i915,
+ #define IS_LUNARLAKE(i915) (0 && i915)
+ #define IS_BATTLEMAGE(i915) (0 && i915)
+
+-#define IS_ARROWLAKE(i915) \
+- IS_SUBPLATFORM(i915, INTEL_METEORLAKE, INTEL_SUBPLATFORM_ARL)
++#define IS_ARROWLAKE_H(i915) \
++ IS_SUBPLATFORM(i915, INTEL_METEORLAKE, INTEL_SUBPLATFORM_ARL_H)
++#define IS_ARROWLAKE_U(i915) \
++ IS_SUBPLATFORM(i915, INTEL_METEORLAKE, INTEL_SUBPLATFORM_ARL_U)
++#define IS_ARROWLAKE_S(i915) \
++ IS_SUBPLATFORM(i915, INTEL_METEORLAKE, INTEL_SUBPLATFORM_ARL_S)
+ #define IS_DG2_G10(i915) \
+ IS_SUBPLATFORM(i915, INTEL_DG2, INTEL_SUBPLATFORM_G10)
+ #define IS_DG2_G11(i915) \
+diff --git a/drivers/gpu/drm/i915/intel_device_info.c b/drivers/gpu/drm/i915/intel_device_info.c
+index 01a6502530501a..bd0cb707e9d494 100644
+--- a/drivers/gpu/drm/i915/intel_device_info.c
++++ b/drivers/gpu/drm/i915/intel_device_info.c
+@@ -202,8 +202,16 @@ static const u16 subplatform_g12_ids[] = {
+ INTEL_DG2_G12_IDS(ID),
+ };
+
+-static const u16 subplatform_arl_ids[] = {
+- INTEL_ARL_IDS(ID),
++static const u16 subplatform_arl_h_ids[] = {
++ INTEL_ARL_H_IDS(ID),
++};
++
++static const u16 subplatform_arl_u_ids[] = {
++ INTEL_ARL_U_IDS(ID),
++};
++
++static const u16 subplatform_arl_s_ids[] = {
++ INTEL_ARL_S_IDS(ID),
+ };
+
+ static bool find_devid(u16 id, const u16 *p, unsigned int num)
+@@ -263,9 +271,15 @@ static void intel_device_info_subplatform_init(struct drm_i915_private *i915)
+ } else if (find_devid(devid, subplatform_g12_ids,
+ ARRAY_SIZE(subplatform_g12_ids))) {
+ mask = BIT(INTEL_SUBPLATFORM_G12);
+- } else if (find_devid(devid, subplatform_arl_ids,
+- ARRAY_SIZE(subplatform_arl_ids))) {
+- mask = BIT(INTEL_SUBPLATFORM_ARL);
++ } else if (find_devid(devid, subplatform_arl_h_ids,
++ ARRAY_SIZE(subplatform_arl_h_ids))) {
++ mask = BIT(INTEL_SUBPLATFORM_ARL_H);
++ } else if (find_devid(devid, subplatform_arl_u_ids,
++ ARRAY_SIZE(subplatform_arl_u_ids))) {
++ mask = BIT(INTEL_SUBPLATFORM_ARL_U);
++ } else if (find_devid(devid, subplatform_arl_s_ids,
++ ARRAY_SIZE(subplatform_arl_s_ids))) {
++ mask = BIT(INTEL_SUBPLATFORM_ARL_S);
+ }
+
+ GEM_BUG_ON(mask & ~INTEL_SUBPLATFORM_MASK);
+diff --git a/drivers/gpu/drm/i915/intel_device_info.h b/drivers/gpu/drm/i915/intel_device_info.h
+index 643ff1bf74eeb0..a9fcaf33df9e26 100644
+--- a/drivers/gpu/drm/i915/intel_device_info.h
++++ b/drivers/gpu/drm/i915/intel_device_info.h
+@@ -128,7 +128,9 @@ enum intel_platform {
+ #define INTEL_SUBPLATFORM_RPLU 2
+
+ /* MTL */
+-#define INTEL_SUBPLATFORM_ARL 0
++#define INTEL_SUBPLATFORM_ARL_H 0
++#define INTEL_SUBPLATFORM_ARL_U 1
++#define INTEL_SUBPLATFORM_ARL_S 2
+
+ enum intel_ppgtt_type {
+ INTEL_PPGTT_NONE = I915_GEM_PPGTT_NONE,
+diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/r535.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/r535.c
+index 027867c2a8c5b6..99110ab2f44dcd 100644
+--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/r535.c
++++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/r535.c
+@@ -992,7 +992,7 @@ r535_dp_train_target(struct nvkm_outp *outp, u8 target, bool mst, u8 link_nr, u8
+ ctrl->data = data;
+
+ ret = nvkm_gsp_rm_ctrl_push(&disp->rm.objcom, &ctrl, sizeof(*ctrl));
+- if (ret == -EAGAIN && ctrl->retryTimeMs) {
++ if ((ret == -EAGAIN || ret == -EBUSY) && ctrl->retryTimeMs) {
+ /*
+ * Device (likely an eDP panel) isn't ready yet, wait for the time specified
+ * by GSP before retrying again
+@@ -1060,33 +1060,44 @@ r535_dp_aux_xfer(struct nvkm_outp *outp, u8 type, u32 addr, u8 *data, u8 *psize)
+ NV0073_CTRL_DP_AUXCH_CTRL_PARAMS *ctrl;
+ u8 size = *psize;
+ int ret;
++ int retries;
+
+- ctrl = nvkm_gsp_rm_ctrl_get(&disp->rm.objcom, NV0073_CTRL_CMD_DP_AUXCH_CTRL, sizeof(*ctrl));
+- if (IS_ERR(ctrl))
+- return PTR_ERR(ctrl);
++ for (retries = 0; retries < 3; ++retries) {
++ ctrl = nvkm_gsp_rm_ctrl_get(&disp->rm.objcom, NV0073_CTRL_CMD_DP_AUXCH_CTRL, sizeof(*ctrl));
++ if (IS_ERR(ctrl))
++ return PTR_ERR(ctrl);
+
+- ctrl->subDeviceInstance = 0;
+- ctrl->displayId = BIT(outp->index);
+- ctrl->bAddrOnly = !size;
+- ctrl->cmd = type;
+- if (ctrl->bAddrOnly) {
+- ctrl->cmd = NVDEF_SET(ctrl->cmd, NV0073_CTRL, DP_AUXCH_CMD, REQ_TYPE, WRITE);
+- ctrl->cmd = NVDEF_SET(ctrl->cmd, NV0073_CTRL, DP_AUXCH_CMD, I2C_MOT, FALSE);
+- }
+- ctrl->addr = addr;
+- ctrl->size = !ctrl->bAddrOnly ? (size - 1) : 0;
+- memcpy(ctrl->data, data, size);
++ ctrl->subDeviceInstance = 0;
++ ctrl->displayId = BIT(outp->index);
++ ctrl->bAddrOnly = !size;
++ ctrl->cmd = type;
++ if (ctrl->bAddrOnly) {
++ ctrl->cmd = NVDEF_SET(ctrl->cmd, NV0073_CTRL, DP_AUXCH_CMD, REQ_TYPE, WRITE);
++ ctrl->cmd = NVDEF_SET(ctrl->cmd, NV0073_CTRL, DP_AUXCH_CMD, I2C_MOT, FALSE);
++ }
++ ctrl->addr = addr;
++ ctrl->size = !ctrl->bAddrOnly ? (size - 1) : 0;
++ memcpy(ctrl->data, data, size);
+
+- ret = nvkm_gsp_rm_ctrl_push(&disp->rm.objcom, &ctrl, sizeof(*ctrl));
+- if (ret) {
+- nvkm_gsp_rm_ctrl_done(&disp->rm.objcom, ctrl);
+- return ret;
++ ret = nvkm_gsp_rm_ctrl_push(&disp->rm.objcom, &ctrl, sizeof(*ctrl));
++ if ((ret == -EAGAIN || ret == -EBUSY) && ctrl->retryTimeMs) {
++ /*
++ * Device (likely an eDP panel) isn't ready yet, wait for the time specified
++ * by GSP before retrying again
++ */
++ nvkm_debug(&disp->engine.subdev,
++ "Waiting %dms for GSP LT panel delay before retrying in AUX\n",
++ ctrl->retryTimeMs);
++ msleep(ctrl->retryTimeMs);
++ nvkm_gsp_rm_ctrl_done(&disp->rm.objcom, ctrl);
++ } else {
++ memcpy(data, ctrl->data, size);
++ *psize = ctrl->size;
++ ret = ctrl->replyType;
++ nvkm_gsp_rm_ctrl_done(&disp->rm.objcom, ctrl);
++ break;
++ }
+ }
+-
+- memcpy(data, ctrl->data, size);
+- *psize = ctrl->size;
+- ret = ctrl->replyType;
+- nvkm_gsp_rm_ctrl_done(&disp->rm.objcom, ctrl);
+ return ret;
+ }
+
+diff --git a/drivers/gpu/drm/nouveau/nvkm/falcon/fw.c b/drivers/gpu/drm/nouveau/nvkm/falcon/fw.c
+index a1c8545f1249a1..cac6d64ab67d1d 100644
+--- a/drivers/gpu/drm/nouveau/nvkm/falcon/fw.c
++++ b/drivers/gpu/drm/nouveau/nvkm/falcon/fw.c
+@@ -89,11 +89,6 @@ nvkm_falcon_fw_boot(struct nvkm_falcon_fw *fw, struct nvkm_subdev *user,
+ nvkm_falcon_fw_dtor_sigs(fw);
+ }
+
+- /* after last write to the img, sync dma mappings */
+- dma_sync_single_for_device(fw->fw.device->dev,
+- fw->fw.phys,
+- sg_dma_len(&fw->fw.mem.sgl),
+- DMA_TO_DEVICE);
+
+ FLCNFW_DBG(fw, "resetting");
+ fw->func->reset(fw);
+@@ -105,6 +100,12 @@ nvkm_falcon_fw_boot(struct nvkm_falcon_fw *fw, struct nvkm_subdev *user,
+ goto done;
+ }
+
++ /* after last write to the img, sync dma mappings */
++ dma_sync_single_for_device(fw->fw.device->dev,
++ fw->fw.phys,
++ sg_dma_len(&fw->fw.mem.sgl),
++ DMA_TO_DEVICE);
++
+ ret = fw->func->load(fw);
+ if (ret)
+ goto done;
+diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/r535.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/r535.c
+index cf58f9da91396d..d586aea3089841 100644
+--- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/r535.c
++++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/r535.c
+@@ -78,7 +78,7 @@ r535_rpc_status_to_errno(uint32_t rpc_status)
+ switch (rpc_status) {
+ case 0x55: /* NV_ERR_NOT_READY */
+ case 0x66: /* NV_ERR_TIMEOUT_RETRY */
+- return -EAGAIN;
++ return -EBUSY;
+ case 0x51: /* NV_ERR_NO_MEMORY */
+ return -ENOMEM;
+ default:
+@@ -601,7 +601,7 @@ r535_gsp_rpc_rm_alloc_push(struct nvkm_gsp_object *object, void *argv, u32 repc)
+
+ if (rpc->status) {
+ ret = ERR_PTR(r535_rpc_status_to_errno(rpc->status));
+- if (PTR_ERR(ret) != -EAGAIN)
++ if (PTR_ERR(ret) != -EAGAIN && PTR_ERR(ret) != -EBUSY)
+ nvkm_error(&gsp->subdev, "RM_ALLOC: 0x%x\n", rpc->status);
+ } else {
+ ret = repc ? rpc->params : NULL;
+@@ -660,7 +660,7 @@ r535_gsp_rpc_rm_ctrl_push(struct nvkm_gsp_object *object, void **argv, u32 repc)
+
+ if (rpc->status) {
+ ret = r535_rpc_status_to_errno(rpc->status);
+- if (ret != -EAGAIN)
++ if (ret != -EAGAIN && ret != -EBUSY)
+ nvkm_error(&gsp->subdev, "cli:0x%08x obj:0x%08x ctrl cmd:0x%08x failed: 0x%08x\n",
+ object->client->object.handle, object->handle, rpc->cmd, rpc->status);
+ }
+diff --git a/drivers/gpu/drm/panthor/panthor_mmu.c b/drivers/gpu/drm/panthor/panthor_mmu.c
+index d18f32640a79fb..64378e8f124bde 100644
+--- a/drivers/gpu/drm/panthor/panthor_mmu.c
++++ b/drivers/gpu/drm/panthor/panthor_mmu.c
+@@ -990,6 +990,8 @@ panthor_vm_map_pages(struct panthor_vm *vm, u64 iova, int prot,
+
+ if (!size)
+ break;
++
++ offset = 0;
+ }
+
+ return panthor_vm_flush_range(vm, start_iova, iova - start_iova);
+diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+index f161f40d8ce4c8..69900138295bf7 100644
+--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
++++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+@@ -1093,10 +1093,10 @@ static int vop_plane_atomic_async_check(struct drm_plane *plane,
+ if (!plane->state->fb)
+ return -EINVAL;
+
+- if (state)
+- crtc_state = drm_atomic_get_existing_crtc_state(state,
+- new_plane_state->crtc);
+- else /* Special case for asynchronous cursor updates. */
++ crtc_state = drm_atomic_get_existing_crtc_state(state, new_plane_state->crtc);
++
++ /* Special case for asynchronous cursor updates. */
++ if (!crtc_state)
+ crtc_state = plane->crtc->state;
+
+ return drm_atomic_helper_check_plane_state(plane->state, crtc_state,
+diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
+index 63b8d7591253cd..10d596cb4b4029 100644
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
+@@ -1265,6 +1265,8 @@ static int vmw_framebuffer_surface_create_handle(struct drm_framebuffer *fb,
+ struct vmw_framebuffer_surface *vfbs = vmw_framebuffer_to_vfbs(fb);
+ struct vmw_bo *bo = vmw_user_object_buffer(&vfbs->uo);
+
++ if (WARN_ON(!bo))
++ return -EINVAL;
+ return drm_gem_handle_create(file_priv, &bo->tbo.base, handle);
+ }
+
+diff --git a/drivers/gpu/drm/xe/xe_bo.c b/drivers/gpu/drm/xe/xe_bo.c
+index e147ef1d0578f3..9a01babe679c97 100644
+--- a/drivers/gpu/drm/xe/xe_bo.c
++++ b/drivers/gpu/drm/xe/xe_bo.c
+@@ -869,8 +869,8 @@ int xe_bo_evict_pinned(struct xe_bo *bo)
+ if (WARN_ON(!xe_bo_is_pinned(bo)))
+ return -EINVAL;
+
+- if (WARN_ON(!xe_bo_is_vram(bo)))
+- return -EINVAL;
++ if (!xe_bo_is_vram(bo))
++ return 0;
+
+ ret = ttm_bo_mem_space(&bo->ttm, &placement, &new_mem, &ctx);
+ if (ret)
+@@ -920,6 +920,7 @@ int xe_bo_restore_pinned(struct xe_bo *bo)
+ .interruptible = false,
+ };
+ struct ttm_resource *new_mem;
++ struct ttm_place *place = &bo->placements[0];
+ int ret;
+
+ xe_bo_assert_held(bo);
+@@ -930,9 +931,15 @@ int xe_bo_restore_pinned(struct xe_bo *bo)
+ if (WARN_ON(!xe_bo_is_pinned(bo)))
+ return -EINVAL;
+
+- if (WARN_ON(xe_bo_is_vram(bo) || !bo->ttm.ttm))
++ if (WARN_ON(xe_bo_is_vram(bo)))
++ return -EINVAL;
++
++ if (WARN_ON(!bo->ttm.ttm && !xe_bo_is_stolen(bo)))
+ return -EINVAL;
+
++ if (!mem_type_is_vram(place->mem_type))
++ return 0;
++
+ ret = ttm_bo_mem_space(&bo->ttm, &bo->placement, &new_mem, &ctx);
+ if (ret)
+ return ret;
+@@ -1702,6 +1709,7 @@ int xe_bo_pin_external(struct xe_bo *bo)
+
+ int xe_bo_pin(struct xe_bo *bo)
+ {
++ struct ttm_place *place = &bo->placements[0];
+ struct xe_device *xe = xe_bo_device(bo);
+ int err;
+
+@@ -1732,21 +1740,21 @@ int xe_bo_pin(struct xe_bo *bo)
+ */
+ if (IS_DGFX(xe) && !(IS_ENABLED(CONFIG_DRM_XE_DEBUG) &&
+ bo->flags & XE_BO_FLAG_INTERNAL_TEST)) {
+- struct ttm_place *place = &(bo->placements[0]);
+-
+ if (mem_type_is_vram(place->mem_type)) {
+ xe_assert(xe, place->flags & TTM_PL_FLAG_CONTIGUOUS);
+
+ place->fpfn = (xe_bo_addr(bo, 0, PAGE_SIZE) -
+ vram_region_gpu_offset(bo->ttm.resource)) >> PAGE_SHIFT;
+ place->lpfn = place->fpfn + (bo->size >> PAGE_SHIFT);
+-
+- spin_lock(&xe->pinned.lock);
+- list_add_tail(&bo->pinned_link, &xe->pinned.kernel_bo_present);
+- spin_unlock(&xe->pinned.lock);
+ }
+ }
+
++ if (mem_type_is_vram(place->mem_type) || bo->flags & XE_BO_FLAG_GGTT) {
++ spin_lock(&xe->pinned.lock);
++ list_add_tail(&bo->pinned_link, &xe->pinned.kernel_bo_present);
++ spin_unlock(&xe->pinned.lock);
++ }
++
+ ttm_bo_pin(&bo->ttm);
+
+ /*
+@@ -1792,23 +1800,18 @@ void xe_bo_unpin_external(struct xe_bo *bo)
+
+ void xe_bo_unpin(struct xe_bo *bo)
+ {
++ struct ttm_place *place = &bo->placements[0];
+ struct xe_device *xe = xe_bo_device(bo);
+
+ xe_assert(xe, !bo->ttm.base.import_attach);
+ xe_assert(xe, xe_bo_is_pinned(bo));
+
+- if (IS_DGFX(xe) && !(IS_ENABLED(CONFIG_DRM_XE_DEBUG) &&
+- bo->flags & XE_BO_FLAG_INTERNAL_TEST)) {
+- struct ttm_place *place = &(bo->placements[0]);
+-
+- if (mem_type_is_vram(place->mem_type)) {
+- spin_lock(&xe->pinned.lock);
+- xe_assert(xe, !list_empty(&bo->pinned_link));
+- list_del_init(&bo->pinned_link);
+- spin_unlock(&xe->pinned.lock);
+- }
++ if (mem_type_is_vram(place->mem_type) || bo->flags & XE_BO_FLAG_GGTT) {
++ spin_lock(&xe->pinned.lock);
++ xe_assert(xe, !list_empty(&bo->pinned_link));
++ list_del_init(&bo->pinned_link);
++ spin_unlock(&xe->pinned.lock);
+ }
+-
+ ttm_bo_unpin(&bo->ttm);
+ }
+
+diff --git a/drivers/gpu/drm/xe/xe_bo_evict.c b/drivers/gpu/drm/xe/xe_bo_evict.c
+index 541b49007d738a..8fb2be0610035b 100644
+--- a/drivers/gpu/drm/xe/xe_bo_evict.c
++++ b/drivers/gpu/drm/xe/xe_bo_evict.c
+@@ -34,14 +34,22 @@ int xe_bo_evict_all(struct xe_device *xe)
+ u8 id;
+ int ret;
+
+- if (!IS_DGFX(xe))
+- return 0;
+-
+ /* User memory */
+- for (mem_type = XE_PL_VRAM0; mem_type <= XE_PL_VRAM1; ++mem_type) {
++ for (mem_type = XE_PL_TT; mem_type <= XE_PL_VRAM1; ++mem_type) {
+ struct ttm_resource_manager *man =
+ ttm_manager_type(bdev, mem_type);
+
++ /*
++ * On igpu platforms with flat CCS we need to ensure we save and restore any CCS
++ * state since this state lives inside graphics stolen memory which doesn't survive
++ * hibernation.
++ *
++ * This can be further improved by only evicting objects that we know have actually
++ * used a compression enabled PAT index.
++ */
++ if (mem_type == XE_PL_TT && (IS_DGFX(xe) || !xe_device_has_flat_ccs(xe)))
++ continue;
++
+ if (man) {
+ ret = ttm_resource_manager_evict_all(bdev, man);
+ if (ret)
+@@ -125,9 +133,6 @@ int xe_bo_restore_kernel(struct xe_device *xe)
+ struct xe_bo *bo;
+ int ret;
+
+- if (!IS_DGFX(xe))
+- return 0;
+-
+ spin_lock(&xe->pinned.lock);
+ for (;;) {
+ bo = list_first_entry_or_null(&xe->pinned.evicted,
+@@ -159,7 +164,6 @@ int xe_bo_restore_kernel(struct xe_device *xe)
+ * should setup the iosys map.
+ */
+ xe_assert(xe, !iosys_map_is_null(&bo->vmap));
+- xe_assert(xe, xe_bo_is_vram(bo));
+
+ xe_bo_put(bo);
+
+diff --git a/drivers/gpu/drm/xe/xe_oa.c b/drivers/gpu/drm/xe/xe_oa.c
+index 5906df55dfdf2d..7b099a25e42a61 100644
+--- a/drivers/gpu/drm/xe/xe_oa.c
++++ b/drivers/gpu/drm/xe/xe_oa.c
+@@ -1206,9 +1206,11 @@ static int xe_oa_release(struct inode *inode, struct file *file)
+ struct xe_oa_stream *stream = file->private_data;
+ struct xe_gt *gt = stream->gt;
+
++ xe_pm_runtime_get(gt_to_xe(gt));
+ mutex_lock(>->oa.gt_lock);
+ xe_oa_destroy_locked(stream);
+ mutex_unlock(>->oa.gt_lock);
++ xe_pm_runtime_put(gt_to_xe(gt));
+
+ /* Release the reference the OA stream kept on the driver */
+ drm_dev_put(>_to_xe(gt)->drm);
+diff --git a/drivers/infiniband/core/addr.c b/drivers/infiniband/core/addr.c
+index c4cf26f1d1496a..be0743dac3fff3 100644
+--- a/drivers/infiniband/core/addr.c
++++ b/drivers/infiniband/core/addr.c
+@@ -269,8 +269,6 @@ rdma_find_ndev_for_src_ip_rcu(struct net *net, const struct sockaddr *src_in)
+ break;
+ #endif
+ }
+- if (!ret && dev && is_vlan_dev(dev))
+- dev = vlan_dev_real_dev(dev);
+ return ret ? ERR_PTR(ret) : dev;
+ }
+
+diff --git a/drivers/mailbox/qcom-cpucp-mbox.c b/drivers/mailbox/qcom-cpucp-mbox.c
+index e5437c294803c7..44f4ed15f81849 100644
+--- a/drivers/mailbox/qcom-cpucp-mbox.c
++++ b/drivers/mailbox/qcom-cpucp-mbox.c
+@@ -138,7 +138,7 @@ static int qcom_cpucp_mbox_probe(struct platform_device *pdev)
+ return irq;
+
+ ret = devm_request_irq(dev, irq, qcom_cpucp_mbox_irq_fn,
+- IRQF_TRIGGER_HIGH, "apss_cpucp_mbox", cpucp);
++ IRQF_TRIGGER_HIGH | IRQF_NO_SUSPEND, "apss_cpucp_mbox", cpucp);
+ if (ret < 0)
+ return dev_err_probe(dev, ret, "Failed to register irq: %d\n", irq);
+
+diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c
+index 14f323fbada719..9df7c213716aec 100644
+--- a/drivers/media/dvb-core/dvbdev.c
++++ b/drivers/media/dvb-core/dvbdev.c
+@@ -530,6 +530,9 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
+ for (minor = 0; minor < MAX_DVB_MINORS; minor++)
+ if (!dvb_minors[minor])
+ break;
++#else
++ minor = nums2minor(adap->num, type, id);
++#endif
+ if (minor >= MAX_DVB_MINORS) {
+ if (new_node) {
+ list_del(&new_node->list_head);
+@@ -543,17 +546,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
+ mutex_unlock(&dvbdev_register_lock);
+ return -EINVAL;
+ }
+-#else
+- minor = nums2minor(adap->num, type, id);
+- if (minor >= MAX_DVB_MINORS) {
+- dvb_media_device_free(dvbdev);
+- list_del(&dvbdev->list_head);
+- kfree(dvbdev);
+- *pdvbdev = NULL;
+- mutex_unlock(&dvbdev_register_lock);
+- return ret;
+- }
+-#endif
++
+ dvbdev->minor = minor;
+ dvb_minors[minor] = dvb_device_get(dvbdev);
+ up_write(&minor_rwsem);
+diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
+index 41e451235f6373..e9f6e4e622901a 100644
+--- a/drivers/mmc/host/dw_mmc.c
++++ b/drivers/mmc/host/dw_mmc.c
+@@ -2957,8 +2957,8 @@ static int dw_mci_init_slot(struct dw_mci *host)
+ if (host->use_dma == TRANS_MODE_IDMAC) {
+ mmc->max_segs = host->ring_size;
+ mmc->max_blk_size = 65535;
+- mmc->max_req_size = DW_MCI_DESC_DATA_LENGTH * host->ring_size;
+- mmc->max_seg_size = mmc->max_req_size;
++ mmc->max_seg_size = 0x1000;
++ mmc->max_req_size = mmc->max_seg_size * host->ring_size;
+ mmc->max_blk_count = mmc->max_req_size / 512;
+ } else if (host->use_dma == TRANS_MODE_EDMAC) {
+ mmc->max_segs = 64;
+diff --git a/drivers/mmc/host/sunxi-mmc.c b/drivers/mmc/host/sunxi-mmc.c
+index d3bd0ac99ec468..e0ab5fd635e6cd 100644
+--- a/drivers/mmc/host/sunxi-mmc.c
++++ b/drivers/mmc/host/sunxi-mmc.c
+@@ -1191,10 +1191,9 @@ static const struct sunxi_mmc_cfg sun50i_a64_emmc_cfg = {
+ .needs_new_timings = true,
+ };
+
+-static const struct sunxi_mmc_cfg sun50i_a100_cfg = {
++static const struct sunxi_mmc_cfg sun50i_h616_cfg = {
+ .idma_des_size_bits = 16,
+ .idma_des_shift = 2,
+- .clk_delays = NULL,
+ .can_calibrate = true,
+ .mask_data0 = true,
+ .needs_new_timings = true,
+@@ -1217,8 +1216,9 @@ static const struct of_device_id sunxi_mmc_of_match[] = {
+ { .compatible = "allwinner,sun20i-d1-mmc", .data = &sun20i_d1_cfg },
+ { .compatible = "allwinner,sun50i-a64-mmc", .data = &sun50i_a64_cfg },
+ { .compatible = "allwinner,sun50i-a64-emmc", .data = &sun50i_a64_emmc_cfg },
+- { .compatible = "allwinner,sun50i-a100-mmc", .data = &sun50i_a100_cfg },
++ { .compatible = "allwinner,sun50i-a100-mmc", .data = &sun20i_d1_cfg },
+ { .compatible = "allwinner,sun50i-a100-emmc", .data = &sun50i_a100_emmc_cfg },
++ { .compatible = "allwinner,sun50i-h616-mmc", .data = &sun50i_h616_cfg },
+ { /* sentinel */ }
+ };
+ MODULE_DEVICE_TABLE(of, sunxi_mmc_of_match);
+diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
+index e20bee1bdffd72..66725c16326350 100644
+--- a/drivers/net/bonding/bond_main.c
++++ b/drivers/net/bonding/bond_main.c
+@@ -934,6 +934,8 @@ static void bond_hw_addr_swap(struct bonding *bond, struct slave *new_active,
+
+ if (bond->dev->flags & IFF_UP)
+ bond_hw_addr_flush(bond->dev, old_active->dev);
++
++ bond_slave_ns_maddrs_add(bond, old_active);
+ }
+
+ if (new_active) {
+@@ -950,6 +952,8 @@ static void bond_hw_addr_swap(struct bonding *bond, struct slave *new_active,
+ dev_mc_sync(new_active->dev, bond->dev);
+ netif_addr_unlock_bh(bond->dev);
+ }
++
++ bond_slave_ns_maddrs_del(bond, new_active);
+ }
+ }
+
+@@ -2267,6 +2271,11 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev,
+ bond_compute_features(bond);
+ bond_set_carrier(bond);
+
++ /* Needs to be called before bond_select_active_slave(), which will
++ * remove the maddrs if the slave is selected as active slave.
++ */
++ bond_slave_ns_maddrs_add(bond, new_slave);
++
+ if (bond_uses_primary(bond)) {
+ block_netpoll_tx();
+ bond_select_active_slave(bond);
+@@ -2276,7 +2285,6 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev,
+ if (bond_mode_can_use_xmit_hash(bond))
+ bond_update_slave_arr(bond, NULL);
+
+-
+ if (!slave_dev->netdev_ops->ndo_bpf ||
+ !slave_dev->netdev_ops->ndo_xdp_xmit) {
+ if (bond->xdp_prog) {
+@@ -2474,6 +2482,12 @@ static int __bond_release_one(struct net_device *bond_dev,
+ if (oldcurrent == slave)
+ bond_change_active_slave(bond, NULL);
+
++ /* Must be called after bond_change_active_slave () as the slave
++ * might change from an active slave to a backup slave. Then it is
++ * necessary to clear the maddrs on the backup slave.
++ */
++ bond_slave_ns_maddrs_del(bond, slave);
++
+ if (bond_is_lb(bond)) {
+ /* Must be called only after the slave has been
+ * detached from the list and the curr_active_slave
+diff --git a/drivers/net/bonding/bond_options.c b/drivers/net/bonding/bond_options.c
+index 95d59a18c0223f..327b6ecdc77e00 100644
+--- a/drivers/net/bonding/bond_options.c
++++ b/drivers/net/bonding/bond_options.c
+@@ -15,6 +15,7 @@
+ #include <linux/sched/signal.h>
+
+ #include <net/bonding.h>
++#include <net/ndisc.h>
+
+ static int bond_option_active_slave_set(struct bonding *bond,
+ const struct bond_opt_value *newval);
+@@ -1234,6 +1235,68 @@ static int bond_option_arp_ip_targets_set(struct bonding *bond,
+ }
+
+ #if IS_ENABLED(CONFIG_IPV6)
++static bool slave_can_set_ns_maddr(const struct bonding *bond, struct slave *slave)
++{
++ return BOND_MODE(bond) == BOND_MODE_ACTIVEBACKUP &&
++ !bond_is_active_slave(slave) &&
++ slave->dev->flags & IFF_MULTICAST;
++}
++
++static void slave_set_ns_maddrs(struct bonding *bond, struct slave *slave, bool add)
++{
++ struct in6_addr *targets = bond->params.ns_targets;
++ char slot_maddr[MAX_ADDR_LEN];
++ int i;
++
++ if (!slave_can_set_ns_maddr(bond, slave))
++ return;
++
++ for (i = 0; i < BOND_MAX_NS_TARGETS; i++) {
++ if (ipv6_addr_any(&targets[i]))
++ break;
++
++ if (!ndisc_mc_map(&targets[i], slot_maddr, slave->dev, 0)) {
++ if (add)
++ dev_mc_add(slave->dev, slot_maddr);
++ else
++ dev_mc_del(slave->dev, slot_maddr);
++ }
++ }
++}
++
++void bond_slave_ns_maddrs_add(struct bonding *bond, struct slave *slave)
++{
++ if (!bond->params.arp_validate)
++ return;
++ slave_set_ns_maddrs(bond, slave, true);
++}
++
++void bond_slave_ns_maddrs_del(struct bonding *bond, struct slave *slave)
++{
++ if (!bond->params.arp_validate)
++ return;
++ slave_set_ns_maddrs(bond, slave, false);
++}
++
++static void slave_set_ns_maddr(struct bonding *bond, struct slave *slave,
++ struct in6_addr *target, struct in6_addr *slot)
++{
++ char target_maddr[MAX_ADDR_LEN], slot_maddr[MAX_ADDR_LEN];
++
++ if (!bond->params.arp_validate || !slave_can_set_ns_maddr(bond, slave))
++ return;
++
++ /* remove the previous maddr from slave */
++ if (!ipv6_addr_any(slot) &&
++ !ndisc_mc_map(slot, slot_maddr, slave->dev, 0))
++ dev_mc_del(slave->dev, slot_maddr);
++
++ /* add new maddr on slave if target is set */
++ if (!ipv6_addr_any(target) &&
++ !ndisc_mc_map(target, target_maddr, slave->dev, 0))
++ dev_mc_add(slave->dev, target_maddr);
++}
++
+ static void _bond_options_ns_ip6_target_set(struct bonding *bond, int slot,
+ struct in6_addr *target,
+ unsigned long last_rx)
+@@ -1243,8 +1306,10 @@ static void _bond_options_ns_ip6_target_set(struct bonding *bond, int slot,
+ struct slave *slave;
+
+ if (slot >= 0 && slot < BOND_MAX_NS_TARGETS) {
+- bond_for_each_slave(bond, slave, iter)
++ bond_for_each_slave(bond, slave, iter) {
+ slave->target_last_arp_rx[slot] = last_rx;
++ slave_set_ns_maddr(bond, slave, target, &targets[slot]);
++ }
+ targets[slot] = *target;
+ }
+ }
+@@ -1296,15 +1361,30 @@ static int bond_option_ns_ip6_targets_set(struct bonding *bond,
+ {
+ return -EPERM;
+ }
++
++static void slave_set_ns_maddrs(struct bonding *bond, struct slave *slave, bool add) {}
++
++void bond_slave_ns_maddrs_add(struct bonding *bond, struct slave *slave) {}
++
++void bond_slave_ns_maddrs_del(struct bonding *bond, struct slave *slave) {}
+ #endif
+
+ static int bond_option_arp_validate_set(struct bonding *bond,
+ const struct bond_opt_value *newval)
+ {
++ bool changed = !!bond->params.arp_validate != !!newval->value;
++ struct list_head *iter;
++ struct slave *slave;
++
+ netdev_dbg(bond->dev, "Setting arp_validate to %s (%llu)\n",
+ newval->string, newval->value);
+ bond->params.arp_validate = newval->value;
+
++ if (changed) {
++ bond_for_each_slave(bond, slave, iter)
++ slave_set_ns_maddrs(bond, slave, !!bond->params.arp_validate);
++ }
++
+ return 0;
+ }
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_ct.c b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_ct.c
+index 71a168746ebe21..deabed1d46a145 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_ct.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_ct.c
+@@ -866,7 +866,7 @@ mlx5_tc_ct_entry_add_rule(struct mlx5_tc_ct_priv *ct_priv,
+ return 0;
+
+ err_rule:
+- mlx5_tc_ct_entry_destroy_mod_hdr(ct_priv, zone_rule->attr, zone_rule->mh);
++ mlx5_tc_ct_entry_destroy_mod_hdr(ct_priv, attr, zone_rule->mh);
+ mlx5_put_label_mapping(ct_priv, attr->ct_attr.ct_labels_id);
+ err_mod_hdr:
+ kfree(attr);
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_tx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_tx.c
+index d61be26a4df1a5..3db31cc1071926 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_tx.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_tx.c
+@@ -660,7 +660,7 @@ tx_sync_info_get(struct mlx5e_ktls_offload_context_tx *priv_tx,
+ while (remaining > 0) {
+ skb_frag_t *frag = &record->frags[i];
+
+- get_page(skb_frag_page(frag));
++ page_ref_inc(skb_frag_page(frag));
+ remaining -= skb_frag_size(frag);
+ info->frags[i++] = *frag;
+ }
+@@ -763,7 +763,7 @@ void mlx5e_ktls_tx_handle_resync_dump_comp(struct mlx5e_txqsq *sq,
+ stats = sq->stats;
+
+ mlx5e_tx_dma_unmap(sq->pdev, dma);
+- put_page(wi->resync_dump_frag_page);
++ page_ref_dec(wi->resync_dump_frag_page);
+ stats->tls_dump_packets++;
+ stats->tls_dump_bytes += wi->num_bytes;
+ }
+@@ -816,12 +816,12 @@ mlx5e_ktls_tx_handle_ooo(struct mlx5e_ktls_offload_context_tx *priv_tx,
+
+ err_out:
+ for (; i < info.nr_frags; i++)
+- /* The put_page() here undoes the page ref obtained in tx_sync_info_get().
++ /* The page_ref_dec() here undoes the page ref obtained in tx_sync_info_get().
+ * Page refs obtained for the DUMP WQEs above (by page_ref_add) will be
+ * released only upon their completions (or in mlx5e_free_txqsq_descs,
+ * if channel closes).
+ */
+- put_page(skb_frag_page(&info.frags[i]));
++ page_ref_dec(skb_frag_page(&info.frags[i]));
+
+ return MLX5E_KTLS_SYNC_FAIL;
+ }
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+index 3e11c1c6d4f69b..99d0b977ed3d2f 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+@@ -4266,7 +4266,8 @@ void mlx5e_set_xdp_feature(struct net_device *netdev)
+ struct mlx5e_params *params = &priv->channels.params;
+ xdp_features_t val;
+
+- if (params->packet_merge.type != MLX5E_PACKET_MERGE_NONE) {
++ if (!netdev->netdev_ops->ndo_bpf ||
++ params->packet_merge.type != MLX5E_PACKET_MERGE_NONE) {
+ xdp_clear_features_flag(netdev);
+ return;
+ }
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_selftest.c b/drivers/net/ethernet/mellanox/mlx5/core/en_selftest.c
+index 5bf8318cc48b8e..1d60465cc2ca4f 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_selftest.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_selftest.c
+@@ -36,6 +36,7 @@
+ #include "en.h"
+ #include "en/port.h"
+ #include "eswitch.h"
++#include "lib/mlx5.h"
+
+ static int mlx5e_test_health_info(struct mlx5e_priv *priv)
+ {
+@@ -247,6 +248,9 @@ static int mlx5e_cond_loopback(struct mlx5e_priv *priv)
+ if (is_mdev_switchdev_mode(priv->mdev))
+ return -EOPNOTSUPP;
+
++ if (mlx5_get_sd(priv->mdev))
++ return -EOPNOTSUPP;
++
+ return 0;
+ }
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c
+index a47d6419160d78..fb01acbadf7325 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c
+@@ -1946,13 +1946,22 @@ lookup_fte_locked(struct mlx5_flow_group *g,
+ fte_tmp = NULL;
+ goto out;
+ }
++
++ nested_down_write_ref_node(&fte_tmp->node, FS_LOCK_CHILD);
++
+ if (!fte_tmp->node.active) {
++ up_write_ref_node(&fte_tmp->node, false);
++
++ if (take_write)
++ up_write_ref_node(&g->node, false);
++ else
++ up_read_ref_node(&g->node);
++
+ tree_put_node(&fte_tmp->node, false);
+- fte_tmp = NULL;
+- goto out;
++
++ return NULL;
+ }
+
+- nested_down_write_ref_node(&fte_tmp->node, FS_LOCK_CHILD);
+ out:
+ if (take_write)
+ up_write_ref_node(&g->node, false);
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/pci_irq.c b/drivers/net/ethernet/mellanox/mlx5/core/pci_irq.c
+index 81a9232a03e1ba..7db9cab9bedf69 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/pci_irq.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/pci_irq.c
+@@ -593,9 +593,11 @@ static void irq_pool_free(struct mlx5_irq_pool *pool)
+ kvfree(pool);
+ }
+
+-static int irq_pools_init(struct mlx5_core_dev *dev, int sf_vec, int pcif_vec)
++static int irq_pools_init(struct mlx5_core_dev *dev, int sf_vec, int pcif_vec,
++ bool dynamic_vec)
+ {
+ struct mlx5_irq_table *table = dev->priv.irq_table;
++ int sf_vec_available = sf_vec;
+ int num_sf_ctrl;
+ int err;
+
+@@ -616,6 +618,13 @@ static int irq_pools_init(struct mlx5_core_dev *dev, int sf_vec, int pcif_vec)
+ num_sf_ctrl = DIV_ROUND_UP(mlx5_sf_max_functions(dev),
+ MLX5_SFS_PER_CTRL_IRQ);
+ num_sf_ctrl = min_t(int, MLX5_IRQ_CTRL_SF_MAX, num_sf_ctrl);
++ if (!dynamic_vec && (num_sf_ctrl + 1) > sf_vec_available) {
++ mlx5_core_dbg(dev,
++ "Not enough IRQs for SFs control and completion pool, required=%d avail=%d\n",
++ num_sf_ctrl + 1, sf_vec_available);
++ return 0;
++ }
++
+ table->sf_ctrl_pool = irq_pool_alloc(dev, pcif_vec, num_sf_ctrl,
+ "mlx5_sf_ctrl",
+ MLX5_EQ_SHARE_IRQ_MIN_CTRL,
+@@ -624,9 +633,11 @@ static int irq_pools_init(struct mlx5_core_dev *dev, int sf_vec, int pcif_vec)
+ err = PTR_ERR(table->sf_ctrl_pool);
+ goto err_pf;
+ }
+- /* init sf_comp_pool */
++ sf_vec_available -= num_sf_ctrl;
++
++ /* init sf_comp_pool, remaining vectors are for the SF completions */
+ table->sf_comp_pool = irq_pool_alloc(dev, pcif_vec + num_sf_ctrl,
+- sf_vec - num_sf_ctrl, "mlx5_sf_comp",
++ sf_vec_available, "mlx5_sf_comp",
+ MLX5_EQ_SHARE_IRQ_MIN_COMP,
+ MLX5_EQ_SHARE_IRQ_MAX_COMP);
+ if (IS_ERR(table->sf_comp_pool)) {
+@@ -715,6 +726,7 @@ int mlx5_irq_table_get_num_comp(struct mlx5_irq_table *table)
+ int mlx5_irq_table_create(struct mlx5_core_dev *dev)
+ {
+ int num_eqs = mlx5_max_eq_cap_get(dev);
++ bool dynamic_vec;
+ int total_vec;
+ int pcif_vec;
+ int req_vec;
+@@ -724,21 +736,31 @@ int mlx5_irq_table_create(struct mlx5_core_dev *dev)
+ if (mlx5_core_is_sf(dev))
+ return 0;
+
++ /* PCI PF vectors usage is limited by online cpus, device EQs and
++ * PCI MSI-X capability.
++ */
+ pcif_vec = MLX5_CAP_GEN(dev, num_ports) * num_online_cpus() + 1;
+ pcif_vec = min_t(int, pcif_vec, num_eqs);
++ pcif_vec = min_t(int, pcif_vec, pci_msix_vec_count(dev->pdev));
+
+ total_vec = pcif_vec;
+ if (mlx5_sf_max_functions(dev))
+ total_vec += MLX5_MAX_MSIX_PER_SF * mlx5_sf_max_functions(dev);
+ total_vec = min_t(int, total_vec, pci_msix_vec_count(dev->pdev));
+- pcif_vec = min_t(int, pcif_vec, pci_msix_vec_count(dev->pdev));
+
+ req_vec = pci_msix_can_alloc_dyn(dev->pdev) ? 1 : total_vec;
+ n = pci_alloc_irq_vectors(dev->pdev, 1, req_vec, PCI_IRQ_MSIX);
+ if (n < 0)
+ return n;
+
+- err = irq_pools_init(dev, total_vec - pcif_vec, pcif_vec);
++ /* Further limit vectors of the pools based on platform for non dynamic case */
++ dynamic_vec = pci_msix_can_alloc_dyn(dev->pdev);
++ if (!dynamic_vec) {
++ pcif_vec = min_t(int, n, pcif_vec);
++ total_vec = min_t(int, n, total_vec);
++ }
++
++ err = irq_pools_init(dev, total_vec - pcif_vec, pcif_vec, dynamic_vec);
+ if (err)
+ pci_free_irq_vectors(dev->pdev);
+
+diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel-plat.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel-plat.c
+index d68f0c4e783505..9739bc9867c514 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel-plat.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel-plat.c
+@@ -108,7 +108,12 @@ static int intel_eth_plat_probe(struct platform_device *pdev)
+ if (IS_ERR(dwmac->tx_clk))
+ return PTR_ERR(dwmac->tx_clk);
+
+- clk_prepare_enable(dwmac->tx_clk);
++ ret = clk_prepare_enable(dwmac->tx_clk);
++ if (ret) {
++ dev_err(&pdev->dev,
++ "Failed to enable tx_clk\n");
++ return ret;
++ }
+
+ /* Check and configure TX clock rate */
+ rate = clk_get_rate(dwmac->tx_clk);
+@@ -119,7 +124,7 @@ static int intel_eth_plat_probe(struct platform_device *pdev)
+ if (ret) {
+ dev_err(&pdev->dev,
+ "Failed to set tx_clk\n");
+- return ret;
++ goto err_tx_clk_disable;
+ }
+ }
+ }
+@@ -133,7 +138,7 @@ static int intel_eth_plat_probe(struct platform_device *pdev)
+ if (ret) {
+ dev_err(&pdev->dev,
+ "Failed to set clk_ptp_ref\n");
+- return ret;
++ goto err_tx_clk_disable;
+ }
+ }
+ }
+@@ -149,12 +154,15 @@ static int intel_eth_plat_probe(struct platform_device *pdev)
+ }
+
+ ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
+- if (ret) {
+- clk_disable_unprepare(dwmac->tx_clk);
+- return ret;
+- }
++ if (ret)
++ goto err_tx_clk_disable;
+
+ return 0;
++
++err_tx_clk_disable:
++ if (dwmac->data->tx_clk_en)
++ clk_disable_unprepare(dwmac->tx_clk);
++ return ret;
+ }
+
+ static void intel_eth_plat_remove(struct platform_device *pdev)
+@@ -162,7 +170,8 @@ static void intel_eth_plat_remove(struct platform_device *pdev)
+ struct intel_dwmac *dwmac = get_stmmac_bsp_priv(&pdev->dev);
+
+ stmmac_pltfr_remove(pdev);
+- clk_disable_unprepare(dwmac->tx_clk);
++ if (dwmac->data->tx_clk_en)
++ clk_disable_unprepare(dwmac->tx_clk);
+ }
+
+ static struct platform_driver intel_eth_plat_driver = {
+diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c
+index 2a9132d6d743ce..001857c294fba1 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c
+@@ -589,9 +589,9 @@ static int mediatek_dwmac_common_data(struct platform_device *pdev,
+
+ plat->mac_interface = priv_plat->phy_mode;
+ if (priv_plat->mac_wol)
+- plat->flags |= STMMAC_FLAG_USE_PHY_WOL;
+- else
+ plat->flags &= ~STMMAC_FLAG_USE_PHY_WOL;
++ else
++ plat->flags |= STMMAC_FLAG_USE_PHY_WOL;
+ plat->riwt_off = 1;
+ plat->maxmtu = ETH_DATA_LEN;
+ plat->host_dma_width = priv_plat->variant->dma_bit_mask;
+diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.c b/drivers/net/ethernet/ti/icssg/icssg_prueth.c
+index 33cb3590a5cdec..55d12679b24b72 100644
+--- a/drivers/net/ethernet/ti/icssg/icssg_prueth.c
++++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.c
+@@ -15,6 +15,7 @@
+ #include <linux/genalloc.h>
+ #include <linux/if_vlan.h>
+ #include <linux/interrupt.h>
++#include <linux/io-64-nonatomic-hi-lo.h>
+ #include <linux/kernel.h>
+ #include <linux/mfd/syscon.h>
+ #include <linux/module.h>
+@@ -389,6 +390,8 @@ static int prueth_perout_enable(void *clockops_data,
+ struct prueth_emac *emac = clockops_data;
+ u32 reduction_factor = 0, offset = 0;
+ struct timespec64 ts;
++ u64 current_cycle;
++ u64 start_offset;
+ u64 ns_period;
+
+ if (!on)
+@@ -427,8 +430,14 @@ static int prueth_perout_enable(void *clockops_data,
+ writel(reduction_factor, emac->prueth->shram.va +
+ TIMESYNC_FW_WC_SYNCOUT_REDUCTION_FACTOR_OFFSET);
+
+- writel(0, emac->prueth->shram.va +
+- TIMESYNC_FW_WC_SYNCOUT_START_TIME_CYCLECOUNT_OFFSET);
++ current_cycle = icssg_read_time(emac->prueth->shram.va +
++ TIMESYNC_FW_WC_CYCLECOUNT_OFFSET);
++
++ /* Rounding of current_cycle count to next second */
++ start_offset = roundup(current_cycle, MSEC_PER_SEC);
++
++ hi_lo_writeq(start_offset, emac->prueth->shram.va +
++ TIMESYNC_FW_WC_SYNCOUT_START_TIME_CYCLECOUNT_OFFSET);
+
+ return 0;
+ }
+diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.h b/drivers/net/ethernet/ti/icssg/icssg_prueth.h
+index 4d1c895dacdb67..169949acf2539f 100644
+--- a/drivers/net/ethernet/ti/icssg/icssg_prueth.h
++++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.h
+@@ -316,6 +316,18 @@ static inline int prueth_emac_slice(struct prueth_emac *emac)
+ extern const struct ethtool_ops icssg_ethtool_ops;
+ extern const struct dev_pm_ops prueth_dev_pm_ops;
+
++static inline u64 icssg_read_time(const void __iomem *addr)
++{
++ u32 low, high;
++
++ do {
++ high = readl(addr + 4);
++ low = readl(addr);
++ } while (high != readl(addr + 4));
++
++ return low + ((u64)high << 32);
++}
++
+ /* Classifier helpers */
+ void icssg_class_set_mac_addr(struct regmap *miig_rt, int slice, u8 *mac);
+ void icssg_class_set_host_mac_addr(struct regmap *miig_rt, const u8 *mac);
+diff --git a/drivers/net/ethernet/vertexcom/mse102x.c b/drivers/net/ethernet/vertexcom/mse102x.c
+index 33ef3a49de8ee8..bccf0ac66b1a84 100644
+--- a/drivers/net/ethernet/vertexcom/mse102x.c
++++ b/drivers/net/ethernet/vertexcom/mse102x.c
+@@ -437,13 +437,15 @@ static void mse102x_tx_work(struct work_struct *work)
+ mse = &mses->mse102x;
+
+ while ((txb = skb_dequeue(&mse->txq))) {
++ unsigned int len = max_t(unsigned int, txb->len, ETH_ZLEN);
++
+ mutex_lock(&mses->lock);
+ ret = mse102x_tx_pkt_spi(mse, txb, work_timeout);
+ mutex_unlock(&mses->lock);
+ if (ret) {
+ mse->ndev->stats.tx_dropped++;
+ } else {
+- mse->ndev->stats.tx_bytes += txb->len;
++ mse->ndev->stats.tx_bytes += len;
+ mse->ndev->stats.tx_packets++;
+ }
+
+diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c
+index 51c526d227fab3..ed60836180b78f 100644
+--- a/drivers/net/phy/phylink.c
++++ b/drivers/net/phy/phylink.c
+@@ -78,7 +78,7 @@ struct phylink {
+ unsigned int pcs_neg_mode;
+ unsigned int pcs_state;
+
+- bool mac_link_dropped;
++ bool link_failed;
+ bool using_mac_select_pcs;
+
+ struct sfp_bus *sfp_bus;
+@@ -1475,9 +1475,9 @@ static void phylink_resolve(struct work_struct *w)
+ cur_link_state = pl->old_link_state;
+
+ if (pl->phylink_disable_state) {
+- pl->mac_link_dropped = false;
++ pl->link_failed = false;
+ link_state.link = false;
+- } else if (pl->mac_link_dropped) {
++ } else if (pl->link_failed) {
+ link_state.link = false;
+ retrigger = true;
+ } else {
+@@ -1572,7 +1572,7 @@ static void phylink_resolve(struct work_struct *w)
+ phylink_link_up(pl, link_state);
+ }
+ if (!link_state.link && retrigger) {
+- pl->mac_link_dropped = false;
++ pl->link_failed = false;
+ queue_work(system_power_efficient_wq, &pl->resolve);
+ }
+ mutex_unlock(&pl->state_mutex);
+@@ -1793,6 +1793,8 @@ static void phylink_phy_change(struct phy_device *phydev, bool up)
+ pl->phy_state.pause |= MLO_PAUSE_RX;
+ pl->phy_state.interface = phydev->interface;
+ pl->phy_state.link = up;
++ if (!up)
++ pl->link_failed = true;
+ mutex_unlock(&pl->state_mutex);
+
+ phylink_run_resolve(pl);
+@@ -2116,7 +2118,7 @@ EXPORT_SYMBOL_GPL(phylink_disconnect_phy);
+ static void phylink_link_changed(struct phylink *pl, bool up, const char *what)
+ {
+ if (!up)
+- pl->mac_link_dropped = true;
++ pl->link_failed = true;
+ phylink_run_resolve(pl);
+ phylink_dbg(pl, "%s link %s\n", what, up ? "up" : "down");
+ }
+@@ -2750,7 +2752,7 @@ int phylink_ethtool_set_pauseparam(struct phylink *pl,
+ * link will cycle.
+ */
+ if (manual_changed) {
+- pl->mac_link_dropped = true;
++ pl->link_failed = true;
+ phylink_run_resolve(pl);
+ }
+
+diff --git a/drivers/perf/riscv_pmu_sbi.c b/drivers/perf/riscv_pmu_sbi.c
+index 671dc55cbd3a87..bc562c759e1e9d 100644
+--- a/drivers/perf/riscv_pmu_sbi.c
++++ b/drivers/perf/riscv_pmu_sbi.c
+@@ -1380,8 +1380,9 @@ static int pmu_sbi_device_probe(struct platform_device *pdev)
+ goto out_unregister;
+
+ cpu = get_cpu();
+-
+ ret = pmu_sbi_snapshot_setup(pmu, cpu);
++ put_cpu();
++
+ if (ret) {
+ /* Snapshot is an optional feature. Continue if not available */
+ pmu_sbi_snapshot_free(pmu);
+@@ -1395,7 +1396,6 @@ static int pmu_sbi_device_probe(struct platform_device *pdev)
+ */
+ static_branch_enable(&sbi_pmu_snapshot_available);
+ }
+- put_cpu();
+ }
+
+ register_sysctl("kernel", sbi_pmu_sysctl_table);
+diff --git a/drivers/pmdomain/arm/scmi_perf_domain.c b/drivers/pmdomain/arm/scmi_perf_domain.c
+index d7ef46ccd9b8a4..3693423459c9cc 100644
+--- a/drivers/pmdomain/arm/scmi_perf_domain.c
++++ b/drivers/pmdomain/arm/scmi_perf_domain.c
+@@ -125,7 +125,8 @@ static int scmi_perf_domain_probe(struct scmi_device *sdev)
+ scmi_pd->ph = ph;
+ scmi_pd->genpd.name = scmi_pd->info->name;
+ scmi_pd->genpd.flags = GENPD_FLAG_ALWAYS_ON |
+- GENPD_FLAG_OPP_TABLE_FW;
++ GENPD_FLAG_OPP_TABLE_FW |
++ GENPD_FLAG_DEV_NAME_FW;
+ scmi_pd->genpd.set_performance_state = scmi_pd_set_perf_state;
+ scmi_pd->genpd.attach_dev = scmi_pd_attach_dev;
+ scmi_pd->genpd.detach_dev = scmi_pd_detach_dev;
+diff --git a/drivers/pmdomain/core.c b/drivers/pmdomain/core.c
+index 3a4e59b93677c3..8a4a7850450cde 100644
+--- a/drivers/pmdomain/core.c
++++ b/drivers/pmdomain/core.c
+@@ -7,6 +7,7 @@
+ #define pr_fmt(fmt) "PM: " fmt
+
+ #include <linux/delay.h>
++#include <linux/idr.h>
+ #include <linux/kernel.h>
+ #include <linux/io.h>
+ #include <linux/platform_device.h>
+@@ -23,6 +24,9 @@
+ #include <linux/cpu.h>
+ #include <linux/debugfs.h>
+
++/* Provides a unique ID for each genpd device */
++static DEFINE_IDA(genpd_ida);
++
+ #define GENPD_RETRY_MAX_MS 250 /* Approximate */
+
+ #define GENPD_DEV_CALLBACK(genpd, type, callback, dev) \
+@@ -129,6 +133,7 @@ static const struct genpd_lock_ops genpd_spin_ops = {
+ #define genpd_is_cpu_domain(genpd) (genpd->flags & GENPD_FLAG_CPU_DOMAIN)
+ #define genpd_is_rpm_always_on(genpd) (genpd->flags & GENPD_FLAG_RPM_ALWAYS_ON)
+ #define genpd_is_opp_table_fw(genpd) (genpd->flags & GENPD_FLAG_OPP_TABLE_FW)
++#define genpd_is_dev_name_fw(genpd) (genpd->flags & GENPD_FLAG_DEV_NAME_FW)
+
+ static inline bool irq_safe_dev_in_sleep_domain(struct device *dev,
+ const struct generic_pm_domain *genpd)
+@@ -147,7 +152,7 @@ static inline bool irq_safe_dev_in_sleep_domain(struct device *dev,
+
+ if (ret)
+ dev_warn_once(dev, "PM domain %s will not be powered off\n",
+- genpd->name);
++ dev_name(&genpd->dev));
+
+ return ret;
+ }
+@@ -232,7 +237,7 @@ static void genpd_debug_remove(struct generic_pm_domain *genpd)
+ if (!genpd_debugfs_dir)
+ return;
+
+- debugfs_lookup_and_remove(genpd->name, genpd_debugfs_dir);
++ debugfs_lookup_and_remove(dev_name(&genpd->dev), genpd_debugfs_dir);
+ }
+
+ static void genpd_update_accounting(struct generic_pm_domain *genpd)
+@@ -689,7 +694,7 @@ static int _genpd_power_on(struct generic_pm_domain *genpd, bool timed)
+ genpd->states[state_idx].power_on_latency_ns = elapsed_ns;
+ genpd->gd->max_off_time_changed = true;
+ pr_debug("%s: Power-%s latency exceeded, new value %lld ns\n",
+- genpd->name, "on", elapsed_ns);
++ dev_name(&genpd->dev), "on", elapsed_ns);
+
+ out:
+ raw_notifier_call_chain(&genpd->power_notifiers, GENPD_NOTIFY_ON, NULL);
+@@ -740,7 +745,7 @@ static int _genpd_power_off(struct generic_pm_domain *genpd, bool timed)
+ genpd->states[state_idx].power_off_latency_ns = elapsed_ns;
+ genpd->gd->max_off_time_changed = true;
+ pr_debug("%s: Power-%s latency exceeded, new value %lld ns\n",
+- genpd->name, "off", elapsed_ns);
++ dev_name(&genpd->dev), "off", elapsed_ns);
+
+ out:
+ raw_notifier_call_chain(&genpd->power_notifiers, GENPD_NOTIFY_OFF,
+@@ -1898,7 +1903,7 @@ int dev_pm_genpd_add_notifier(struct device *dev, struct notifier_block *nb)
+
+ if (ret) {
+ dev_warn(dev, "failed to add notifier for PM domain %s\n",
+- genpd->name);
++ dev_name(&genpd->dev));
+ return ret;
+ }
+
+@@ -1945,7 +1950,7 @@ int dev_pm_genpd_remove_notifier(struct device *dev)
+
+ if (ret) {
+ dev_warn(dev, "failed to remove notifier for PM domain %s\n",
+- genpd->name);
++ dev_name(&genpd->dev));
+ return ret;
+ }
+
+@@ -1971,7 +1976,7 @@ static int genpd_add_subdomain(struct generic_pm_domain *genpd,
+ */
+ if (!genpd_is_irq_safe(genpd) && genpd_is_irq_safe(subdomain)) {
+ WARN(1, "Parent %s of subdomain %s must be IRQ safe\n",
+- genpd->name, subdomain->name);
++ dev_name(&genpd->dev), subdomain->name);
+ return -EINVAL;
+ }
+
+@@ -2046,7 +2051,7 @@ int pm_genpd_remove_subdomain(struct generic_pm_domain *genpd,
+
+ if (!list_empty(&subdomain->parent_links) || subdomain->device_count) {
+ pr_warn("%s: unable to remove subdomain %s\n",
+- genpd->name, subdomain->name);
++ dev_name(&genpd->dev), subdomain->name);
+ ret = -EBUSY;
+ goto out;
+ }
+@@ -2180,6 +2185,7 @@ int pm_genpd_init(struct generic_pm_domain *genpd,
+ genpd->status = is_off ? GENPD_STATE_OFF : GENPD_STATE_ON;
+ genpd->device_count = 0;
+ genpd->provider = NULL;
++ genpd->device_id = -ENXIO;
+ genpd->has_provider = false;
+ genpd->accounting_time = ktime_get_mono_fast_ns();
+ genpd->domain.ops.runtime_suspend = genpd_runtime_suspend;
+@@ -2220,7 +2226,18 @@ int pm_genpd_init(struct generic_pm_domain *genpd,
+ return ret;
+
+ device_initialize(&genpd->dev);
+- dev_set_name(&genpd->dev, "%s", genpd->name);
++
++ if (!genpd_is_dev_name_fw(genpd)) {
++ dev_set_name(&genpd->dev, "%s", genpd->name);
++ } else {
++ ret = ida_alloc(&genpd_ida, GFP_KERNEL);
++ if (ret < 0) {
++ put_device(&genpd->dev);
++ return ret;
++ }
++ genpd->device_id = ret;
++ dev_set_name(&genpd->dev, "%s_%u", genpd->name, genpd->device_id);
++ }
+
+ mutex_lock(&gpd_list_lock);
+ list_add(&genpd->gpd_list_node, &gpd_list);
+@@ -2242,13 +2259,13 @@ static int genpd_remove(struct generic_pm_domain *genpd)
+
+ if (genpd->has_provider) {
+ genpd_unlock(genpd);
+- pr_err("Provider present, unable to remove %s\n", genpd->name);
++ pr_err("Provider present, unable to remove %s\n", dev_name(&genpd->dev));
+ return -EBUSY;
+ }
+
+ if (!list_empty(&genpd->parent_links) || genpd->device_count) {
+ genpd_unlock(genpd);
+- pr_err("%s: unable to remove %s\n", __func__, genpd->name);
++ pr_err("%s: unable to remove %s\n", __func__, dev_name(&genpd->dev));
+ return -EBUSY;
+ }
+
+@@ -2262,9 +2279,11 @@ static int genpd_remove(struct generic_pm_domain *genpd)
+ genpd_unlock(genpd);
+ genpd_debug_remove(genpd);
+ cancel_work_sync(&genpd->power_off_work);
++ if (genpd->device_id != -ENXIO)
++ ida_free(&genpd_ida, genpd->device_id);
+ genpd_free_data(genpd);
+
+- pr_debug("%s: removed %s\n", __func__, genpd->name);
++ pr_debug("%s: removed %s\n", __func__, dev_name(&genpd->dev));
+
+ return 0;
+ }
+@@ -3226,12 +3245,12 @@ static int genpd_summary_one(struct seq_file *s,
+ else
+ snprintf(state, sizeof(state), "%s",
+ status_lookup[genpd->status]);
+- seq_printf(s, "%-30s %-30s %u", genpd->name, state, genpd->performance_state);
++ seq_printf(s, "%-30s %-30s %u", dev_name(&genpd->dev), state, genpd->performance_state);
+
+ /*
+ * Modifications on the list require holding locks on both
+ * parent and child, so we are safe.
+- * Also genpd->name is immutable.
++ * Also the device name is immutable.
+ */
+ list_for_each_entry(link, &genpd->parent_links, parent_node) {
+ if (list_is_first(&link->parent_node, &genpd->parent_links))
+@@ -3456,7 +3475,7 @@ static void genpd_debug_add(struct generic_pm_domain *genpd)
+ if (!genpd_debugfs_dir)
+ return;
+
+- d = debugfs_create_dir(genpd->name, genpd_debugfs_dir);
++ d = debugfs_create_dir(dev_name(&genpd->dev), genpd_debugfs_dir);
+
+ debugfs_create_file("current_state", 0444,
+ d, genpd, &status_fops);
+diff --git a/drivers/pmdomain/imx/imx93-blk-ctrl.c b/drivers/pmdomain/imx/imx93-blk-ctrl.c
+index 904ffa55b8f4d3..b10348ac10f06d 100644
+--- a/drivers/pmdomain/imx/imx93-blk-ctrl.c
++++ b/drivers/pmdomain/imx/imx93-blk-ctrl.c
+@@ -313,7 +313,9 @@ static void imx93_blk_ctrl_remove(struct platform_device *pdev)
+
+ of_genpd_del_provider(pdev->dev.of_node);
+
+- for (i = 0; bc->onecell_data.num_domains; i++) {
++ pm_runtime_disable(&pdev->dev);
++
++ for (i = 0; i < bc->onecell_data.num_domains; i++) {
+ struct imx93_blk_ctrl_domain *domain = &bc->domains[i];
+
+ pm_genpd_remove(&domain->genpd);
+diff --git a/drivers/vdpa/mlx5/core/mr.c b/drivers/vdpa/mlx5/core/mr.c
+index bf56f3d6962533..f1da0b7e08e9e0 100644
+--- a/drivers/vdpa/mlx5/core/mr.c
++++ b/drivers/vdpa/mlx5/core/mr.c
+@@ -232,7 +232,7 @@ static int map_direct_mr(struct mlx5_vdpa_dev *mvdev, struct mlx5_vdpa_direct_mr
+ struct page *pg;
+ unsigned int nsg;
+ int sglen;
+- u64 pa;
++ u64 pa, offset;
+ u64 paend;
+ struct scatterlist *sg;
+ struct device *dma = mvdev->vdev.dma_dev;
+@@ -255,8 +255,10 @@ static int map_direct_mr(struct mlx5_vdpa_dev *mvdev, struct mlx5_vdpa_direct_mr
+ sg = mr->sg_head.sgl;
+ for (map = vhost_iotlb_itree_first(iotlb, mr->start, mr->end - 1);
+ map; map = vhost_iotlb_itree_next(map, mr->start, mr->end - 1)) {
+- paend = map->addr + maplen(map, mr);
+- for (pa = map->addr; pa < paend; pa += sglen) {
++ offset = mr->start > map->start ? mr->start - map->start : 0;
++ pa = map->addr + offset;
++ paend = map->addr + offset + maplen(map, mr);
++ for (; pa < paend; pa += sglen) {
+ pg = pfn_to_page(__phys_to_pfn(pa));
+ if (!sg) {
+ mlx5_vdpa_warn(mvdev, "sg null. start 0x%llx, end 0x%llx\n",
+diff --git a/drivers/vdpa/solidrun/snet_main.c b/drivers/vdpa/solidrun/snet_main.c
+index 99428a04068d2d..c8b74980dbd172 100644
+--- a/drivers/vdpa/solidrun/snet_main.c
++++ b/drivers/vdpa/solidrun/snet_main.c
+@@ -555,7 +555,7 @@ static const struct vdpa_config_ops snet_config_ops = {
+
+ static int psnet_open_pf_bar(struct pci_dev *pdev, struct psnet *psnet)
+ {
+- char name[50];
++ char *name;
+ int ret, i, mask = 0;
+ /* We don't know which BAR will be used to communicate..
+ * We will map every bar with len > 0.
+@@ -573,7 +573,10 @@ static int psnet_open_pf_bar(struct pci_dev *pdev, struct psnet *psnet)
+ return -ENODEV;
+ }
+
+- snprintf(name, sizeof(name), "psnet[%s]-bars", pci_name(pdev));
++ name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "psnet[%s]-bars", pci_name(pdev));
++ if (!name)
++ return -ENOMEM;
++
+ ret = pcim_iomap_regions(pdev, mask, name);
+ if (ret) {
+ SNET_ERR(pdev, "Failed to request and map PCI BARs\n");
+@@ -590,10 +593,13 @@ static int psnet_open_pf_bar(struct pci_dev *pdev, struct psnet *psnet)
+
+ static int snet_open_vf_bar(struct pci_dev *pdev, struct snet *snet)
+ {
+- char name[50];
++ char *name;
+ int ret;
+
+- snprintf(name, sizeof(name), "snet[%s]-bar", pci_name(pdev));
++ name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "snet[%s]-bars", pci_name(pdev));
++ if (!name)
++ return -ENOMEM;
++
+ /* Request and map BAR */
+ ret = pcim_iomap_regions(pdev, BIT(snet->psnet->cfg.vf_bar), name);
+ if (ret) {
+diff --git a/drivers/vdpa/virtio_pci/vp_vdpa.c b/drivers/vdpa/virtio_pci/vp_vdpa.c
+index ac4ab22f7d8b94..16380764275ea0 100644
+--- a/drivers/vdpa/virtio_pci/vp_vdpa.c
++++ b/drivers/vdpa/virtio_pci/vp_vdpa.c
+@@ -612,7 +612,11 @@ static int vp_vdpa_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+ goto mdev_err;
+ }
+
+- mdev_id = kzalloc(sizeof(struct virtio_device_id), GFP_KERNEL);
++ /*
++ * id_table should be a null terminated array, so allocate one additional
++ * entry here, see vdpa_mgmtdev_get_classes().
++ */
++ mdev_id = kcalloc(2, sizeof(struct virtio_device_id), GFP_KERNEL);
+ if (!mdev_id) {
+ err = -ENOMEM;
+ goto mdev_id_err;
+@@ -632,8 +636,8 @@ static int vp_vdpa_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+ goto probe_err;
+ }
+
+- mdev_id->device = mdev->id.device;
+- mdev_id->vendor = mdev->id.vendor;
++ mdev_id[0].device = mdev->id.device;
++ mdev_id[0].vendor = mdev->id.vendor;
+ mgtdev->id_table = mdev_id;
+ mgtdev->max_supported_vqs = vp_modern_get_num_queues(mdev);
+ mgtdev->supported_features = vp_modern_get_features(mdev);
+diff --git a/fs/btrfs/delayed-ref.c b/fs/btrfs/delayed-ref.c
+index 7a2a4fdc07f1ff..af65d113853bcc 100644
+--- a/fs/btrfs/delayed-ref.c
++++ b/fs/btrfs/delayed-ref.c
+@@ -298,7 +298,7 @@ static int comp_refs(struct btrfs_delayed_ref_node *ref1,
+ if (ref1->ref_root < ref2->ref_root)
+ return -1;
+ if (ref1->ref_root > ref2->ref_root)
+- return -1;
++ return 1;
+ if (ref1->type == BTRFS_EXTENT_DATA_REF_KEY)
+ ret = comp_data_refs(ref1, ref2);
+ }
+diff --git a/fs/nilfs2/btnode.c b/fs/nilfs2/btnode.c
+index c034080c334b98..5f894459bafefe 100644
+--- a/fs/nilfs2/btnode.c
++++ b/fs/nilfs2/btnode.c
+@@ -68,7 +68,6 @@ nilfs_btnode_create_block(struct address_space *btnc, __u64 blocknr)
+ goto failed;
+ }
+ memset(bh->b_data, 0, i_blocksize(inode));
+- bh->b_bdev = inode->i_sb->s_bdev;
+ bh->b_blocknr = blocknr;
+ set_buffer_mapped(bh);
+ set_buffer_uptodate(bh);
+@@ -133,7 +132,6 @@ int nilfs_btnode_submit_block(struct address_space *btnc, __u64 blocknr,
+ goto found;
+ }
+ set_buffer_mapped(bh);
+- bh->b_bdev = inode->i_sb->s_bdev;
+ bh->b_blocknr = pblocknr; /* set block address for read */
+ bh->b_end_io = end_buffer_read_sync;
+ get_bh(bh);
+diff --git a/fs/nilfs2/gcinode.c b/fs/nilfs2/gcinode.c
+index 1c9ae36a03abe9..ace22253fed0f2 100644
+--- a/fs/nilfs2/gcinode.c
++++ b/fs/nilfs2/gcinode.c
+@@ -83,10 +83,8 @@ int nilfs_gccache_submit_read_data(struct inode *inode, sector_t blkoff,
+ goto out;
+ }
+
+- if (!buffer_mapped(bh)) {
+- bh->b_bdev = inode->i_sb->s_bdev;
++ if (!buffer_mapped(bh))
+ set_buffer_mapped(bh);
+- }
+ bh->b_blocknr = pbn;
+ bh->b_end_io = end_buffer_read_sync;
+ get_bh(bh);
+diff --git a/fs/nilfs2/mdt.c b/fs/nilfs2/mdt.c
+index 4f792a0ad0f0ff..8e66f2c13ad658 100644
+--- a/fs/nilfs2/mdt.c
++++ b/fs/nilfs2/mdt.c
+@@ -89,7 +89,6 @@ static int nilfs_mdt_create_block(struct inode *inode, unsigned long block,
+ if (buffer_uptodate(bh))
+ goto failed_bh;
+
+- bh->b_bdev = sb->s_bdev;
+ err = nilfs_mdt_insert_new_block(inode, block, bh, init_block);
+ if (likely(!err)) {
+ get_bh(bh);
+diff --git a/fs/nilfs2/page.c b/fs/nilfs2/page.c
+index 097e2c7f7f718c..d30114a713608d 100644
+--- a/fs/nilfs2/page.c
++++ b/fs/nilfs2/page.c
+@@ -39,7 +39,6 @@ static struct buffer_head *__nilfs_get_folio_block(struct folio *folio,
+ first_block = (unsigned long)index << (PAGE_SHIFT - blkbits);
+ bh = get_nth_bh(bh, block - first_block);
+
+- touch_buffer(bh);
+ wait_on_buffer(bh);
+ return bh;
+ }
+@@ -64,6 +63,7 @@ struct buffer_head *nilfs_grab_buffer(struct inode *inode,
+ folio_put(folio);
+ return NULL;
+ }
++ bh->b_bdev = inode->i_sb->s_bdev;
+ return bh;
+ }
+
+diff --git a/fs/ocfs2/resize.c b/fs/ocfs2/resize.c
+index c4a4016d3866a3..b0733c08ed13b1 100644
+--- a/fs/ocfs2/resize.c
++++ b/fs/ocfs2/resize.c
+@@ -574,6 +574,8 @@ int ocfs2_group_add(struct inode *inode, struct ocfs2_new_group_input *input)
+ ocfs2_commit_trans(osb, handle);
+
+ out_free_group_bh:
++ if (ret < 0)
++ ocfs2_remove_from_cache(INODE_CACHE(inode), group_bh);
+ brelse(group_bh);
+
+ out_unlock:
+diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c
+index afee70125ae3bf..ded6d0b3e02336 100644
+--- a/fs/ocfs2/super.c
++++ b/fs/ocfs2/super.c
+@@ -2321,6 +2321,7 @@ static int ocfs2_verify_volume(struct ocfs2_dinode *di,
+ struct ocfs2_blockcheck_stats *stats)
+ {
+ int status = -EAGAIN;
++ u32 blksz_bits;
+
+ if (memcmp(di->i_signature, OCFS2_SUPER_BLOCK_SIGNATURE,
+ strlen(OCFS2_SUPER_BLOCK_SIGNATURE)) == 0) {
+@@ -2335,11 +2336,15 @@ static int ocfs2_verify_volume(struct ocfs2_dinode *di,
+ goto out;
+ }
+ status = -EINVAL;
+- if ((1 << le32_to_cpu(di->id2.i_super.s_blocksize_bits)) != blksz) {
++ /* Acceptable block sizes are 512 bytes, 1K, 2K and 4K. */
++ blksz_bits = le32_to_cpu(di->id2.i_super.s_blocksize_bits);
++ if (blksz_bits < 9 || blksz_bits > 12) {
+ mlog(ML_ERROR, "found superblock with incorrect block "
+- "size: found %u, should be %u\n",
+- 1 << le32_to_cpu(di->id2.i_super.s_blocksize_bits),
+- blksz);
++ "size bits: found %u, should be 9, 10, 11, or 12\n",
++ blksz_bits);
++ } else if ((1 << le32_to_cpu(blksz_bits)) != blksz) {
++ mlog(ML_ERROR, "found superblock with incorrect block "
++ "size: found %u, should be %u\n", 1 << blksz_bits, blksz);
+ } else if (le16_to_cpu(di->id2.i_super.s_major_rev_level) !=
+ OCFS2_MAJOR_REV_LEVEL ||
+ le16_to_cpu(di->id2.i_super.s_minor_rev_level) !=
+diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
+index 5f171ad7b436be..164247e724dcdf 100644
+--- a/fs/proc/task_mmu.c
++++ b/fs/proc/task_mmu.c
+@@ -2672,8 +2672,10 @@ static int pagemap_scan_get_args(struct pm_scan_arg *arg,
+ return -EFAULT;
+ if (!arg->vec && arg->vec_len)
+ return -EINVAL;
++ if (UINT_MAX == SIZE_MAX && arg->vec_len > SIZE_MAX)
++ return -EINVAL;
+ if (arg->vec && !access_ok((void __user *)(long)arg->vec,
+- arg->vec_len * sizeof(struct page_region)))
++ size_mul(arg->vec_len, sizeof(struct page_region))))
+ return -EFAULT;
+
+ /* Fixup default values */
+diff --git a/include/drm/intel/i915_pciids.h b/include/drm/intel/i915_pciids.h
+index 2bf03ebfcf73da..f35534522d3338 100644
+--- a/include/drm/intel/i915_pciids.h
++++ b/include/drm/intel/i915_pciids.h
+@@ -771,13 +771,24 @@
+ INTEL_ATS_M150_IDS(MACRO__, ## __VA_ARGS__), \
+ INTEL_ATS_M75_IDS(MACRO__, ## __VA_ARGS__)
+
+-/* MTL */
+-#define INTEL_ARL_IDS(MACRO__, ...) \
+- MACRO__(0x7D41, ## __VA_ARGS__), \
++/* ARL */
++#define INTEL_ARL_H_IDS(MACRO__, ...) \
+ MACRO__(0x7D51, ## __VA_ARGS__), \
+- MACRO__(0x7D67, ## __VA_ARGS__), \
+ MACRO__(0x7DD1, ## __VA_ARGS__)
+
++#define INTEL_ARL_U_IDS(MACRO__, ...) \
++ MACRO__(0x7D41, ## __VA_ARGS__) \
++
++#define INTEL_ARL_S_IDS(MACRO__, ...) \
++ MACRO__(0x7D67, ## __VA_ARGS__), \
++ MACRO__(0xB640, ## __VA_ARGS__)
++
++#define INTEL_ARL_IDS(MACRO__, ...) \
++ INTEL_ARL_H_IDS(MACRO__, ## __VA_ARGS__), \
++ INTEL_ARL_U_IDS(MACRO__, ## __VA_ARGS__), \
++ INTEL_ARL_S_IDS(MACRO__, ## __VA_ARGS__)
++
++/* MTL */
+ #define INTEL_MTL_IDS(MACRO__, ...) \
+ INTEL_ARL_IDS(MACRO__, ## __VA_ARGS__), \
+ MACRO__(0x7D40, ## __VA_ARGS__), \
+diff --git a/include/linux/mman.h b/include/linux/mman.h
+index bcb201ab7a412e..c2748703431558 100644
+--- a/include/linux/mman.h
++++ b/include/linux/mman.h
+@@ -2,6 +2,7 @@
+ #ifndef _LINUX_MMAN_H
+ #define _LINUX_MMAN_H
+
++#include <linux/fs.h>
+ #include <linux/mm.h>
+ #include <linux/percpu_counter.h>
+
+@@ -94,7 +95,7 @@ static inline void vm_unacct_memory(long pages)
+ #endif
+
+ #ifndef arch_calc_vm_flag_bits
+-#define arch_calc_vm_flag_bits(flags) 0
++#define arch_calc_vm_flag_bits(file, flags) 0
+ #endif
+
+ #ifndef arch_validate_prot
+@@ -151,13 +152,13 @@ calc_vm_prot_bits(unsigned long prot, unsigned long pkey)
+ * Combine the mmap "flags" argument into "vm_flags" used internally.
+ */
+ static inline unsigned long
+-calc_vm_flag_bits(unsigned long flags)
++calc_vm_flag_bits(struct file *file, unsigned long flags)
+ {
+ return _calc_vm_trans(flags, MAP_GROWSDOWN, VM_GROWSDOWN ) |
+ _calc_vm_trans(flags, MAP_LOCKED, VM_LOCKED ) |
+ _calc_vm_trans(flags, MAP_SYNC, VM_SYNC ) |
+ _calc_vm_trans(flags, MAP_STACK, VM_NOHUGEPAGE) |
+- arch_calc_vm_flag_bits(flags);
++ arch_calc_vm_flag_bits(file, flags);
+ }
+
+ unsigned long vm_commit_limit(void);
+diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h
+index 858c8e7851fb5d..f63faa12bba0f7 100644
+--- a/include/linux/pm_domain.h
++++ b/include/linux/pm_domain.h
+@@ -92,6 +92,10 @@ struct dev_pm_domain_list {
+ * GENPD_FLAG_OPP_TABLE_FW: The genpd provider supports performance states,
+ * but its corresponding OPP tables are not
+ * described in DT, but are given directly by FW.
++ *
++ * GENPD_FLAG_DEV_NAME_FW: Instructs genpd to generate an unique device name
++ * using ida. It is used by genpd providers which
++ * get their genpd-names directly from FW.
+ */
+ #define GENPD_FLAG_PM_CLK (1U << 0)
+ #define GENPD_FLAG_IRQ_SAFE (1U << 1)
+@@ -101,6 +105,7 @@ struct dev_pm_domain_list {
+ #define GENPD_FLAG_RPM_ALWAYS_ON (1U << 5)
+ #define GENPD_FLAG_MIN_RESIDENCY (1U << 6)
+ #define GENPD_FLAG_OPP_TABLE_FW (1U << 7)
++#define GENPD_FLAG_DEV_NAME_FW (1U << 8)
+
+ enum gpd_status {
+ GENPD_STATE_ON = 0, /* PM domain is on */
+@@ -163,6 +168,7 @@ struct generic_pm_domain {
+ atomic_t sd_count; /* Number of subdomains with power "on" */
+ enum gpd_status status; /* Current state of the domain */
+ unsigned int device_count; /* Number of devices */
++ unsigned int device_id; /* unique device id */
+ unsigned int suspended_count; /* System suspend device counter */
+ unsigned int prepared_count; /* Suspend counter of prepared devices */
+ unsigned int performance_state; /* Aggregated max performance state */
+diff --git a/include/linux/sched/task_stack.h b/include/linux/sched/task_stack.h
+index ccd72b978e1fc7..4ac64f68dcf03f 100644
+--- a/include/linux/sched/task_stack.h
++++ b/include/linux/sched/task_stack.h
+@@ -9,6 +9,7 @@
+ #include <linux/sched.h>
+ #include <linux/magic.h>
+ #include <linux/refcount.h>
++#include <linux/kasan.h>
+
+ #ifdef CONFIG_THREAD_INFO_IN_TASK
+
+@@ -89,6 +90,7 @@ static inline int object_is_on_stack(const void *obj)
+ {
+ void *stack = task_stack_page(current);
+
++ obj = kasan_reset_tag(obj);
+ return (obj >= stack) && (obj < (stack + THREAD_SIZE));
+ }
+
+diff --git a/include/linux/sockptr.h b/include/linux/sockptr.h
+index fc5a206c40435f..195debe2b1dbc5 100644
+--- a/include/linux/sockptr.h
++++ b/include/linux/sockptr.h
+@@ -77,7 +77,9 @@ static inline int copy_safe_from_sockptr(void *dst, size_t ksize,
+ {
+ if (optlen < ksize)
+ return -EINVAL;
+- return copy_from_sockptr(dst, optval, ksize);
++ if (copy_from_sockptr(dst, optval, ksize))
++ return -EFAULT;
++ return 0;
+ }
+
+ static inline int copy_struct_from_sockptr(void *dst, size_t ksize,
+diff --git a/include/net/bond_options.h b/include/net/bond_options.h
+index 473a0147769eb9..18687ccf063830 100644
+--- a/include/net/bond_options.h
++++ b/include/net/bond_options.h
+@@ -161,5 +161,7 @@ void bond_option_arp_ip_targets_clear(struct bonding *bond);
+ #if IS_ENABLED(CONFIG_IPV6)
+ void bond_option_ns_ip6_targets_clear(struct bonding *bond);
+ #endif
++void bond_slave_ns_maddrs_add(struct bonding *bond, struct slave *slave);
++void bond_slave_ns_maddrs_del(struct bonding *bond, struct slave *slave);
+
+ #endif /* _NET_BOND_OPTIONS_H */
+diff --git a/kernel/Kconfig.kexec b/kernel/Kconfig.kexec
+index 6c34e63c88ff4c..4d111f87195167 100644
+--- a/kernel/Kconfig.kexec
++++ b/kernel/Kconfig.kexec
+@@ -97,7 +97,7 @@ config KEXEC_JUMP
+
+ config CRASH_DUMP
+ bool "kernel crash dumps"
+- default y
++ default ARCH_DEFAULT_CRASH_DUMP
+ depends on ARCH_SUPPORTS_CRASH_DUMP
+ depends on KEXEC_CORE
+ select VMCORE_INFO
+diff --git a/lib/buildid.c b/lib/buildid.c
+index 26007cc99a38f6..aee749f2647da0 100644
+--- a/lib/buildid.c
++++ b/lib/buildid.c
+@@ -40,7 +40,7 @@ static int parse_build_id_buf(unsigned char *build_id,
+ name_sz == note_name_sz &&
+ memcmp(nhdr + 1, note_name, note_name_sz) == 0 &&
+ desc_sz > 0 && desc_sz <= BUILD_ID_SIZE_MAX) {
+- data = note_start + note_off + ALIGN(note_name_sz, 4);
++ data = note_start + note_off + sizeof(Elf32_Nhdr) + ALIGN(note_name_sz, 4);
+ memcpy(build_id, data, desc_sz);
+ memset(build_id + desc_sz, 0, BUILD_ID_SIZE_MAX - desc_sz);
+ if (size)
+diff --git a/mm/mmap.c b/mm/mmap.c
+index 8a04f29aa4230d..ccebd17fb48f6f 100644
+--- a/mm/mmap.c
++++ b/mm/mmap.c
+@@ -1316,7 +1316,7 @@ unsigned long do_mmap(struct file *file, unsigned long addr,
+ * to. we assume access permissions have been handled by the open
+ * of the memory object, so we don't do any here.
+ */
+- vm_flags |= calc_vm_prot_bits(prot, pkey) | calc_vm_flag_bits(flags) |
++ vm_flags |= calc_vm_prot_bits(prot, pkey) | calc_vm_flag_bits(file, flags) |
+ mm->def_flags | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC;
+
+ /* Obtain the address to map to. we verify (or select) it and ensure
+diff --git a/mm/mremap.c b/mm/mremap.c
+index 3ca167d84c5655..ffed8584deb1a0 100644
+--- a/mm/mremap.c
++++ b/mm/mremap.c
+@@ -648,7 +648,7 @@ unsigned long move_page_tables(struct vm_area_struct *vma,
+ * Prevent negative return values when {old,new}_addr was realigned
+ * but we broke out of the above loop for the first PMD itself.
+ */
+- if (len + old_addr < old_end)
++ if (old_addr < old_end - len)
+ return 0;
+
+ return len + old_addr - old_end; /* how much done */
+diff --git a/mm/nommu.c b/mm/nommu.c
+index 7296e775e04e29..50100b909187af 100644
+--- a/mm/nommu.c
++++ b/mm/nommu.c
+@@ -568,7 +568,7 @@ static int delete_vma_from_mm(struct vm_area_struct *vma)
+ VMA_ITERATOR(vmi, vma->vm_mm, vma->vm_start);
+
+ vma_iter_config(&vmi, vma->vm_start, vma->vm_end);
+- if (vma_iter_prealloc(&vmi, vma)) {
++ if (vma_iter_prealloc(&vmi, NULL)) {
+ pr_warn("Allocation of vma tree for process %d failed\n",
+ current->pid);
+ return -ENOMEM;
+@@ -838,7 +838,7 @@ static unsigned long determine_vm_flags(struct file *file,
+ {
+ unsigned long vm_flags;
+
+- vm_flags = calc_vm_prot_bits(prot, 0) | calc_vm_flag_bits(flags);
++ vm_flags = calc_vm_prot_bits(prot, 0) | calc_vm_flag_bits(file, flags);
+
+ if (!file) {
+ /*
+diff --git a/mm/page_alloc.c b/mm/page_alloc.c
+index f9111356d1047b..2f19464db66e05 100644
+--- a/mm/page_alloc.c
++++ b/mm/page_alloc.c
+@@ -1040,6 +1040,7 @@ __always_inline bool free_pages_prepare(struct page *page,
+ bool skip_kasan_poison = should_skip_kasan_poison(page);
+ bool init = want_init_on_free();
+ bool compound = PageCompound(page);
++ struct folio *folio = page_folio(page);
+
+ VM_BUG_ON_PAGE(PageTail(page), page);
+
+@@ -1049,6 +1050,20 @@ __always_inline bool free_pages_prepare(struct page *page,
+ if (memcg_kmem_online() && PageMemcgKmem(page))
+ __memcg_kmem_uncharge_page(page, order);
+
++ /*
++ * In rare cases, when truncation or holepunching raced with
++ * munlock after VM_LOCKED was cleared, Mlocked may still be
++ * found set here. This does not indicate a problem, unless
++ * "unevictable_pgs_cleared" appears worryingly large.
++ */
++ if (unlikely(folio_test_mlocked(folio))) {
++ long nr_pages = folio_nr_pages(folio);
++
++ __folio_clear_mlocked(folio);
++ zone_stat_mod_folio(folio, NR_MLOCK, -nr_pages);
++ count_vm_events(UNEVICTABLE_PGCLEARED, nr_pages);
++ }
++
+ if (unlikely(PageHWPoison(page)) && !order) {
+ /* Do not let hwpoison pages hit pcplists/buddy */
+ reset_page_owner(page, order);
+@@ -4569,7 +4584,8 @@ unsigned long alloc_pages_bulk_noprof(gfp_t gfp, int preferred_nid,
+ gfp = alloc_gfp;
+
+ /* Find an allowed local zone that meets the low watermark. */
+- for_each_zone_zonelist_nodemask(zone, z, ac.zonelist, ac.highest_zoneidx, ac.nodemask) {
++ z = ac.preferred_zoneref;
++ for_next_zone_zonelist_nodemask(zone, z, ac.highest_zoneidx, ac.nodemask) {
+ unsigned long mark;
+
+ if (cpusets_enabled() && (alloc_flags & ALLOC_CPUSET) &&
+diff --git a/mm/shmem.c b/mm/shmem.c
+index 941d1271395202..67f2ae6a8f0f36 100644
+--- a/mm/shmem.c
++++ b/mm/shmem.c
+@@ -1163,9 +1163,7 @@ static int shmem_getattr(struct mnt_idmap *idmap,
+ stat->attributes_mask |= (STATX_ATTR_APPEND |
+ STATX_ATTR_IMMUTABLE |
+ STATX_ATTR_NODUMP);
+- inode_lock_shared(inode);
+ generic_fillattr(idmap, request_mask, inode, stat);
+- inode_unlock_shared(inode);
+
+ if (shmem_huge_global_enabled(inode, 0, false, NULL, 0))
+ stat->blksize = HPAGE_PMD_SIZE;
+@@ -2599,9 +2597,6 @@ static int shmem_mmap(struct file *file, struct vm_area_struct *vma)
+ if (ret)
+ return ret;
+
+- /* arm64 - allow memory tagging on RAM-based files */
+- vm_flags_set(vma, VM_MTE_ALLOWED);
+-
+ file_accessed(file);
+ /* This is anonymous shared memory if it is unlinked at the time of mmap */
+ if (inode->i_nlink)
+diff --git a/mm/swap.c b/mm/swap.c
+index 1e734a5a6453e2..5d1850adf76a13 100644
+--- a/mm/swap.c
++++ b/mm/swap.c
+@@ -82,20 +82,6 @@ static void __page_cache_release(struct folio *folio, struct lruvec **lruvecp,
+ lruvec_del_folio(*lruvecp, folio);
+ __folio_clear_lru_flags(folio);
+ }
+-
+- /*
+- * In rare cases, when truncation or holepunching raced with
+- * munlock after VM_LOCKED was cleared, Mlocked may still be
+- * found set here. This does not indicate a problem, unless
+- * "unevictable_pgs_cleared" appears worryingly large.
+- */
+- if (unlikely(folio_test_mlocked(folio))) {
+- long nr_pages = folio_nr_pages(folio);
+-
+- __folio_clear_mlocked(folio);
+- zone_stat_mod_folio(folio, NR_MLOCK, -nr_pages);
+- count_vm_events(UNEVICTABLE_PGCLEARED, nr_pages);
+- }
+ }
+
+ /*
+diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
+index 6e07350817bec2..eeb4f025ca3bfc 100644
+--- a/net/bluetooth/hci_core.c
++++ b/net/bluetooth/hci_core.c
+@@ -3788,8 +3788,6 @@ static void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb)
+
+ hci_dev_lock(hdev);
+ conn = hci_conn_hash_lookup_handle(hdev, handle);
+- if (conn && hci_dev_test_flag(hdev, HCI_MGMT))
+- mgmt_device_connected(hdev, conn, NULL, 0);
+ hci_dev_unlock(hdev);
+
+ if (conn) {
+diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c
+index da5dba120bc9a5..d6649246188d72 100644
+--- a/net/dccp/ipv6.c
++++ b/net/dccp/ipv6.c
+@@ -618,7 +618,7 @@ static int dccp_v6_do_rcv(struct sock *sk, struct sk_buff *skb)
+ by tcp. Feel free to propose better solution.
+ --ANK (980728)
+ */
+- if (np->rxopt.all)
++ if (np->rxopt.all && sk->sk_state != DCCP_LISTEN)
+ opt_skb = skb_clone_and_charge_r(skb, sk);
+
+ if (sk->sk_state == DCCP_OPEN) { /* Fast path */
+diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
+index 200fea92f12fc9..84cd46311da092 100644
+--- a/net/ipv6/tcp_ipv6.c
++++ b/net/ipv6/tcp_ipv6.c
+@@ -1617,7 +1617,7 @@ int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb)
+ by tcp. Feel free to propose better solution.
+ --ANK (980728)
+ */
+- if (np->rxopt.all)
++ if (np->rxopt.all && sk->sk_state != TCP_LISTEN)
+ opt_skb = skb_clone_and_charge_r(skb, sk);
+
+ if (sk->sk_state == TCP_ESTABLISHED) { /* Fast path */
+@@ -1655,8 +1655,6 @@ int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb)
+ if (reason)
+ goto reset;
+ }
+- if (opt_skb)
+- __kfree_skb(opt_skb);
+ return 0;
+ }
+ } else
+diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
+index ba99484c501ed2..a09120d2eb8075 100644
+--- a/net/mptcp/pm_netlink.c
++++ b/net/mptcp/pm_netlink.c
+@@ -520,7 +520,8 @@ __lookup_addr(struct pm_nl_pernet *pernet, const struct mptcp_addr_info *info)
+ {
+ struct mptcp_pm_addr_entry *entry;
+
+- list_for_each_entry(entry, &pernet->local_addr_list, list) {
++ list_for_each_entry_rcu(entry, &pernet->local_addr_list, list,
++ lockdep_is_held(&pernet->lock)) {
+ if (mptcp_addresses_equal(&entry->addr, info, entry->addr.port))
+ return entry;
+ }
+diff --git a/net/mptcp/pm_userspace.c b/net/mptcp/pm_userspace.c
+index 8f3b01d46d243f..0ba145188e6b09 100644
+--- a/net/mptcp/pm_userspace.c
++++ b/net/mptcp/pm_userspace.c
+@@ -325,14 +325,17 @@ int mptcp_pm_nl_remove_doit(struct sk_buff *skb, struct genl_info *info)
+
+ lock_sock(sk);
+
++ spin_lock_bh(&msk->pm.lock);
+ match = mptcp_userspace_pm_lookup_addr_by_id(msk, id_val);
+ if (!match) {
+ GENL_SET_ERR_MSG(info, "address with specified id not found");
++ spin_unlock_bh(&msk->pm.lock);
+ release_sock(sk);
+ goto out;
+ }
+
+ list_move(&match->list, &free_list);
++ spin_unlock_bh(&msk->pm.lock);
+
+ mptcp_pm_remove_addrs(msk, &free_list);
+
+@@ -574,6 +577,7 @@ int mptcp_userspace_pm_set_flags(struct sk_buff *skb, struct genl_info *info)
+ struct nlattr *token = info->attrs[MPTCP_PM_ATTR_TOKEN];
+ struct nlattr *attr = info->attrs[MPTCP_PM_ATTR_ADDR];
+ struct net *net = sock_net(skb->sk);
++ struct mptcp_pm_addr_entry *entry;
+ struct mptcp_sock *msk;
+ int ret = -EINVAL;
+ struct sock *sk;
+@@ -615,6 +619,17 @@ int mptcp_userspace_pm_set_flags(struct sk_buff *skb, struct genl_info *info)
+ if (loc.flags & MPTCP_PM_ADDR_FLAG_BACKUP)
+ bkup = 1;
+
++ spin_lock_bh(&msk->pm.lock);
++ list_for_each_entry(entry, &msk->pm.userspace_pm_local_addr_list, list) {
++ if (mptcp_addresses_equal(&entry->addr, &loc.addr, false)) {
++ if (bkup)
++ entry->flags |= MPTCP_PM_ADDR_FLAG_BACKUP;
++ else
++ entry->flags &= ~MPTCP_PM_ADDR_FLAG_BACKUP;
++ }
++ }
++ spin_unlock_bh(&msk->pm.lock);
++
+ lock_sock(sk);
+ ret = mptcp_pm_nl_mp_prio_send_ack(msk, &loc.addr, &rem.addr, bkup);
+ release_sock(sk);
+diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
+index ec87b36f0d451a..7913ba6b5daa38 100644
+--- a/net/mptcp/protocol.c
++++ b/net/mptcp/protocol.c
+@@ -2082,7 +2082,8 @@ static void mptcp_rcv_space_adjust(struct mptcp_sock *msk, int copied)
+ slow = lock_sock_fast(ssk);
+ WRITE_ONCE(ssk->sk_rcvbuf, rcvbuf);
+ WRITE_ONCE(tcp_sk(ssk)->window_clamp, window_clamp);
+- tcp_cleanup_rbuf(ssk, 1);
++ if (tcp_can_send_ack(ssk))
++ tcp_cleanup_rbuf(ssk, 1);
+ unlock_sock_fast(ssk, slow);
+ }
+ }
+@@ -2205,7 +2206,7 @@ static int mptcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
+ cmsg_flags = MPTCP_CMSG_INQ;
+
+ while (copied < len) {
+- int bytes_read;
++ int err, bytes_read;
+
+ bytes_read = __mptcp_recvmsg_mskq(msk, msg, len - copied, flags, &tss, &cmsg_flags);
+ if (unlikely(bytes_read < 0)) {
+@@ -2267,9 +2268,16 @@ static int mptcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
+ }
+
+ pr_debug("block timeout %ld\n", timeo);
+- sk_wait_data(sk, &timeo, NULL);
++ mptcp_rcv_space_adjust(msk, copied);
++ err = sk_wait_data(sk, &timeo, NULL);
++ if (err < 0) {
++ err = copied ? : err;
++ goto out_err;
++ }
+ }
+
++ mptcp_rcv_space_adjust(msk, copied);
++
+ out_err:
+ if (cmsg_flags && copied >= 0) {
+ if (cmsg_flags & MPTCP_CMSG_TS)
+@@ -2285,8 +2293,6 @@ static int mptcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
+ pr_debug("msk=%p rx queue empty=%d:%d copied=%d\n",
+ msk, skb_queue_empty_lockless(&sk->sk_receive_queue),
+ skb_queue_empty(&msk->receive_queue), copied);
+- if (!(flags & MSG_PEEK))
+- mptcp_rcv_space_adjust(msk, copied);
+
+ release_sock(sk);
+ return copied;
+diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
+index 0a9287fadb47a2..f84aad420d4464 100644
+--- a/net/netlink/af_netlink.c
++++ b/net/netlink/af_netlink.c
+@@ -393,15 +393,6 @@ static void netlink_skb_set_owner_r(struct sk_buff *skb, struct sock *sk)
+
+ static void netlink_sock_destruct(struct sock *sk)
+ {
+- struct netlink_sock *nlk = nlk_sk(sk);
+-
+- if (nlk->cb_running) {
+- if (nlk->cb.done)
+- nlk->cb.done(&nlk->cb);
+- module_put(nlk->cb.module);
+- kfree_skb(nlk->cb.skb);
+- }
+-
+ skb_queue_purge(&sk->sk_receive_queue);
+
+ if (!sock_flag(sk, SOCK_DEAD)) {
+@@ -414,14 +405,6 @@ static void netlink_sock_destruct(struct sock *sk)
+ WARN_ON(nlk_sk(sk)->groups);
+ }
+
+-static void netlink_sock_destruct_work(struct work_struct *work)
+-{
+- struct netlink_sock *nlk = container_of(work, struct netlink_sock,
+- work);
+-
+- sk_free(&nlk->sk);
+-}
+-
+ /* This lock without WQ_FLAG_EXCLUSIVE is good on UP and it is _very_ bad on
+ * SMP. Look, when several writers sleep and reader wakes them up, all but one
+ * immediately hit write lock and grab all the cpus. Exclusive sleep solves
+@@ -731,12 +714,6 @@ static void deferred_put_nlk_sk(struct rcu_head *head)
+ if (!refcount_dec_and_test(&sk->sk_refcnt))
+ return;
+
+- if (nlk->cb_running && nlk->cb.done) {
+- INIT_WORK(&nlk->work, netlink_sock_destruct_work);
+- schedule_work(&nlk->work);
+- return;
+- }
+-
+ sk_free(sk);
+ }
+
+@@ -788,6 +765,14 @@ static int netlink_release(struct socket *sock)
+ NETLINK_URELEASE, &n);
+ }
+
++ /* Terminate any outstanding dump */
++ if (nlk->cb_running) {
++ if (nlk->cb.done)
++ nlk->cb.done(&nlk->cb);
++ module_put(nlk->cb.module);
++ kfree_skb(nlk->cb.skb);
++ }
++
+ module_put(nlk->module);
+
+ if (netlink_is_kernel(sk)) {
+diff --git a/net/netlink/af_netlink.h b/net/netlink/af_netlink.h
+index 9751e29d4bbb9a..b1a17c0d97a103 100644
+--- a/net/netlink/af_netlink.h
++++ b/net/netlink/af_netlink.h
+@@ -4,7 +4,6 @@
+
+ #include <linux/rhashtable.h>
+ #include <linux/atomic.h>
+-#include <linux/workqueue.h>
+ #include <net/sock.h>
+
+ /* flags */
+@@ -51,7 +50,6 @@ struct netlink_sock {
+
+ struct rhash_head node;
+ struct rcu_head rcu;
+- struct work_struct work;
+ };
+
+ static inline struct netlink_sock *nlk_sk(struct sock *sk)
+diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c
+index 9412d88a99bc12..d3a03c57545bcc 100644
+--- a/net/sched/cls_u32.c
++++ b/net/sched/cls_u32.c
+@@ -92,6 +92,16 @@ struct tc_u_common {
+ long knodes;
+ };
+
++static u32 handle2id(u32 h)
++{
++ return ((h & 0x80000000) ? ((h >> 20) & 0x7FF) : h);
++}
++
++static u32 id2handle(u32 id)
++{
++ return (id | 0x800U) << 20;
++}
++
+ static inline unsigned int u32_hash_fold(__be32 key,
+ const struct tc_u32_sel *sel,
+ u8 fshift)
+@@ -310,7 +320,7 @@ static u32 gen_new_htid(struct tc_u_common *tp_c, struct tc_u_hnode *ptr)
+ int id = idr_alloc_cyclic(&tp_c->handle_idr, ptr, 1, 0x7FF, GFP_KERNEL);
+ if (id < 0)
+ return 0;
+- return (id | 0x800U) << 20;
++ return id2handle(id);
+ }
+
+ static struct hlist_head *tc_u_common_hash;
+@@ -360,7 +370,7 @@ static int u32_init(struct tcf_proto *tp)
+ return -ENOBUFS;
+
+ refcount_set(&root_ht->refcnt, 1);
+- root_ht->handle = tp_c ? gen_new_htid(tp_c, root_ht) : 0x80000000;
++ root_ht->handle = tp_c ? gen_new_htid(tp_c, root_ht) : id2handle(0);
+ root_ht->prio = tp->prio;
+ root_ht->is_root = true;
+ idr_init(&root_ht->handle_idr);
+@@ -612,7 +622,7 @@ static int u32_destroy_hnode(struct tcf_proto *tp, struct tc_u_hnode *ht,
+ if (phn == ht) {
+ u32_clear_hw_hnode(tp, ht, extack);
+ idr_destroy(&ht->handle_idr);
+- idr_remove(&tp_c->handle_idr, ht->handle);
++ idr_remove(&tp_c->handle_idr, handle2id(ht->handle));
+ RCU_INIT_POINTER(*hn, ht->next);
+ kfree_rcu(ht, rcu);
+ return 0;
+@@ -989,7 +999,7 @@ static int u32_change(struct net *net, struct sk_buff *in_skb,
+
+ err = u32_replace_hw_hnode(tp, ht, userflags, extack);
+ if (err) {
+- idr_remove(&tp_c->handle_idr, handle);
++ idr_remove(&tp_c->handle_idr, handle2id(handle));
+ kfree(ht);
+ return err;
+ }
+diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
+index f7b809c0d142c0..38e2fbdcbeac4b 100644
+--- a/net/sctp/ipv6.c
++++ b/net/sctp/ipv6.c
+@@ -683,7 +683,7 @@ static int sctp_v6_available(union sctp_addr *addr, struct sctp_sock *sp)
+ struct sock *sk = &sp->inet.sk;
+ struct net *net = sock_net(sk);
+ struct net_device *dev = NULL;
+- int type;
++ int type, res, bound_dev_if;
+
+ type = ipv6_addr_type(in6);
+ if (IPV6_ADDR_ANY == type)
+@@ -697,14 +697,21 @@ static int sctp_v6_available(union sctp_addr *addr, struct sctp_sock *sp)
+ if (!(type & IPV6_ADDR_UNICAST))
+ return 0;
+
+- if (sk->sk_bound_dev_if) {
+- dev = dev_get_by_index_rcu(net, sk->sk_bound_dev_if);
++ rcu_read_lock();
++ bound_dev_if = READ_ONCE(sk->sk_bound_dev_if);
++ if (bound_dev_if) {
++ res = 0;
++ dev = dev_get_by_index_rcu(net, bound_dev_if);
+ if (!dev)
+- return 0;
++ goto out;
+ }
+
+- return ipv6_can_nonlocal_bind(net, &sp->inet) ||
+- ipv6_chk_addr(net, in6, dev, 0);
++ res = ipv6_can_nonlocal_bind(net, &sp->inet) ||
++ ipv6_chk_addr(net, in6, dev, 0);
++
++out:
++ rcu_read_unlock();
++ return res;
+ }
+
+ /* This function checks if the address is a valid address to be used for
+diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c
+index 0ff9b2dd86bac2..a0202d9b479217 100644
+--- a/net/vmw_vsock/af_vsock.c
++++ b/net/vmw_vsock/af_vsock.c
+@@ -835,6 +835,9 @@ static void vsock_sk_destruct(struct sock *sk)
+ {
+ struct vsock_sock *vsk = vsock_sk(sk);
+
++ /* Flush MSG_ZEROCOPY leftovers. */
++ __skb_queue_purge(&sk->sk_error_queue);
++
+ vsock_deassign_transport(vsk);
+
+ /* When clearing these addresses, there's no need to set the family and
+diff --git a/net/vmw_vsock/virtio_transport_common.c b/net/vmw_vsock/virtio_transport_common.c
+index 01b6b1ed5acfb8..0211964e45459d 100644
+--- a/net/vmw_vsock/virtio_transport_common.c
++++ b/net/vmw_vsock/virtio_transport_common.c
+@@ -400,6 +400,7 @@ static int virtio_transport_send_pkt_info(struct vsock_sock *vsk,
+ if (virtio_transport_init_zcopy_skb(vsk, skb,
+ info->msg,
+ can_zcopy)) {
++ kfree_skb(skb);
+ ret = -ENOMEM;
+ break;
+ }
+@@ -1478,6 +1479,14 @@ virtio_transport_recv_listen(struct sock *sk, struct sk_buff *skb,
+ return -ENOMEM;
+ }
+
++ /* __vsock_release() might have already flushed accept_queue.
++ * Subsequent enqueues would lead to a memory leak.
++ */
++ if (sk->sk_shutdown == SHUTDOWN_MASK) {
++ virtio_transport_reset_no_sock(t, skb);
++ return -ESHUTDOWN;
++ }
++
+ child = vsock_create_connected(sk);
+ if (!child) {
+ virtio_transport_reset_no_sock(t, skb);
+diff --git a/samples/pktgen/pktgen_sample01_simple.sh b/samples/pktgen/pktgen_sample01_simple.sh
+index cdb9f497f87da7..66cb707479e6c5 100755
+--- a/samples/pktgen/pktgen_sample01_simple.sh
++++ b/samples/pktgen/pktgen_sample01_simple.sh
+@@ -76,7 +76,7 @@ if [ -n "$DST_PORT" ]; then
+ pg_set $DEV "udp_dst_max $UDP_DST_MAX"
+ fi
+
+-[ ! -z "$UDP_CSUM" ] && pg_set $dev "flag UDPCSUM"
++[ ! -z "$UDP_CSUM" ] && pg_set $DEV "flag UDPCSUM"
+
+ # Setup random UDP port src range
+ pg_set $DEV "flag UDPSRC_RND"
+diff --git a/security/integrity/evm/evm_main.c b/security/integrity/evm/evm_main.c
+index 62fe66dd53ce5a..309630f319e2d6 100644
+--- a/security/integrity/evm/evm_main.c
++++ b/security/integrity/evm/evm_main.c
+@@ -1084,7 +1084,8 @@ static void evm_file_release(struct file *file)
+ if (!S_ISREG(inode->i_mode) || !(mode & FMODE_WRITE))
+ return;
+
+- if (iint && atomic_read(&inode->i_writecount) == 1)
++ if (iint && iint->flags & EVM_NEW_FILE &&
++ atomic_read(&inode->i_writecount) == 1)
+ iint->flags &= ~EVM_NEW_FILE;
+ }
+
+diff --git a/security/integrity/ima/ima_template_lib.c b/security/integrity/ima/ima_template_lib.c
+index 4183956c53af49..0e627eac9c33bb 100644
+--- a/security/integrity/ima/ima_template_lib.c
++++ b/security/integrity/ima/ima_template_lib.c
+@@ -318,15 +318,21 @@ static int ima_eventdigest_init_common(const u8 *digest, u32 digestsize,
+ hash_algo_name[hash_algo]);
+ }
+
+- if (digest)
++ if (digest) {
+ memcpy(buffer + offset, digest, digestsize);
+- else
++ } else {
+ /*
+ * If digest is NULL, the event being recorded is a violation.
+ * Make room for the digest by increasing the offset by the
+- * hash algorithm digest size.
++ * hash algorithm digest size. If the hash algorithm is not
++ * specified increase the offset by IMA_DIGEST_SIZE which
++ * fits SHA1 or MD5
+ */
+- offset += hash_digest_size[hash_algo];
++ if (hash_algo < HASH_ALGO__LAST)
++ offset += hash_digest_size[hash_algo];
++ else
++ offset += IMA_DIGEST_SIZE;
++ }
+
+ return ima_write_template_field_data(buffer, offset + digestsize,
+ fmt, field_data);
+diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
+index d1d39f4cc94256..833635aaee1d02 100644
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -7436,7 +7436,6 @@ static void alc287_alc1318_playback_pcm_hook(struct hda_pcm_stream *hinfo,
+ struct snd_pcm_substream *substream,
+ int action)
+ {
+- alc_write_coef_idx(codec, 0x10, 0x8806); /* Change MLK to GPIO3 */
+ switch (action) {
+ case HDA_GEN_PCM_ACT_OPEN:
+ alc_write_coefex_idx(codec, 0x5a, 0x00, 0x954f); /* write gpio3 to high */
+@@ -7450,7 +7449,6 @@ static void alc287_alc1318_playback_pcm_hook(struct hda_pcm_stream *hinfo,
+ static void alc287_s4_power_gpio3_default(struct hda_codec *codec)
+ {
+ if (is_s4_suspend(codec)) {
+- alc_write_coef_idx(codec, 0x10, 0x8806); /* Change MLK to GPIO3 */
+ alc_write_coefex_idx(codec, 0x5a, 0x00, 0x554f); /* write gpio3 as default value */
+ }
+ }
+@@ -7459,9 +7457,17 @@ static void alc287_fixup_lenovo_thinkpad_with_alc1318(struct hda_codec *codec,
+ const struct hda_fixup *fix, int action)
+ {
+ struct alc_spec *spec = codec->spec;
++ static const struct coef_fw coefs[] = {
++ WRITE_COEF(0x24, 0x0013), WRITE_COEF(0x25, 0x0000), WRITE_COEF(0x26, 0xC300),
++ WRITE_COEF(0x28, 0x0001), WRITE_COEF(0x29, 0xb023),
++ WRITE_COEF(0x24, 0x0013), WRITE_COEF(0x25, 0x0000), WRITE_COEF(0x26, 0xC301),
++ WRITE_COEF(0x28, 0x0001), WRITE_COEF(0x29, 0xb023),
++ };
+
+ if (action != HDA_FIXUP_ACT_PRE_PROBE)
+ return;
++ alc_update_coef_idx(codec, 0x10, 1<<11, 1<<11);
++ alc_process_coef_fw(codec, coefs);
+ spec->power_hook = alc287_s4_power_gpio3_default;
+ spec->gen.pcm_playback_hook = alc287_alc1318_playback_pcm_hook;
+ }
+@@ -10477,6 +10483,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
+ SND_PCI_QUIRK(0x103c, 0x8b59, "HP Elite mt645 G7 Mobile Thin Client U89", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF),
+ SND_PCI_QUIRK(0x103c, 0x8b5d, "HP", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF),
+ SND_PCI_QUIRK(0x103c, 0x8b5e, "HP", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF),
++ SND_PCI_QUIRK(0x103c, 0x8b5f, "HP", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF),
+ SND_PCI_QUIRK(0x103c, 0x8b63, "HP Elite Dragonfly 13.5 inch G4", ALC245_FIXUP_CS35L41_SPI_4_HP_GPIO_LED),
+ SND_PCI_QUIRK(0x103c, 0x8b65, "HP ProBook 455 15.6 inch G10 Notebook PC", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF),
+ SND_PCI_QUIRK(0x103c, 0x8b66, "HP", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF),
+@@ -11664,6 +11671,8 @@ static const struct snd_hda_pin_quirk alc269_fallback_pin_fixup_tbl[] = {
+ {0x1a, 0x40000000}),
+ SND_HDA_PIN_QUIRK(0x10ec0256, 0x1043, "ASUS", ALC2XX_FIXUP_HEADSET_MIC,
+ {0x19, 0x40000000}),
++ SND_HDA_PIN_QUIRK(0x10ec0255, 0x1558, "Clevo", ALC2XX_FIXUP_HEADSET_MIC,
++ {0x19, 0x40000000}),
+ {}
+ };
+
+diff --git a/tools/mm/page-types.c b/tools/mm/page-types.c
+index 2a4ca4dd2da80a..69f00eab1b8c7d 100644
+--- a/tools/mm/page-types.c
++++ b/tools/mm/page-types.c
+@@ -421,7 +421,7 @@ static void show_page(unsigned long voffset, unsigned long offset,
+ if (opt_file)
+ printf("%lx\t", voffset);
+ if (opt_list_cgroup)
+- printf("@%" PRIu64 "\t", cgroup)
++ printf("@%" PRIu64 "\t", cgroup);
+ if (opt_list_mapcnt)
+ printf("%" PRIu64 "\t", mapcnt);
+
+diff --git a/tools/testing/selftests/kvm/Makefile b/tools/testing/selftests/kvm/Makefile
+index 48d32c5aa3eb71..a6f92129bb02f3 100644
+--- a/tools/testing/selftests/kvm/Makefile
++++ b/tools/testing/selftests/kvm/Makefile
+@@ -235,10 +235,10 @@ CFLAGS += -Wall -Wstrict-prototypes -Wuninitialized -O2 -g -std=gnu99 \
+ -Wno-gnu-variable-sized-type-not-at-end -MD -MP -DCONFIG_64BIT \
+ -fno-builtin-memcmp -fno-builtin-memcpy \
+ -fno-builtin-memset -fno-builtin-strnlen \
+- -fno-stack-protector -fno-PIE -I$(LINUX_TOOL_INCLUDE) \
+- -I$(LINUX_TOOL_ARCH_INCLUDE) -I$(LINUX_HDR_PATH) -Iinclude \
+- -I$(<D) -Iinclude/$(ARCH_DIR) -I ../rseq -I.. $(EXTRA_CFLAGS) \
+- $(KHDR_INCLUDES)
++ -fno-stack-protector -fno-PIE -fno-strict-aliasing \
++ -I$(LINUX_TOOL_INCLUDE) -I$(LINUX_TOOL_ARCH_INCLUDE) \
++ -I$(LINUX_HDR_PATH) -Iinclude -I$(<D) -Iinclude/$(ARCH_DIR) \
++ -I ../rseq -I.. $(EXTRA_CFLAGS) $(KHDR_INCLUDES)
+ ifeq ($(ARCH),s390)
+ CFLAGS += -march=z10
+ endif
+diff --git a/tools/testing/selftests/mm/hugetlb_dio.c b/tools/testing/selftests/mm/hugetlb_dio.c
+index 60001c142ce998..432d5af15e66b7 100644
+--- a/tools/testing/selftests/mm/hugetlb_dio.c
++++ b/tools/testing/selftests/mm/hugetlb_dio.c
+@@ -44,6 +44,13 @@ void run_dio_using_hugetlb(unsigned int start_off, unsigned int end_off)
+ if (fd < 0)
+ ksft_exit_fail_perror("Error opening file\n");
+
++ /* Get the free huge pages before allocation */
++ free_hpage_b = get_free_hugepages();
++ if (free_hpage_b == 0) {
++ close(fd);
++ ksft_exit_skip("No free hugepage, exiting!\n");
++ }
++
+ /* Allocate a hugetlb page */
+ orig_buffer = mmap(NULL, h_pagesize, mmap_prot, mmap_flags, -1, 0);
+ if (orig_buffer == MAP_FAILED) {
+diff --git a/tools/testing/selftests/tc-testing/tc-tests/filters/u32.json b/tools/testing/selftests/tc-testing/tc-tests/filters/u32.json
+index 24bd0c2a3014cf..b2ca9d4e991bdf 100644
+--- a/tools/testing/selftests/tc-testing/tc-tests/filters/u32.json
++++ b/tools/testing/selftests/tc-testing/tc-tests/filters/u32.json
+@@ -329,5 +329,29 @@
+ "teardown": [
+ "$TC qdisc del dev $DEV1 parent root drr"
+ ]
++ },
++ {
++ "id": "1234",
++ "name": "Exercise IDR leaks by creating/deleting a filter many (2048) times",
++ "category": [
++ "filter",
++ "u32"
++ ],
++ "plugins": {
++ "requires": "nsPlugin"
++ },
++ "setup": [
++ "$TC qdisc add dev $DEV1 parent root handle 10: drr",
++ "$TC filter add dev $DEV1 parent 10:0 protocol ip prio 2 u32 match ip src 0.0.0.2/32 action drop",
++ "$TC filter add dev $DEV1 parent 10:0 protocol ip prio 3 u32 match ip src 0.0.0.3/32 action drop"
++ ],
++ "cmdUnderTest": "bash -c 'for i in {1..2048} ;do echo filter delete dev $DEV1 pref 3;echo filter add dev $DEV1 parent 10:0 protocol ip prio 3 u32 match ip src 0.0.0.3/32 action drop;done | $TC -b -'",
++ "expExitCode": "0",
++ "verifyCmd": "$TC filter show dev $DEV1",
++ "matchPattern": "protocol ip pref 3 u32",
++ "matchCount": "3",
++ "teardown": [
++ "$TC qdisc del dev $DEV1 parent root drr"
++ ]
+ }
+ ]
next reply other threads:[~2024-11-22 17:46 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-11-22 17:46 Mike Pagano [this message]
-- strict thread matches above, loose matches on Subject: below --
2024-12-05 14:07 [gentoo-commits] proj/linux-patches:6.11 commit in: / Mike Pagano
2024-11-22 17:54 Mike Pagano
2024-11-21 18:02 Mike Pagano
2024-11-19 18:42 Mike Pagano
2024-11-17 18:15 Mike Pagano
2024-11-14 14:53 Mike Pagano
2024-11-14 13:49 Mike Pagano
2024-11-13 19:54 Mike Pagano
2024-11-08 16:29 Mike Pagano
2024-11-04 20:27 Mike Pagano
2024-11-03 11:29 Mike Pagano
2024-11-01 11:54 Mike Pagano
2024-11-01 11:26 Mike Pagano
2024-10-27 13:40 Mike Pagano
2024-10-25 11:42 Mike Pagano
2024-10-22 16:56 Mike Pagano
2024-10-21 13:35 Mike Pagano
2024-10-17 14:31 Mike Pagano
2024-10-17 14:04 Mike Pagano
2024-10-10 11:34 Mike Pagano
2024-10-04 22:53 Mike Pagano
2024-10-04 15:21 Mike Pagano
2024-09-30 16:02 Mike Pagano
2024-09-21 15:21 Mike Pagano
2024-09-15 19:09 Mike Pagano
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1732297578.80fc1f5354a1d26cad5e58fd20b089999eef1cc7.mpagano@gentoo \
--to=mpagano@gentoo.org \
--cc=gentoo-commits@lists.gentoo.org \
--cc=gentoo-dev@lists.gentoo.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox