summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlice Ferrazzi <alicef@gentoo.org>2022-12-08 20:37:53 +0900
committerAlice Ferrazzi <alicef@gentoo.org>2022-12-08 20:38:02 +0900
commita50c38236ed2bbbe1fd3b03fa28959329ea054c6 (patch)
treee73dfd140922b354fe6af7663a568f3c56c1cb84
parentnetfilter: ctnetlink fix compl. warning after data race fixes in ct mark (diff)
downloadlinux-patches-a50c38236ed2bbbe1fd3b03fa28959329ea054c6.tar.gz
linux-patches-a50c38236ed2bbbe1fd3b03fa28959329ea054c6.tar.bz2
linux-patches-a50c38236ed2bbbe1fd3b03fa28959329ea054c6.zip
Linux patch 6.0.126.0-12
Signed-off-by: Alice Ferrazzi <alicef@gentoo.org>
-rw-r--r--0000_README4
-rw-r--r--1011_linux-6.0.12.patch4938
2 files changed, 4942 insertions, 0 deletions
diff --git a/0000_README b/0000_README
index 52214e7a..37d6ef5a 100644
--- a/0000_README
+++ b/0000_README
@@ -87,6 +87,10 @@ Patch: 1010_linux-6.0.11.patch
From: http://www.kernel.org
Desc: Linux 6.0.11
+Patch: 1011_linux-6.0.12.patch
+From: http://www.kernel.org
+Desc: Linux 6.0.12
+
Patch: 1500_XATTR_USER_PREFIX.patch
From: https://bugs.gentoo.org/show_bug.cgi?id=470644
Desc: Support for namespace user.pax.* on tmpfs.
diff --git a/1011_linux-6.0.12.patch b/1011_linux-6.0.12.patch
new file mode 100644
index 00000000..9bfea012
--- /dev/null
+++ b/1011_linux-6.0.12.patch
@@ -0,0 +1,4938 @@
+diff --git a/Makefile b/Makefile
+index 9fecb094c28a2..46c6eb57b354d 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,7 +1,7 @@
+ # SPDX-License-Identifier: GPL-2.0
+ VERSION = 6
+ PATCHLEVEL = 0
+-SUBLEVEL = 11
++SUBLEVEL = 12
+ EXTRAVERSION =
+ NAME = Hurr durr I'ma ninja sloth
+
+diff --git a/arch/arm/boot/dts/at91rm9200.dtsi b/arch/arm/boot/dts/at91rm9200.dtsi
+index d1181ead18e5a..21344fbc89e5e 100644
+--- a/arch/arm/boot/dts/at91rm9200.dtsi
++++ b/arch/arm/boot/dts/at91rm9200.dtsi
+@@ -660,7 +660,7 @@
+ compatible = "atmel,at91rm9200-udc";
+ reg = <0xfffb0000 0x4000>;
+ interrupts = <11 IRQ_TYPE_LEVEL_HIGH 2>;
+- clocks = <&pmc PMC_TYPE_PERIPHERAL 11>, <&pmc PMC_TYPE_SYSTEM 2>;
++ clocks = <&pmc PMC_TYPE_PERIPHERAL 11>, <&pmc PMC_TYPE_SYSTEM 1>;
+ clock-names = "pclk", "hclk";
+ status = "disabled";
+ };
+diff --git a/arch/powerpc/net/bpf_jit_comp32.c b/arch/powerpc/net/bpf_jit_comp32.c
+index 43f1c76d48cea..a379b0ce19ffa 100644
+--- a/arch/powerpc/net/bpf_jit_comp32.c
++++ b/arch/powerpc/net/bpf_jit_comp32.c
+@@ -113,23 +113,19 @@ void bpf_jit_build_prologue(u32 *image, struct codegen_context *ctx)
+ {
+ int i;
+
+- /* First arg comes in as a 32 bits pointer. */
+- EMIT(PPC_RAW_MR(bpf_to_ppc(BPF_REG_1), _R3));
+- EMIT(PPC_RAW_LI(bpf_to_ppc(BPF_REG_1) - 1, 0));
++ /* Initialize tail_call_cnt, to be skipped if we do tail calls. */
++ EMIT(PPC_RAW_LI(_R4, 0));
++
++#define BPF_TAILCALL_PROLOGUE_SIZE 4
++
+ EMIT(PPC_RAW_STWU(_R1, _R1, -BPF_PPC_STACKFRAME(ctx)));
+
+- /*
+- * Initialize tail_call_cnt in stack frame if we do tail calls.
+- * Otherwise, put in NOPs so that it can be skipped when we are
+- * invoked through a tail call.
+- */
+ if (ctx->seen & SEEN_TAILCALL)
+- EMIT(PPC_RAW_STW(bpf_to_ppc(BPF_REG_1) - 1, _R1,
+- bpf_jit_stack_offsetof(ctx, BPF_PPC_TC)));
+- else
+- EMIT(PPC_RAW_NOP());
++ EMIT(PPC_RAW_STW(_R4, _R1, bpf_jit_stack_offsetof(ctx, BPF_PPC_TC)));
+
+-#define BPF_TAILCALL_PROLOGUE_SIZE 16
++ /* First arg comes in as a 32 bits pointer. */
++ EMIT(PPC_RAW_MR(bpf_to_ppc(BPF_REG_1), _R3));
++ EMIT(PPC_RAW_LI(bpf_to_ppc(BPF_REG_1) - 1, 0));
+
+ /*
+ * We need a stack frame, but we don't necessarily need to
+@@ -170,24 +166,24 @@ static void bpf_jit_emit_common_epilogue(u32 *image, struct codegen_context *ctx
+ for (i = BPF_PPC_NVR_MIN; i <= 31; i++)
+ if (bpf_is_seen_register(ctx, i))
+ EMIT(PPC_RAW_LWZ(i, _R1, bpf_jit_stack_offsetof(ctx, i)));
+-}
+-
+-void bpf_jit_build_epilogue(u32 *image, struct codegen_context *ctx)
+-{
+- EMIT(PPC_RAW_MR(_R3, bpf_to_ppc(BPF_REG_0)));
+-
+- bpf_jit_emit_common_epilogue(image, ctx);
+-
+- /* Tear down our stack frame */
+
+ if (ctx->seen & SEEN_FUNC)
+ EMIT(PPC_RAW_LWZ(_R0, _R1, BPF_PPC_STACKFRAME(ctx) + PPC_LR_STKOFF));
+
++ /* Tear down our stack frame */
+ EMIT(PPC_RAW_ADDI(_R1, _R1, BPF_PPC_STACKFRAME(ctx)));
+
+ if (ctx->seen & SEEN_FUNC)
+ EMIT(PPC_RAW_MTLR(_R0));
+
++}
++
++void bpf_jit_build_epilogue(u32 *image, struct codegen_context *ctx)
++{
++ EMIT(PPC_RAW_MR(_R3, bpf_to_ppc(BPF_REG_0)));
++
++ bpf_jit_emit_common_epilogue(image, ctx);
++
+ EMIT(PPC_RAW_BLR());
+ }
+
+@@ -244,7 +240,6 @@ static int bpf_jit_emit_tail_call(u32 *image, struct codegen_context *ctx, u32 o
+ EMIT(PPC_RAW_RLWINM(_R3, b2p_index, 2, 0, 29));
+ EMIT(PPC_RAW_ADD(_R3, _R3, b2p_bpf_array));
+ EMIT(PPC_RAW_LWZ(_R3, _R3, offsetof(struct bpf_array, ptrs)));
+- EMIT(PPC_RAW_STW(_R0, _R1, bpf_jit_stack_offsetof(ctx, BPF_PPC_TC)));
+
+ /*
+ * if (prog == NULL)
+@@ -255,19 +250,14 @@ static int bpf_jit_emit_tail_call(u32 *image, struct codegen_context *ctx, u32 o
+
+ /* goto *(prog->bpf_func + prologue_size); */
+ EMIT(PPC_RAW_LWZ(_R3, _R3, offsetof(struct bpf_prog, bpf_func)));
+-
+- if (ctx->seen & SEEN_FUNC)
+- EMIT(PPC_RAW_LWZ(_R0, _R1, BPF_PPC_STACKFRAME(ctx) + PPC_LR_STKOFF));
+-
+ EMIT(PPC_RAW_ADDIC(_R3, _R3, BPF_TAILCALL_PROLOGUE_SIZE));
+-
+- if (ctx->seen & SEEN_FUNC)
+- EMIT(PPC_RAW_MTLR(_R0));
+-
+ EMIT(PPC_RAW_MTCTR(_R3));
+
+ EMIT(PPC_RAW_MR(_R3, bpf_to_ppc(BPF_REG_1)));
+
++ /* Put tail_call_cnt in r4 */
++ EMIT(PPC_RAW_MR(_R4, _R0));
++
+ /* tear restore NVRs, ... */
+ bpf_jit_emit_common_epilogue(image, ctx);
+
+diff --git a/arch/riscv/include/asm/asm.h b/arch/riscv/include/asm/asm.h
+index 1b471ff731788..816e753de636d 100644
+--- a/arch/riscv/include/asm/asm.h
++++ b/arch/riscv/include/asm/asm.h
+@@ -23,6 +23,7 @@
+ #define REG_L __REG_SEL(ld, lw)
+ #define REG_S __REG_SEL(sd, sw)
+ #define REG_SC __REG_SEL(sc.d, sc.w)
++#define REG_AMOSWAP_AQ __REG_SEL(amoswap.d.aq, amoswap.w.aq)
+ #define REG_ASM __REG_SEL(.dword, .word)
+ #define SZREG __REG_SEL(8, 4)
+ #define LGREG __REG_SEL(3, 2)
+diff --git a/arch/riscv/include/asm/efi.h b/arch/riscv/include/asm/efi.h
+index f74879a8f1ea1..e229d7be4b665 100644
+--- a/arch/riscv/include/asm/efi.h
++++ b/arch/riscv/include/asm/efi.h
+@@ -10,6 +10,7 @@
+ #include <asm/mmu_context.h>
+ #include <asm/ptrace.h>
+ #include <asm/tlbflush.h>
++#include <asm/pgalloc.h>
+
+ #ifdef CONFIG_EFI
+ extern void efi_init(void);
+@@ -20,7 +21,10 @@ extern void efi_init(void);
+ int efi_create_mapping(struct mm_struct *mm, efi_memory_desc_t *md);
+ int efi_set_mapping_permissions(struct mm_struct *mm, efi_memory_desc_t *md);
+
+-#define arch_efi_call_virt_setup() efi_virtmap_load()
++#define arch_efi_call_virt_setup() ({ \
++ sync_kernel_mappings(efi_mm.pgd); \
++ efi_virtmap_load(); \
++ })
+ #define arch_efi_call_virt_teardown() efi_virtmap_unload()
+
+ #define ARCH_EFI_IRQ_FLAGS_MASK (SR_IE | SR_SPIE)
+diff --git a/arch/riscv/include/asm/pgalloc.h b/arch/riscv/include/asm/pgalloc.h
+index 947f23d7b6af5..59dc12b5b7e8f 100644
+--- a/arch/riscv/include/asm/pgalloc.h
++++ b/arch/riscv/include/asm/pgalloc.h
+@@ -127,6 +127,13 @@ static inline void p4d_free(struct mm_struct *mm, p4d_t *p4d)
+ #define __p4d_free_tlb(tlb, p4d, addr) p4d_free((tlb)->mm, p4d)
+ #endif /* __PAGETABLE_PMD_FOLDED */
+
++static inline void sync_kernel_mappings(pgd_t *pgd)
++{
++ memcpy(pgd + USER_PTRS_PER_PGD,
++ init_mm.pgd + USER_PTRS_PER_PGD,
++ (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t));
++}
++
+ static inline pgd_t *pgd_alloc(struct mm_struct *mm)
+ {
+ pgd_t *pgd;
+@@ -135,9 +142,7 @@ static inline pgd_t *pgd_alloc(struct mm_struct *mm)
+ if (likely(pgd != NULL)) {
+ memset(pgd, 0, USER_PTRS_PER_PGD * sizeof(pgd_t));
+ /* Copy kernel mappings */
+- memcpy(pgd + USER_PTRS_PER_PGD,
+- init_mm.pgd + USER_PTRS_PER_PGD,
+- (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t));
++ sync_kernel_mappings(pgd);
+ }
+ return pgd;
+ }
+diff --git a/arch/riscv/kernel/entry.S b/arch/riscv/kernel/entry.S
+index b9eda3fcbd6d7..186abd146eaff 100644
+--- a/arch/riscv/kernel/entry.S
++++ b/arch/riscv/kernel/entry.S
+@@ -404,6 +404,19 @@ handle_syscall_trace_exit:
+
+ #ifdef CONFIG_VMAP_STACK
+ handle_kernel_stack_overflow:
++ /*
++ * Takes the psuedo-spinlock for the shadow stack, in case multiple
++ * harts are concurrently overflowing their kernel stacks. We could
++ * store any value here, but since we're overflowing the kernel stack
++ * already we only have SP to use as a scratch register. So we just
++ * swap in the address of the spinlock, as that's definately non-zero.
++ *
++ * Pairs with a store_release in handle_bad_stack().
++ */
++1: la sp, spin_shadow_stack
++ REG_AMOSWAP_AQ sp, sp, (sp)
++ bnez sp, 1b
++
+ la sp, shadow_stack
+ addi sp, sp, SHADOW_OVERFLOW_STACK_SIZE
+
+diff --git a/arch/riscv/kernel/machine_kexec.c b/arch/riscv/kernel/machine_kexec.c
+index ee79e6839b863..db41c676e5a26 100644
+--- a/arch/riscv/kernel/machine_kexec.c
++++ b/arch/riscv/kernel/machine_kexec.c
+@@ -15,6 +15,8 @@
+ #include <linux/compiler.h> /* For unreachable() */
+ #include <linux/cpu.h> /* For cpu_down() */
+ #include <linux/reboot.h>
++#include <linux/interrupt.h>
++#include <linux/irq.h>
+
+ /*
+ * kexec_image_info - Print received image details
+@@ -154,6 +156,37 @@ void crash_smp_send_stop(void)
+ cpus_stopped = 1;
+ }
+
++static void machine_kexec_mask_interrupts(void)
++{
++ unsigned int i;
++ struct irq_desc *desc;
++
++ for_each_irq_desc(i, desc) {
++ struct irq_chip *chip;
++ int ret;
++
++ chip = irq_desc_get_chip(desc);
++ if (!chip)
++ continue;
++
++ /*
++ * First try to remove the active state. If this
++ * fails, try to EOI the interrupt.
++ */
++ ret = irq_set_irqchip_state(i, IRQCHIP_STATE_ACTIVE, false);
++
++ if (ret && irqd_irq_inprogress(&desc->irq_data) &&
++ chip->irq_eoi)
++ chip->irq_eoi(&desc->irq_data);
++
++ if (chip->irq_mask)
++ chip->irq_mask(&desc->irq_data);
++
++ if (chip->irq_disable && !irqd_irq_disabled(&desc->irq_data))
++ chip->irq_disable(&desc->irq_data);
++ }
++}
++
+ /*
+ * machine_crash_shutdown - Prepare to kexec after a kernel crash
+ *
+@@ -169,6 +202,8 @@ machine_crash_shutdown(struct pt_regs *regs)
+ crash_smp_send_stop();
+
+ crash_save_cpu(regs, smp_processor_id());
++ machine_kexec_mask_interrupts();
++
+ pr_info("Starting crashdump kernel...\n");
+ }
+
+diff --git a/arch/riscv/kernel/setup.c b/arch/riscv/kernel/setup.c
+index 67ec1fadcfe24..86acd690d5293 100644
+--- a/arch/riscv/kernel/setup.c
++++ b/arch/riscv/kernel/setup.c
+@@ -322,10 +322,11 @@ subsys_initcall(topology_init);
+
+ void free_initmem(void)
+ {
+- if (IS_ENABLED(CONFIG_STRICT_KERNEL_RWX))
+- set_kernel_memory(lm_alias(__init_begin), lm_alias(__init_end),
+- IS_ENABLED(CONFIG_64BIT) ?
+- set_memory_rw : set_memory_rw_nx);
++ if (IS_ENABLED(CONFIG_STRICT_KERNEL_RWX)) {
++ set_kernel_memory(lm_alias(__init_begin), lm_alias(__init_end), set_memory_rw_nx);
++ if (IS_ENABLED(CONFIG_64BIT))
++ set_kernel_memory(__init_begin, __init_end, set_memory_nx);
++ }
+
+ free_initmem_default(POISON_FREE_INITMEM);
+ }
+diff --git a/arch/riscv/kernel/traps.c b/arch/riscv/kernel/traps.c
+index 635e6ec269380..6e8822446069e 100644
+--- a/arch/riscv/kernel/traps.c
++++ b/arch/riscv/kernel/traps.c
+@@ -218,11 +218,29 @@ asmlinkage unsigned long get_overflow_stack(void)
+ OVERFLOW_STACK_SIZE;
+ }
+
++/*
++ * A pseudo spinlock to protect the shadow stack from being used by multiple
++ * harts concurrently. This isn't a real spinlock because the lock side must
++ * be taken without a valid stack and only a single register, it's only taken
++ * while in the process of panicing anyway so the performance and error
++ * checking a proper spinlock gives us doesn't matter.
++ */
++unsigned long spin_shadow_stack;
++
+ asmlinkage void handle_bad_stack(struct pt_regs *regs)
+ {
+ unsigned long tsk_stk = (unsigned long)current->stack;
+ unsigned long ovf_stk = (unsigned long)this_cpu_ptr(overflow_stack);
+
++ /*
++ * We're done with the shadow stack by this point, as we're on the
++ * overflow stack. Tell any other concurrent overflowing harts that
++ * they can proceed with panicing by releasing the pseudo-spinlock.
++ *
++ * This pairs with an amoswap.aq in handle_kernel_stack_overflow.
++ */
++ smp_store_release(&spin_shadow_stack, 0);
++
+ console_verbose();
+
+ pr_emerg("Insufficient stack space to handle exception!\n");
+diff --git a/arch/riscv/kernel/vdso/Makefile b/arch/riscv/kernel/vdso/Makefile
+index db6548509bb3e..06e6b27f3bcc9 100644
+--- a/arch/riscv/kernel/vdso/Makefile
++++ b/arch/riscv/kernel/vdso/Makefile
+@@ -17,6 +17,7 @@ vdso-syms += flush_icache
+ obj-vdso = $(patsubst %, %.o, $(vdso-syms)) note.o
+
+ ccflags-y := -fno-stack-protector
++ccflags-y += -DDISABLE_BRANCH_PROFILING
+
+ ifneq ($(c-gettimeofday-y),)
+ CFLAGS_vgettimeofday.o += -fPIC -include $(c-gettimeofday-y)
+diff --git a/arch/x86/include/asm/nospec-branch.h b/arch/x86/include/asm/nospec-branch.h
+index c936ce9f0c47c..dfdb103ae4f6f 100644
+--- a/arch/x86/include/asm/nospec-branch.h
++++ b/arch/x86/include/asm/nospec-branch.h
+@@ -321,7 +321,7 @@ static inline void indirect_branch_prediction_barrier(void)
+ /* The Intel SPEC CTRL MSR base value cache */
+ extern u64 x86_spec_ctrl_base;
+ DECLARE_PER_CPU(u64, x86_spec_ctrl_current);
+-extern void write_spec_ctrl_current(u64 val, bool force);
++extern void update_spec_ctrl_cond(u64 val);
+ extern u64 spec_ctrl_current(void);
+
+ /*
+diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c
+index 6ec0b7ce74531..06ad95ae78ceb 100644
+--- a/arch/x86/kernel/cpu/bugs.c
++++ b/arch/x86/kernel/cpu/bugs.c
+@@ -60,11 +60,18 @@ EXPORT_SYMBOL_GPL(x86_spec_ctrl_current);
+
+ static DEFINE_MUTEX(spec_ctrl_mutex);
+
++/* Update SPEC_CTRL MSR and its cached copy unconditionally */
++static void update_spec_ctrl(u64 val)
++{
++ this_cpu_write(x86_spec_ctrl_current, val);
++ wrmsrl(MSR_IA32_SPEC_CTRL, val);
++}
++
+ /*
+ * Keep track of the SPEC_CTRL MSR value for the current task, which may differ
+ * from x86_spec_ctrl_base due to STIBP/SSB in __speculation_ctrl_update().
+ */
+-void write_spec_ctrl_current(u64 val, bool force)
++void update_spec_ctrl_cond(u64 val)
+ {
+ if (this_cpu_read(x86_spec_ctrl_current) == val)
+ return;
+@@ -75,7 +82,7 @@ void write_spec_ctrl_current(u64 val, bool force)
+ * When KERNEL_IBRS this MSR is written on return-to-user, unless
+ * forced the update can be delayed until that time.
+ */
+- if (force || !cpu_feature_enabled(X86_FEATURE_KERNEL_IBRS))
++ if (!cpu_feature_enabled(X86_FEATURE_KERNEL_IBRS))
+ wrmsrl(MSR_IA32_SPEC_CTRL, val);
+ }
+
+@@ -1328,7 +1335,7 @@ static void __init spec_ctrl_disable_kernel_rrsba(void)
+
+ if (ia32_cap & ARCH_CAP_RRSBA) {
+ x86_spec_ctrl_base |= SPEC_CTRL_RRSBA_DIS_S;
+- write_spec_ctrl_current(x86_spec_ctrl_base, true);
++ update_spec_ctrl(x86_spec_ctrl_base);
+ }
+ }
+
+@@ -1450,7 +1457,7 @@ static void __init spectre_v2_select_mitigation(void)
+
+ if (spectre_v2_in_ibrs_mode(mode)) {
+ x86_spec_ctrl_base |= SPEC_CTRL_IBRS;
+- write_spec_ctrl_current(x86_spec_ctrl_base, true);
++ update_spec_ctrl(x86_spec_ctrl_base);
+ }
+
+ switch (mode) {
+@@ -1564,7 +1571,7 @@ static void __init spectre_v2_select_mitigation(void)
+ static void update_stibp_msr(void * __unused)
+ {
+ u64 val = spec_ctrl_current() | (x86_spec_ctrl_base & SPEC_CTRL_STIBP);
+- write_spec_ctrl_current(val, true);
++ update_spec_ctrl(val);
+ }
+
+ /* Update x86_spec_ctrl_base in case SMT state changed. */
+@@ -1797,7 +1804,7 @@ static enum ssb_mitigation __init __ssb_select_mitigation(void)
+ x86_amd_ssb_disable();
+ } else {
+ x86_spec_ctrl_base |= SPEC_CTRL_SSBD;
+- write_spec_ctrl_current(x86_spec_ctrl_base, true);
++ update_spec_ctrl(x86_spec_ctrl_base);
+ }
+ }
+
+@@ -2048,7 +2055,7 @@ int arch_prctl_spec_ctrl_get(struct task_struct *task, unsigned long which)
+ void x86_spec_ctrl_setup_ap(void)
+ {
+ if (boot_cpu_has(X86_FEATURE_MSR_SPEC_CTRL))
+- write_spec_ctrl_current(x86_spec_ctrl_base, true);
++ update_spec_ctrl(x86_spec_ctrl_base);
+
+ if (ssb_mode == SPEC_STORE_BYPASS_DISABLE)
+ x86_amd_ssb_disable();
+diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
+index 58a6ea472db92..5e39449b9dfce 100644
+--- a/arch/x86/kernel/process.c
++++ b/arch/x86/kernel/process.c
+@@ -600,7 +600,7 @@ static __always_inline void __speculation_ctrl_update(unsigned long tifp,
+ }
+
+ if (updmsr)
+- write_spec_ctrl_current(msr, false);
++ update_spec_ctrl_cond(msr);
+ }
+
+ static unsigned long speculation_ctrl_update_tif(struct task_struct *tsk)
+diff --git a/drivers/acpi/numa/hmat.c b/drivers/acpi/numa/hmat.c
+index c3d783aca196f..b42653707fdcd 100644
+--- a/drivers/acpi/numa/hmat.c
++++ b/drivers/acpi/numa/hmat.c
+@@ -563,17 +563,26 @@ static int initiator_cmp(void *priv, const struct list_head *a,
+ {
+ struct memory_initiator *ia;
+ struct memory_initiator *ib;
+- unsigned long *p_nodes = priv;
+
+ ia = list_entry(a, struct memory_initiator, node);
+ ib = list_entry(b, struct memory_initiator, node);
+
+- set_bit(ia->processor_pxm, p_nodes);
+- set_bit(ib->processor_pxm, p_nodes);
+-
+ return ia->processor_pxm - ib->processor_pxm;
+ }
+
++static int initiators_to_nodemask(unsigned long *p_nodes)
++{
++ struct memory_initiator *initiator;
++
++ if (list_empty(&initiators))
++ return -ENXIO;
++
++ list_for_each_entry(initiator, &initiators, node)
++ set_bit(initiator->processor_pxm, p_nodes);
++
++ return 0;
++}
++
+ static void hmat_register_target_initiators(struct memory_target *target)
+ {
+ static DECLARE_BITMAP(p_nodes, MAX_NUMNODES);
+@@ -610,7 +619,10 @@ static void hmat_register_target_initiators(struct memory_target *target)
+ * initiators.
+ */
+ bitmap_zero(p_nodes, MAX_NUMNODES);
+- list_sort(p_nodes, &initiators, initiator_cmp);
++ list_sort(NULL, &initiators, initiator_cmp);
++ if (initiators_to_nodemask(p_nodes) < 0)
++ return;
++
+ if (!access0done) {
+ for (i = WRITE_LATENCY; i <= READ_BANDWIDTH; i++) {
+ loc = localities_types[i];
+@@ -644,8 +656,9 @@ static void hmat_register_target_initiators(struct memory_target *target)
+
+ /* Access 1 ignores Generic Initiators */
+ bitmap_zero(p_nodes, MAX_NUMNODES);
+- list_sort(p_nodes, &initiators, initiator_cmp);
+- best = 0;
++ if (initiators_to_nodemask(p_nodes) < 0)
++ return;
++
+ for (i = WRITE_LATENCY; i <= READ_BANDWIDTH; i++) {
+ loc = localities_types[i];
+ if (!loc)
+diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c
+index 1621ce8187052..d69905233aff2 100644
+--- a/drivers/char/tpm/tpm-interface.c
++++ b/drivers/char/tpm/tpm-interface.c
+@@ -401,13 +401,14 @@ int tpm_pm_suspend(struct device *dev)
+ !pm_suspend_via_firmware())
+ goto suspended;
+
+- if (!tpm_chip_start(chip)) {
++ rc = tpm_try_get_ops(chip);
++ if (!rc) {
+ if (chip->flags & TPM_CHIP_FLAG_TPM2)
+ tpm2_shutdown(chip, TPM2_SU_STATE);
+ else
+ rc = tpm1_pm_suspend(chip, tpm_suspend_pcr);
+
+- tpm_chip_stop(chip);
++ tpm_put_ops(chip);
+ }
+
+ suspended:
+diff --git a/drivers/clk/at91/at91rm9200.c b/drivers/clk/at91/at91rm9200.c
+index b174f727a8ef8..16870943a13e5 100644
+--- a/drivers/clk/at91/at91rm9200.c
++++ b/drivers/clk/at91/at91rm9200.c
+@@ -40,7 +40,7 @@ static const struct clk_pll_characteristics rm9200_pll_characteristics = {
+ };
+
+ static const struct sck at91rm9200_systemck[] = {
+- { .n = "udpck", .p = "usbck", .id = 2 },
++ { .n = "udpck", .p = "usbck", .id = 1 },
+ { .n = "uhpck", .p = "usbck", .id = 4 },
+ { .n = "pck0", .p = "prog0", .id = 8 },
+ { .n = "pck1", .p = "prog1", .id = 9 },
+diff --git a/drivers/clk/qcom/gcc-sc8280xp.c b/drivers/clk/qcom/gcc-sc8280xp.c
+index a2f3ffcc58491..fd332383527fc 100644
+--- a/drivers/clk/qcom/gcc-sc8280xp.c
++++ b/drivers/clk/qcom/gcc-sc8280xp.c
+@@ -5364,6 +5364,8 @@ static struct clk_branch gcc_ufs_1_card_clkref_clk = {
+ .enable_mask = BIT(0),
+ .hw.init = &(const struct clk_init_data) {
+ .name = "gcc_ufs_1_card_clkref_clk",
++ .parent_data = &gcc_parent_data_tcxo,
++ .num_parents = 1,
+ .ops = &clk_branch2_ops,
+ },
+ },
+@@ -5432,6 +5434,8 @@ static struct clk_branch gcc_ufs_card_clkref_clk = {
+ .enable_mask = BIT(0),
+ .hw.init = &(const struct clk_init_data) {
+ .name = "gcc_ufs_card_clkref_clk",
++ .parent_data = &gcc_parent_data_tcxo,
++ .num_parents = 1,
+ .ops = &clk_branch2_ops,
+ },
+ },
+@@ -5848,6 +5852,8 @@ static struct clk_branch gcc_ufs_ref_clkref_clk = {
+ .enable_mask = BIT(0),
+ .hw.init = &(const struct clk_init_data) {
+ .name = "gcc_ufs_ref_clkref_clk",
++ .parent_data = &gcc_parent_data_tcxo,
++ .num_parents = 1,
+ .ops = &clk_branch2_ops,
+ },
+ },
+diff --git a/drivers/clk/qcom/gdsc.c b/drivers/clk/qcom/gdsc.c
+index d3244006c661a..39b35058ad474 100644
+--- a/drivers/clk/qcom/gdsc.c
++++ b/drivers/clk/qcom/gdsc.c
+@@ -11,7 +11,6 @@
+ #include <linux/kernel.h>
+ #include <linux/ktime.h>
+ #include <linux/pm_domain.h>
+-#include <linux/pm_runtime.h>
+ #include <linux/regmap.h>
+ #include <linux/regulator/consumer.h>
+ #include <linux/reset-controller.h>
+@@ -56,22 +55,6 @@ enum gdsc_status {
+ GDSC_ON
+ };
+
+-static int gdsc_pm_runtime_get(struct gdsc *sc)
+-{
+- if (!sc->dev)
+- return 0;
+-
+- return pm_runtime_resume_and_get(sc->dev);
+-}
+-
+-static int gdsc_pm_runtime_put(struct gdsc *sc)
+-{
+- if (!sc->dev)
+- return 0;
+-
+- return pm_runtime_put_sync(sc->dev);
+-}
+-
+ /* Returns 1 if GDSC status is status, 0 if not, and < 0 on error */
+ static int gdsc_check_status(struct gdsc *sc, enum gdsc_status status)
+ {
+@@ -271,8 +254,9 @@ static void gdsc_retain_ff_on(struct gdsc *sc)
+ regmap_update_bits(sc->regmap, sc->gdscr, mask, mask);
+ }
+
+-static int _gdsc_enable(struct gdsc *sc)
++static int gdsc_enable(struct generic_pm_domain *domain)
+ {
++ struct gdsc *sc = domain_to_gdsc(domain);
+ int ret;
+
+ if (sc->pwrsts == PWRSTS_ON)
+@@ -328,22 +312,11 @@ static int _gdsc_enable(struct gdsc *sc)
+ return 0;
+ }
+
+-static int gdsc_enable(struct generic_pm_domain *domain)
++static int gdsc_disable(struct generic_pm_domain *domain)
+ {
+ struct gdsc *sc = domain_to_gdsc(domain);
+ int ret;
+
+- ret = gdsc_pm_runtime_get(sc);
+- if (ret)
+- return ret;
+-
+- return _gdsc_enable(sc);
+-}
+-
+-static int _gdsc_disable(struct gdsc *sc)
+-{
+- int ret;
+-
+ if (sc->pwrsts == PWRSTS_ON)
+ return gdsc_assert_reset(sc);
+
+@@ -378,18 +351,6 @@ static int _gdsc_disable(struct gdsc *sc)
+ return 0;
+ }
+
+-static int gdsc_disable(struct generic_pm_domain *domain)
+-{
+- struct gdsc *sc = domain_to_gdsc(domain);
+- int ret;
+-
+- ret = _gdsc_disable(sc);
+-
+- gdsc_pm_runtime_put(sc);
+-
+- return ret;
+-}
+-
+ static int gdsc_init(struct gdsc *sc)
+ {
+ u32 mask, val;
+@@ -437,14 +398,6 @@ static int gdsc_init(struct gdsc *sc)
+ return ret;
+ }
+
+- /* ...and the power-domain */
+- ret = gdsc_pm_runtime_get(sc);
+- if (ret) {
+- if (sc->rsupply)
+- regulator_disable(sc->rsupply);
+- return ret;
+- }
+-
+ /*
+ * Votable GDSCs can be ON due to Vote from other masters.
+ * If a Votable GDSC is ON, make sure we have a Vote.
+@@ -452,14 +405,14 @@ static int gdsc_init(struct gdsc *sc)
+ if (sc->flags & VOTABLE) {
+ ret = gdsc_update_collapse_bit(sc, false);
+ if (ret)
+- return ret;
++ goto err_disable_supply;
+ }
+
+ /* Turn on HW trigger mode if supported */
+ if (sc->flags & HW_CTRL) {
+ ret = gdsc_hwctrl(sc, true);
+ if (ret < 0)
+- return ret;
++ goto err_disable_supply;
+ }
+
+ /*
+@@ -486,9 +439,18 @@ static int gdsc_init(struct gdsc *sc)
+ sc->pd.power_off = gdsc_disable;
+ if (!sc->pd.power_on)
+ sc->pd.power_on = gdsc_enable;
+- pm_genpd_init(&sc->pd, NULL, !on);
++
++ ret = pm_genpd_init(&sc->pd, NULL, !on);
++ if (ret)
++ goto err_disable_supply;
+
+ return 0;
++
++err_disable_supply:
++ if (on && sc->rsupply)
++ regulator_disable(sc->rsupply);
++
++ return ret;
+ }
+
+ int gdsc_register(struct gdsc_desc *desc,
+@@ -522,8 +484,6 @@ int gdsc_register(struct gdsc_desc *desc,
+ for (i = 0; i < num; i++) {
+ if (!scs[i])
+ continue;
+- if (pm_runtime_enabled(dev))
+- scs[i]->dev = dev;
+ scs[i]->regmap = regmap;
+ scs[i]->rcdev = rcdev;
+ ret = gdsc_init(scs[i]);
+diff --git a/drivers/clk/qcom/gdsc.h b/drivers/clk/qcom/gdsc.h
+index 5de48c9439b29..8d569232bbd6b 100644
+--- a/drivers/clk/qcom/gdsc.h
++++ b/drivers/clk/qcom/gdsc.h
+@@ -30,7 +30,6 @@ struct reset_controller_dev;
+ * @resets: ids of resets associated with this gdsc
+ * @reset_count: number of @resets
+ * @rcdev: reset controller
+- * @dev: the device holding the GDSC, used for pm_runtime calls
+ */
+ struct gdsc {
+ struct generic_pm_domain pd;
+@@ -69,7 +68,6 @@ struct gdsc {
+
+ const char *supply;
+ struct regulator *rsupply;
+- struct device *dev;
+ };
+
+ struct gdsc_desc {
+diff --git a/drivers/clk/samsung/clk-exynos7885.c b/drivers/clk/samsung/clk-exynos7885.c
+index a7b1063027067..368c50badd15a 100644
+--- a/drivers/clk/samsung/clk-exynos7885.c
++++ b/drivers/clk/samsung/clk-exynos7885.c
+@@ -182,7 +182,7 @@ static const struct samsung_div_clock top_div_clks[] __initconst = {
+ CLK_CON_DIV_PLL_SHARED0_DIV2, 0, 1),
+ DIV(CLK_DOUT_SHARED0_DIV3, "dout_shared0_div3", "fout_shared0_pll",
+ CLK_CON_DIV_PLL_SHARED0_DIV3, 0, 2),
+- DIV(CLK_DOUT_SHARED0_DIV4, "dout_shared0_div4", "fout_shared0_pll",
++ DIV(CLK_DOUT_SHARED0_DIV4, "dout_shared0_div4", "dout_shared0_div2",
+ CLK_CON_DIV_PLL_SHARED0_DIV4, 0, 1),
+ DIV(CLK_DOUT_SHARED0_DIV5, "dout_shared0_div5", "fout_shared0_pll",
+ CLK_CON_DIV_PLL_SHARED0_DIV5, 0, 3),
+@@ -190,7 +190,7 @@ static const struct samsung_div_clock top_div_clks[] __initconst = {
+ CLK_CON_DIV_PLL_SHARED1_DIV2, 0, 1),
+ DIV(CLK_DOUT_SHARED1_DIV3, "dout_shared1_div3", "fout_shared1_pll",
+ CLK_CON_DIV_PLL_SHARED1_DIV3, 0, 2),
+- DIV(CLK_DOUT_SHARED1_DIV4, "dout_shared1_div4", "fout_shared1_pll",
++ DIV(CLK_DOUT_SHARED1_DIV4, "dout_shared1_div4", "dout_shared1_div2",
+ CLK_CON_DIV_PLL_SHARED1_DIV4, 0, 1),
+
+ /* CORE */
+diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
+index a7ff77550e173..933bb960490d0 100644
+--- a/drivers/clocksource/arm_arch_timer.c
++++ b/drivers/clocksource/arm_arch_timer.c
+@@ -806,6 +806,9 @@ static u64 __arch_timer_check_delta(void)
+ /*
+ * XGene-1 implements CVAL in terms of TVAL, meaning
+ * that the maximum timer range is 32bit. Shame on them.
++ *
++ * Note that TVAL is signed, thus has only 31 of its
++ * 32 bits to express magnitude.
+ */
+ MIDR_ALL_VERSIONS(MIDR_CPU_MODEL(ARM_CPU_IMP_APM,
+ APM_CPU_PART_POTENZA)),
+@@ -813,8 +816,8 @@ static u64 __arch_timer_check_delta(void)
+ };
+
+ if (is_midr_in_range_list(read_cpuid_id(), broken_cval_midrs)) {
+- pr_warn_once("Broken CNTx_CVAL_EL1, limiting width to 32bits");
+- return CLOCKSOURCE_MASK(32);
++ pr_warn_once("Broken CNTx_CVAL_EL1, using 31 bit TVAL instead.\n");
++ return CLOCKSOURCE_MASK(31);
+ }
+ #endif
+ return CLOCKSOURCE_MASK(arch_counter_get_width());
+diff --git a/drivers/clocksource/timer-riscv.c b/drivers/clocksource/timer-riscv.c
+index 969a552da8d29..a0d66fabf0732 100644
+--- a/drivers/clocksource/timer-riscv.c
++++ b/drivers/clocksource/timer-riscv.c
+@@ -51,7 +51,7 @@ static int riscv_clock_next_event(unsigned long delta,
+ static unsigned int riscv_clock_event_irq;
+ static DEFINE_PER_CPU(struct clock_event_device, riscv_clock_event) = {
+ .name = "riscv_timer_clockevent",
+- .features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_C3STOP,
++ .features = CLOCK_EVT_FEAT_ONESHOT,
+ .rating = 100,
+ .set_next_event = riscv_clock_next_event,
+ };
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
+index 7db4aef9c45cb..5e184952ec988 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
+@@ -985,6 +985,7 @@ static int init_user_pages(struct kgd_mem *mem, uint64_t user_addr,
+ struct amdkfd_process_info *process_info = mem->process_info;
+ struct amdgpu_bo *bo = mem->bo;
+ struct ttm_operation_ctx ctx = { true, false };
++ struct hmm_range *range;
+ int ret = 0;
+
+ mutex_lock(&process_info->lock);
+@@ -1014,7 +1015,7 @@ static int init_user_pages(struct kgd_mem *mem, uint64_t user_addr,
+ return 0;
+ }
+
+- ret = amdgpu_ttm_tt_get_user_pages(bo, bo->tbo.ttm->pages);
++ ret = amdgpu_ttm_tt_get_user_pages(bo, bo->tbo.ttm->pages, &range);
+ if (ret) {
+ pr_err("%s: Failed to get user pages: %d\n", __func__, ret);
+ goto unregister_out;
+@@ -1032,7 +1033,7 @@ static int init_user_pages(struct kgd_mem *mem, uint64_t user_addr,
+ amdgpu_bo_unreserve(bo);
+
+ release_out:
+- amdgpu_ttm_tt_get_user_pages_done(bo->tbo.ttm);
++ amdgpu_ttm_tt_get_user_pages_done(bo->tbo.ttm, range);
+ unregister_out:
+ if (ret)
+ amdgpu_mn_unregister(bo);
+@@ -2367,6 +2368,8 @@ static int update_invalid_user_pages(struct amdkfd_process_info *process_info,
+ /* Go through userptr_inval_list and update any invalid user_pages */
+ list_for_each_entry(mem, &process_info->userptr_inval_list,
+ validate_list.head) {
++ struct hmm_range *range;
++
+ invalid = atomic_read(&mem->invalid);
+ if (!invalid)
+ /* BO hasn't been invalidated since the last
+@@ -2377,7 +2380,8 @@ static int update_invalid_user_pages(struct amdkfd_process_info *process_info,
+ bo = mem->bo;
+
+ /* Get updated user pages */
+- ret = amdgpu_ttm_tt_get_user_pages(bo, bo->tbo.ttm->pages);
++ ret = amdgpu_ttm_tt_get_user_pages(bo, bo->tbo.ttm->pages,
++ &range);
+ if (ret) {
+ pr_debug("Failed %d to get user pages\n", ret);
+
+@@ -2396,7 +2400,7 @@ static int update_invalid_user_pages(struct amdkfd_process_info *process_info,
+ * FIXME: Cannot ignore the return code, must hold
+ * notifier_lock
+ */
+- amdgpu_ttm_tt_get_user_pages_done(bo->tbo.ttm);
++ amdgpu_ttm_tt_get_user_pages_done(bo->tbo.ttm, range);
+ }
+
+ /* Mark the BO as valid unless it was invalidated
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c
+index 2168163aad2d3..252a876b07258 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c
+@@ -209,6 +209,7 @@ void amdgpu_bo_list_get_list(struct amdgpu_bo_list *list,
+ list_add_tail(&e->tv.head, &bucket[priority]);
+
+ e->user_pages = NULL;
++ e->range = NULL;
+ }
+
+ /* Connect the sorted buckets in the output list. */
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.h
+index 9caea1688fc32..e4d78491bcc7e 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.h
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.h
+@@ -26,6 +26,8 @@
+ #include <drm/ttm/ttm_execbuf_util.h>
+ #include <drm/amdgpu_drm.h>
+
++struct hmm_range;
++
+ struct amdgpu_device;
+ struct amdgpu_bo;
+ struct amdgpu_bo_va;
+@@ -36,6 +38,7 @@ struct amdgpu_bo_list_entry {
+ struct amdgpu_bo_va *bo_va;
+ uint32_t priority;
+ struct page **user_pages;
++ struct hmm_range *range;
+ bool user_invalidated;
+ };
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+index b7bae833c804b..7e350ea0368b6 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+@@ -495,9 +495,6 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p,
+ struct amdgpu_vm *vm = &fpriv->vm;
+ struct amdgpu_bo_list_entry *e;
+ struct list_head duplicates;
+- struct amdgpu_bo *gds;
+- struct amdgpu_bo *gws;
+- struct amdgpu_bo *oa;
+ int r;
+
+ INIT_LIST_HEAD(&p->validated);
+@@ -551,7 +548,7 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p,
+ goto out_free_user_pages;
+ }
+
+- r = amdgpu_ttm_tt_get_user_pages(bo, e->user_pages);
++ r = amdgpu_ttm_tt_get_user_pages(bo, e->user_pages, &e->range);
+ if (r) {
+ kvfree(e->user_pages);
+ e->user_pages = NULL;
+@@ -611,49 +608,35 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p,
+ if (r)
+ goto error_validate;
+
+- amdgpu_cs_report_moved_bytes(p->adev, p->bytes_moved,
+- p->bytes_moved_vis);
+-
+- gds = p->bo_list->gds_obj;
+- gws = p->bo_list->gws_obj;
+- oa = p->bo_list->oa_obj;
+-
+- if (gds) {
+- p->job->gds_base = amdgpu_bo_gpu_offset(gds) >> PAGE_SHIFT;
+- p->job->gds_size = amdgpu_bo_size(gds) >> PAGE_SHIFT;
+- }
+- if (gws) {
+- p->job->gws_base = amdgpu_bo_gpu_offset(gws) >> PAGE_SHIFT;
+- p->job->gws_size = amdgpu_bo_size(gws) >> PAGE_SHIFT;
+- }
+- if (oa) {
+- p->job->oa_base = amdgpu_bo_gpu_offset(oa) >> PAGE_SHIFT;
+- p->job->oa_size = amdgpu_bo_size(oa) >> PAGE_SHIFT;
+- }
+-
+- if (!r && p->uf_entry.tv.bo) {
++ if (p->uf_entry.tv.bo) {
+ struct amdgpu_bo *uf = ttm_to_amdgpu_bo(p->uf_entry.tv.bo);
+
+ r = amdgpu_ttm_alloc_gart(&uf->tbo);
++ if (r)
++ goto error_validate;
++
+ p->job->uf_addr += amdgpu_bo_gpu_offset(uf);
+ }
+
++ amdgpu_cs_report_moved_bytes(p->adev, p->bytes_moved,
++ p->bytes_moved_vis);
++ amdgpu_job_set_resources(p->job, p->bo_list->gds_obj,
++ p->bo_list->gws_obj, p->bo_list->oa_obj);
++ return 0;
++
+ error_validate:
+- if (r)
+- ttm_eu_backoff_reservation(&p->ticket, &p->validated);
++ ttm_eu_backoff_reservation(&p->ticket, &p->validated);
+
+ out_free_user_pages:
+- if (r) {
+- amdgpu_bo_list_for_each_userptr_entry(e, p->bo_list) {
+- struct amdgpu_bo *bo = ttm_to_amdgpu_bo(e->tv.bo);
++ amdgpu_bo_list_for_each_userptr_entry(e, p->bo_list) {
++ struct amdgpu_bo *bo = ttm_to_amdgpu_bo(e->tv.bo);
+
+- if (!e->user_pages)
+- continue;
+- amdgpu_ttm_tt_get_user_pages_done(bo->tbo.ttm);
+- kvfree(e->user_pages);
+- e->user_pages = NULL;
+- }
+- mutex_unlock(&p->bo_list->bo_list_mutex);
++ if (!e->user_pages)
++ continue;
++ amdgpu_ttm_tt_get_user_pages_done(bo->tbo.ttm, e->range);
++ kvfree(e->user_pages);
++ e->user_pages = NULL;
++ e->range = NULL;
+ }
+ return r;
+ }
+@@ -1248,7 +1231,8 @@ static int amdgpu_cs_submit(struct amdgpu_cs_parser *p,
+ amdgpu_bo_list_for_each_userptr_entry(e, p->bo_list) {
+ struct amdgpu_bo *bo = ttm_to_amdgpu_bo(e->tv.bo);
+
+- r |= !amdgpu_ttm_tt_get_user_pages_done(bo->tbo.ttm);
++ r |= !amdgpu_ttm_tt_get_user_pages_done(bo->tbo.ttm, e->range);
++ e->range = NULL;
+ }
+ if (r) {
+ r = -EAGAIN;
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
+index 111484ceb47d7..91571b1324f2f 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
+@@ -378,6 +378,7 @@ int amdgpu_gem_userptr_ioctl(struct drm_device *dev, void *data,
+ struct amdgpu_device *adev = drm_to_adev(dev);
+ struct drm_amdgpu_gem_userptr *args = data;
+ struct drm_gem_object *gobj;
++ struct hmm_range *range;
+ struct amdgpu_bo *bo;
+ uint32_t handle;
+ int r;
+@@ -418,7 +419,8 @@ int amdgpu_gem_userptr_ioctl(struct drm_device *dev, void *data,
+ goto release_object;
+
+ if (args->flags & AMDGPU_GEM_USERPTR_VALIDATE) {
+- r = amdgpu_ttm_tt_get_user_pages(bo, bo->tbo.ttm->pages);
++ r = amdgpu_ttm_tt_get_user_pages(bo, bo->tbo.ttm->pages,
++ &range);
+ if (r)
+ goto release_object;
+
+@@ -441,7 +443,7 @@ int amdgpu_gem_userptr_ioctl(struct drm_device *dev, void *data,
+
+ user_pages_done:
+ if (args->flags & AMDGPU_GEM_USERPTR_VALIDATE)
+- amdgpu_ttm_tt_get_user_pages_done(bo->tbo.ttm);
++ amdgpu_ttm_tt_get_user_pages_done(bo->tbo.ttm, range);
+
+ release_object:
+ drm_gem_object_put(gobj);
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
+index c2fd6f3076a6f..3b025aace2831 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
+@@ -129,6 +129,23 @@ int amdgpu_job_alloc_with_ib(struct amdgpu_device *adev, unsigned size,
+ return r;
+ }
+
++void amdgpu_job_set_resources(struct amdgpu_job *job, struct amdgpu_bo *gds,
++ struct amdgpu_bo *gws, struct amdgpu_bo *oa)
++{
++ if (gds) {
++ job->gds_base = amdgpu_bo_gpu_offset(gds) >> PAGE_SHIFT;
++ job->gds_size = amdgpu_bo_size(gds) >> PAGE_SHIFT;
++ }
++ if (gws) {
++ job->gws_base = amdgpu_bo_gpu_offset(gws) >> PAGE_SHIFT;
++ job->gws_size = amdgpu_bo_size(gws) >> PAGE_SHIFT;
++ }
++ if (oa) {
++ job->oa_base = amdgpu_bo_gpu_offset(oa) >> PAGE_SHIFT;
++ job->oa_size = amdgpu_bo_size(oa) >> PAGE_SHIFT;
++ }
++}
++
+ void amdgpu_job_free_resources(struct amdgpu_job *job)
+ {
+ struct amdgpu_ring *ring = to_amdgpu_ring(job->base.sched);
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.h
+index babc0af751c2f..2a1961bf1194f 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.h
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.h
+@@ -76,6 +76,8 @@ int amdgpu_job_alloc(struct amdgpu_device *adev, unsigned num_ibs,
+ struct amdgpu_job **job, struct amdgpu_vm *vm);
+ int amdgpu_job_alloc_with_ib(struct amdgpu_device *adev, unsigned size,
+ enum amdgpu_ib_pool_type pool, struct amdgpu_job **job);
++void amdgpu_job_set_resources(struct amdgpu_job *job, struct amdgpu_bo *gds,
++ struct amdgpu_bo *gws, struct amdgpu_bo *oa);
+ void amdgpu_job_free_resources(struct amdgpu_job *job);
+ void amdgpu_job_free(struct amdgpu_job *job);
+ int amdgpu_job_submit(struct amdgpu_job *job, struct drm_sched_entity *entity,
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
+index 9e6c23266a1a0..dfb8875e0f286 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
+@@ -642,9 +642,6 @@ struct amdgpu_ttm_tt {
+ struct task_struct *usertask;
+ uint32_t userflags;
+ bool bound;
+-#if IS_ENABLED(CONFIG_DRM_AMDGPU_USERPTR)
+- struct hmm_range *range;
+-#endif
+ };
+
+ #define ttm_to_amdgpu_ttm_tt(ptr) container_of(ptr, struct amdgpu_ttm_tt, ttm)
+@@ -657,7 +654,8 @@ struct amdgpu_ttm_tt {
+ * Calling function must call amdgpu_ttm_tt_userptr_range_done() once and only
+ * once afterwards to stop HMM tracking
+ */
+-int amdgpu_ttm_tt_get_user_pages(struct amdgpu_bo *bo, struct page **pages)
++int amdgpu_ttm_tt_get_user_pages(struct amdgpu_bo *bo, struct page **pages,
++ struct hmm_range **range)
+ {
+ struct ttm_tt *ttm = bo->tbo.ttm;
+ struct amdgpu_ttm_tt *gtt = ttm_to_amdgpu_ttm_tt(ttm);
+@@ -667,16 +665,15 @@ int amdgpu_ttm_tt_get_user_pages(struct amdgpu_bo *bo, struct page **pages)
+ bool readonly;
+ int r = 0;
+
++ /* Make sure get_user_pages_done() can cleanup gracefully */
++ *range = NULL;
++
+ mm = bo->notifier.mm;
+ if (unlikely(!mm)) {
+ DRM_DEBUG_DRIVER("BO is not registered?\n");
+ return -EFAULT;
+ }
+
+- /* Another get_user_pages is running at the same time?? */
+- if (WARN_ON(gtt->range))
+- return -EFAULT;
+-
+ if (!mmget_not_zero(mm)) /* Happens during process shutdown */
+ return -ESRCH;
+
+@@ -694,7 +691,7 @@ int amdgpu_ttm_tt_get_user_pages(struct amdgpu_bo *bo, struct page **pages)
+
+ readonly = amdgpu_ttm_tt_is_readonly(ttm);
+ r = amdgpu_hmm_range_get_pages(&bo->notifier, mm, pages, start,
+- ttm->num_pages, &gtt->range, readonly,
++ ttm->num_pages, range, readonly,
+ true, NULL);
+ out_unlock:
+ mmap_read_unlock(mm);
+@@ -712,30 +709,24 @@ out_unlock:
+ *
+ * Returns: true if pages are still valid
+ */
+-bool amdgpu_ttm_tt_get_user_pages_done(struct ttm_tt *ttm)
++bool amdgpu_ttm_tt_get_user_pages_done(struct ttm_tt *ttm,
++ struct hmm_range *range)
+ {
+ struct amdgpu_ttm_tt *gtt = ttm_to_amdgpu_ttm_tt(ttm);
+- bool r = false;
+
+- if (!gtt || !gtt->userptr)
++ if (!gtt || !gtt->userptr || !range)
+ return false;
+
+ DRM_DEBUG_DRIVER("user_pages_done 0x%llx pages 0x%x\n",
+ gtt->userptr, ttm->num_pages);
+
+- WARN_ONCE(!gtt->range || !gtt->range->hmm_pfns,
+- "No user pages to check\n");
++ WARN_ONCE(!range->hmm_pfns, "No user pages to check\n");
+
+- if (gtt->range) {
+- /*
+- * FIXME: Must always hold notifier_lock for this, and must
+- * not ignore the return code.
+- */
+- r = amdgpu_hmm_range_get_pages_done(gtt->range);
+- gtt->range = NULL;
+- }
+-
+- return !r;
++ /*
++ * FIXME: Must always hold notifier_lock for this, and must
++ * not ignore the return code.
++ */
++ return !amdgpu_hmm_range_get_pages_done(range);
+ }
+ #endif
+
+@@ -812,20 +803,6 @@ static void amdgpu_ttm_tt_unpin_userptr(struct ttm_device *bdev,
+ /* unmap the pages mapped to the device */
+ dma_unmap_sgtable(adev->dev, ttm->sg, direction, 0);
+ sg_free_table(ttm->sg);
+-
+-#if IS_ENABLED(CONFIG_DRM_AMDGPU_USERPTR)
+- if (gtt->range) {
+- unsigned long i;
+-
+- for (i = 0; i < ttm->num_pages; i++) {
+- if (ttm->pages[i] !=
+- hmm_pfn_to_page(gtt->range->hmm_pfns[i]))
+- break;
+- }
+-
+- WARN((i == ttm->num_pages), "Missing get_user_page_done\n");
+- }
+-#endif
+ }
+
+ static void amdgpu_ttm_gart_bind(struct amdgpu_device *adev,
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
+index 6a70818039dda..a37207011a69a 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
+@@ -39,6 +39,8 @@
+
+ #define AMDGPU_POISON 0xd0bed0be
+
++struct hmm_range;
++
+ struct amdgpu_gtt_mgr {
+ struct ttm_resource_manager manager;
+ struct drm_mm mm;
+@@ -149,15 +151,19 @@ void amdgpu_ttm_recover_gart(struct ttm_buffer_object *tbo);
+ uint64_t amdgpu_ttm_domain_start(struct amdgpu_device *adev, uint32_t type);
+
+ #if IS_ENABLED(CONFIG_DRM_AMDGPU_USERPTR)
+-int amdgpu_ttm_tt_get_user_pages(struct amdgpu_bo *bo, struct page **pages);
+-bool amdgpu_ttm_tt_get_user_pages_done(struct ttm_tt *ttm);
++int amdgpu_ttm_tt_get_user_pages(struct amdgpu_bo *bo, struct page **pages,
++ struct hmm_range **range);
++bool amdgpu_ttm_tt_get_user_pages_done(struct ttm_tt *ttm,
++ struct hmm_range *range);
+ #else
+ static inline int amdgpu_ttm_tt_get_user_pages(struct amdgpu_bo *bo,
+- struct page **pages)
++ struct page **pages,
++ struct hmm_range **range)
+ {
+ return -EPERM;
+ }
+-static inline bool amdgpu_ttm_tt_get_user_pages_done(struct ttm_tt *ttm)
++static inline bool amdgpu_ttm_tt_get_user_pages_done(struct ttm_tt *ttm,
++ struct hmm_range *range)
+ {
+ return false;
+ }
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c
+index 0b52af415b282..ce64ca1c6e669 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c
+@@ -156,6 +156,9 @@ int amdgpu_vcn_sw_init(struct amdgpu_device *adev)
+ break;
+ case IP_VERSION(3, 0, 2):
+ fw_name = FIRMWARE_VANGOGH;
++ if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) &&
++ (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG))
++ adev->vcn.indirect_sram = true;
+ break;
+ case IP_VERSION(3, 0, 16):
+ fw_name = FIRMWARE_DIMGREY_CAVEFISH;
+diff --git a/drivers/gpu/drm/amd/display/Kconfig b/drivers/gpu/drm/amd/display/Kconfig
+index 413d8c6d592ff..220fb332c8e61 100644
+--- a/drivers/gpu/drm/amd/display/Kconfig
++++ b/drivers/gpu/drm/amd/display/Kconfig
+@@ -5,6 +5,7 @@ menu "Display Engine Configuration"
+ config DRM_AMD_DC
+ bool "AMD DC - Enable new display engine"
+ default y
++ depends on BROKEN || !CC_IS_CLANG || X86_64 || SPARC64 || ARM64
+ select SND_HDA_COMPONENT if SND_HDA_CORE
+ select DRM_AMD_DC_DCN if (X86 || PPC_LONG_DOUBLE_128)
+ help
+@@ -12,6 +13,12 @@ config DRM_AMD_DC
+ support for AMDGPU. This adds required support for Vega and
+ Raven ASICs.
+
++ calculate_bandwidth() is presently broken on all !(X86_64 || SPARC64 || ARM64)
++ architectures built with Clang (all released versions), whereby the stack
++ frame gets blown up to well over 5k. This would cause an immediate kernel
++ panic on most architectures. We'll revert this when the following bug report
++ has been resolved: https://github.com/llvm/llvm-project/issues/41896.
++
+ config DRM_AMD_DC_DCN
+ def_bool n
+ help
+diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu13_driver_if_v13_0_0.h b/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu13_driver_if_v13_0_0.h
+index 063f4a7376056..b76f0f7e42998 100644
+--- a/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu13_driver_if_v13_0_0.h
++++ b/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu13_driver_if_v13_0_0.h
+@@ -25,7 +25,7 @@
+ #define SMU13_DRIVER_IF_V13_0_0_H
+
+ //Increment this version if SkuTable_t or BoardTable_t change
+-#define PPTABLE_VERSION 0x24
++#define PPTABLE_VERSION 0x26
+
+ #define NUM_GFXCLK_DPM_LEVELS 16
+ #define NUM_SOCCLK_DPM_LEVELS 8
+@@ -109,6 +109,22 @@
+ #define FEATURE_SPARE_63_BIT 63
+ #define NUM_FEATURES 64
+
++#define ALLOWED_FEATURE_CTRL_DEFAULT 0xFFFFFFFFFFFFFFFFULL
++#define ALLOWED_FEATURE_CTRL_SCPM ((1 << FEATURE_DPM_GFXCLK_BIT) | \
++ (1 << FEATURE_DPM_GFX_POWER_OPTIMIZER_BIT) | \
++ (1 << FEATURE_DPM_UCLK_BIT) | \
++ (1 << FEATURE_DPM_FCLK_BIT) | \
++ (1 << FEATURE_DPM_SOCCLK_BIT) | \
++ (1 << FEATURE_DPM_MP0CLK_BIT) | \
++ (1 << FEATURE_DPM_LINK_BIT) | \
++ (1 << FEATURE_DPM_DCN_BIT) | \
++ (1 << FEATURE_DS_GFXCLK_BIT) | \
++ (1 << FEATURE_DS_SOCCLK_BIT) | \
++ (1 << FEATURE_DS_FCLK_BIT) | \
++ (1 << FEATURE_DS_LCLK_BIT) | \
++ (1 << FEATURE_DS_DCFCLK_BIT) | \
++ (1 << FEATURE_DS_UCLK_BIT))
++
+ //For use with feature control messages
+ typedef enum {
+ FEATURE_PWR_ALL,
+@@ -133,6 +149,7 @@ typedef enum {
+ #define DEBUG_OVERRIDE_DISABLE_DFLL 0x00000200
+ #define DEBUG_OVERRIDE_ENABLE_RLC_VF_BRINGUP_MODE 0x00000400
+ #define DEBUG_OVERRIDE_DFLL_MASTER_MODE 0x00000800
++#define DEBUG_OVERRIDE_ENABLE_PROFILING_MODE 0x00001000
+
+ // VR Mapping Bit Defines
+ #define VR_MAPPING_VR_SELECT_MASK 0x01
+@@ -262,15 +279,15 @@ typedef enum {
+ } I2cControllerPort_e;
+
+ typedef enum {
+- I2C_CONTROLLER_NAME_VR_GFX = 0,
+- I2C_CONTROLLER_NAME_VR_SOC,
+- I2C_CONTROLLER_NAME_VR_VMEMP,
+- I2C_CONTROLLER_NAME_VR_VDDIO,
+- I2C_CONTROLLER_NAME_LIQUID0,
+- I2C_CONTROLLER_NAME_LIQUID1,
+- I2C_CONTROLLER_NAME_PLX,
+- I2C_CONTROLLER_NAME_OTHER,
+- I2C_CONTROLLER_NAME_COUNT,
++ I2C_CONTROLLER_NAME_VR_GFX = 0,
++ I2C_CONTROLLER_NAME_VR_SOC,
++ I2C_CONTROLLER_NAME_VR_VMEMP,
++ I2C_CONTROLLER_NAME_VR_VDDIO,
++ I2C_CONTROLLER_NAME_LIQUID0,
++ I2C_CONTROLLER_NAME_LIQUID1,
++ I2C_CONTROLLER_NAME_PLX,
++ I2C_CONTROLLER_NAME_FAN_INTAKE,
++ I2C_CONTROLLER_NAME_COUNT,
+ } I2cControllerName_e;
+
+ typedef enum {
+@@ -282,16 +299,17 @@ typedef enum {
+ I2C_CONTROLLER_THROTTLER_LIQUID0,
+ I2C_CONTROLLER_THROTTLER_LIQUID1,
+ I2C_CONTROLLER_THROTTLER_PLX,
++ I2C_CONTROLLER_THROTTLER_FAN_INTAKE,
+ I2C_CONTROLLER_THROTTLER_INA3221,
+ I2C_CONTROLLER_THROTTLER_COUNT,
+ } I2cControllerThrottler_e;
+
+ typedef enum {
+- I2C_CONTROLLER_PROTOCOL_VR_XPDE132G5,
+- I2C_CONTROLLER_PROTOCOL_VR_IR35217,
+- I2C_CONTROLLER_PROTOCOL_TMP_TMP102A,
+- I2C_CONTROLLER_PROTOCOL_INA3221,
+- I2C_CONTROLLER_PROTOCOL_COUNT,
++ I2C_CONTROLLER_PROTOCOL_VR_XPDE132G5,
++ I2C_CONTROLLER_PROTOCOL_VR_IR35217,
++ I2C_CONTROLLER_PROTOCOL_TMP_MAX31875,
++ I2C_CONTROLLER_PROTOCOL_INA3221,
++ I2C_CONTROLLER_PROTOCOL_COUNT,
+ } I2cControllerProtocol_e;
+
+ typedef struct {
+@@ -658,13 +676,20 @@ typedef struct {
+
+ #define PP_NUM_OD_VF_CURVE_POINTS PP_NUM_RTAVFS_PWL_ZONES + 1
+
++typedef enum {
++ FAN_MODE_AUTO = 0,
++ FAN_MODE_MANUAL_LINEAR,
++} FanMode_e;
+
+ typedef struct {
+ uint32_t FeatureCtrlMask;
+
+ //Voltage control
+ int16_t VoltageOffsetPerZoneBoundary[PP_NUM_OD_VF_CURVE_POINTS];
+- uint16_t reserved[2];
++ uint16_t VddGfxVmax; // in mV
++
++ uint8_t IdlePwrSavingFeaturesCtrl;
++ uint8_t RuntimePwrSavingFeaturesCtrl;
+
+ //Frequency changes
+ int16_t GfxclkFmin; // MHz
+@@ -674,7 +699,7 @@ typedef struct {
+
+ //PPT
+ int16_t Ppt; // %
+- int16_t reserved1;
++ int16_t Tdc;
+
+ //Fan control
+ uint8_t FanLinearPwmPoints[NUM_OD_FAN_MAX_POINTS];
+@@ -701,16 +726,19 @@ typedef struct {
+ uint32_t FeatureCtrlMask;
+
+ int16_t VoltageOffsetPerZoneBoundary;
+- uint16_t reserved[2];
++ uint16_t VddGfxVmax; // in mV
++
++ uint8_t IdlePwrSavingFeaturesCtrl;
++ uint8_t RuntimePwrSavingFeaturesCtrl;
+
+- uint16_t GfxclkFmin; // MHz
+- uint16_t GfxclkFmax; // MHz
++ int16_t GfxclkFmin; // MHz
++ int16_t GfxclkFmax; // MHz
+ uint16_t UclkFmin; // MHz
+ uint16_t UclkFmax; // MHz
+
+ //PPT
+ int16_t Ppt; // %
+- int16_t reserved1;
++ int16_t Tdc;
+
+ uint8_t FanLinearPwmPoints;
+ uint8_t FanLinearTempPoints;
+@@ -857,7 +885,8 @@ typedef struct {
+ uint16_t FanStartTempMin;
+ uint16_t FanStartTempMax;
+
+- uint32_t Spare[12];
++ uint16_t PowerMinPpt0[POWER_SOURCE_COUNT];
++ uint32_t Spare[11];
+
+ } MsgLimits_t;
+
+@@ -1041,7 +1070,17 @@ typedef struct {
+ uint32_t GfxoffSpare[15];
+
+ // GFX GPO
+- uint32_t GfxGpoSpare[16];
++ uint32_t DfllBtcMasterScalerM;
++ int32_t DfllBtcMasterScalerB;
++ uint32_t DfllBtcSlaveScalerM;
++ int32_t DfllBtcSlaveScalerB;
++
++ uint32_t DfllPccAsWaitCtrl; //GDFLL_AS_WAIT_CTRL_PCC register value to be passed to RLC msg
++ uint32_t DfllPccAsStepCtrl; //GDFLL_AS_STEP_CTRL_PCC register value to be passed to RLC msg
++
++ uint32_t DfllL2FrequencyBoostM; //Unitless (float)
++ uint32_t DfllL2FrequencyBoostB; //In MHz (integer)
++ uint32_t GfxGpoSpare[8];
+
+ // GFX DCS
+
+@@ -1114,12 +1153,14 @@ typedef struct {
+ uint16_t IntakeTempHighIntakeAcousticLimit;
+ uint16_t IntakeTempAcouticLimitReleaseRate;
+
+- uint16_t FanStalledTempLimitOffset;
++ int16_t FanAbnormalTempLimitOffset;
+ uint16_t FanStalledTriggerRpm;
+- uint16_t FanAbnormalTriggerRpm;
+- uint16_t FanPadding;
++ uint16_t FanAbnormalTriggerRpmCoeff;
++ uint16_t FanAbnormalDetectionEnable;
+
+- uint32_t FanSpare[14];
++ uint8_t FanIntakeSensorSupport;
++ uint8_t FanIntakePadding[3];
++ uint32_t FanSpare[13];
+
+ // SECTION: VDD_GFX AVFS
+
+@@ -1198,8 +1239,13 @@ typedef struct {
+ int16_t TotalBoardPowerM;
+ int16_t TotalBoardPowerB;
+
++ //PMFW-11158
++ QuadraticInt_t qFeffCoeffGameClock[POWER_SOURCE_COUNT];
++ QuadraticInt_t qFeffCoeffBaseClock[POWER_SOURCE_COUNT];
++ QuadraticInt_t qFeffCoeffBoostClock[POWER_SOURCE_COUNT];
++
+ // SECTION: Sku Reserved
+- uint32_t Spare[61];
++ uint32_t Spare[43];
+
+ // Padding for MMHUB - do not modify this
+ uint32_t MmHubPadding[8];
+@@ -1288,8 +1334,11 @@ typedef struct {
+ uint32_t PostVoltageSetBacoDelay; // in microseconds. Amount of time FW will wait after power good is established or PSI0 command is issued
+ uint32_t BacoEntryDelay; // in milliseconds. Amount of time FW will wait to trigger BACO entry after receiving entry notification from OS
+
++ uint8_t FuseWritePowerMuxPresent;
++ uint8_t FuseWritePadding[3];
++
+ // SECTION: Board Reserved
+- uint32_t BoardSpare[64];
++ uint32_t BoardSpare[63];
+
+ // SECTION: Structure Padding
+
+@@ -1381,7 +1430,7 @@ typedef struct {
+ uint16_t AverageTotalBoardPower;
+
+ uint16_t AvgTemperature[TEMP_COUNT];
+- uint16_t TempPadding;
++ uint16_t AvgTemperatureFanIntake;
+
+ uint8_t PcieRate ;
+ uint8_t PcieWidth ;
+@@ -1550,5 +1599,7 @@ typedef struct {
+ #define IH_INTERRUPT_CONTEXT_ID_AUDIO_D0 0x5
+ #define IH_INTERRUPT_CONTEXT_ID_AUDIO_D3 0x6
+ #define IH_INTERRUPT_CONTEXT_ID_THERMAL_THROTTLING 0x7
++#define IH_INTERRUPT_CONTEXT_ID_FAN_ABNORMAL 0x8
++#define IH_INTERRUPT_CONTEXT_ID_FAN_RECOVERY 0x9
+
+ #endif
+diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu13_driver_if_v13_0_7.h b/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu13_driver_if_v13_0_7.h
+index 25c08f963f499..d6b13933a98fb 100644
+--- a/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu13_driver_if_v13_0_7.h
++++ b/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu13_driver_if_v13_0_7.h
+@@ -25,10 +25,10 @@
+
+ // *** IMPORTANT ***
+ // PMFW TEAM: Always increment the interface version on any change to this file
+-#define SMU13_DRIVER_IF_VERSION 0x2C
++#define SMU13_DRIVER_IF_VERSION 0x35
+
+ //Increment this version if SkuTable_t or BoardTable_t change
+-#define PPTABLE_VERSION 0x20
++#define PPTABLE_VERSION 0x27
+
+ #define NUM_GFXCLK_DPM_LEVELS 16
+ #define NUM_SOCCLK_DPM_LEVELS 8
+@@ -96,7 +96,7 @@
+ #define FEATURE_MEM_TEMP_READ_BIT 47
+ #define FEATURE_ATHUB_MMHUB_PG_BIT 48
+ #define FEATURE_SOC_PCC_BIT 49
+-#define FEATURE_SPARE_50_BIT 50
++#define FEATURE_EDC_PWRBRK_BIT 50
+ #define FEATURE_SPARE_51_BIT 51
+ #define FEATURE_SPARE_52_BIT 52
+ #define FEATURE_SPARE_53_BIT 53
+@@ -282,15 +282,15 @@ typedef enum {
+ } I2cControllerPort_e;
+
+ typedef enum {
+- I2C_CONTROLLER_NAME_VR_GFX = 0,
+- I2C_CONTROLLER_NAME_VR_SOC,
+- I2C_CONTROLLER_NAME_VR_VMEMP,
+- I2C_CONTROLLER_NAME_VR_VDDIO,
+- I2C_CONTROLLER_NAME_LIQUID0,
+- I2C_CONTROLLER_NAME_LIQUID1,
+- I2C_CONTROLLER_NAME_PLX,
+- I2C_CONTROLLER_NAME_OTHER,
+- I2C_CONTROLLER_NAME_COUNT,
++ I2C_CONTROLLER_NAME_VR_GFX = 0,
++ I2C_CONTROLLER_NAME_VR_SOC,
++ I2C_CONTROLLER_NAME_VR_VMEMP,
++ I2C_CONTROLLER_NAME_VR_VDDIO,
++ I2C_CONTROLLER_NAME_LIQUID0,
++ I2C_CONTROLLER_NAME_LIQUID1,
++ I2C_CONTROLLER_NAME_PLX,
++ I2C_CONTROLLER_NAME_FAN_INTAKE,
++ I2C_CONTROLLER_NAME_COUNT,
+ } I2cControllerName_e;
+
+ typedef enum {
+@@ -302,6 +302,7 @@ typedef enum {
+ I2C_CONTROLLER_THROTTLER_LIQUID0,
+ I2C_CONTROLLER_THROTTLER_LIQUID1,
+ I2C_CONTROLLER_THROTTLER_PLX,
++ I2C_CONTROLLER_THROTTLER_FAN_INTAKE,
+ I2C_CONTROLLER_THROTTLER_INA3221,
+ I2C_CONTROLLER_THROTTLER_COUNT,
+ } I2cControllerThrottler_e;
+@@ -309,8 +310,9 @@ typedef enum {
+ typedef enum {
+ I2C_CONTROLLER_PROTOCOL_VR_XPDE132G5,
+ I2C_CONTROLLER_PROTOCOL_VR_IR35217,
+- I2C_CONTROLLER_PROTOCOL_TMP_TMP102A,
++ I2C_CONTROLLER_PROTOCOL_TMP_MAX31875,
+ I2C_CONTROLLER_PROTOCOL_INA3221,
++ I2C_CONTROLLER_PROTOCOL_TMP_MAX6604,
+ I2C_CONTROLLER_PROTOCOL_COUNT,
+ } I2cControllerProtocol_e;
+
+@@ -690,6 +692,9 @@ typedef struct {
+ #define PP_OD_FEATURE_UCLK_BIT 8
+ #define PP_OD_FEATURE_ZERO_FAN_BIT 9
+ #define PP_OD_FEATURE_TEMPERATURE_BIT 10
++#define PP_OD_FEATURE_POWER_FEATURE_CTRL_BIT 11
++#define PP_OD_FEATURE_ASIC_TDC_BIT 12
++#define PP_OD_FEATURE_COUNT 13
+
+ typedef enum {
+ PP_OD_POWER_FEATURE_ALWAYS_ENABLED,
+@@ -697,6 +702,11 @@ typedef enum {
+ PP_OD_POWER_FEATURE_ALWAYS_DISABLED,
+ } PP_OD_POWER_FEATURE_e;
+
++typedef enum {
++ FAN_MODE_AUTO = 0,
++ FAN_MODE_MANUAL_LINEAR,
++} FanMode_e;
++
+ typedef struct {
+ uint32_t FeatureCtrlMask;
+
+@@ -708,8 +718,8 @@ typedef struct {
+ uint8_t RuntimePwrSavingFeaturesCtrl;
+
+ //Frequency changes
+- int16_t GfxclkFmin; // MHz
+- int16_t GfxclkFmax; // MHz
++ int16_t GfxclkFmin; // MHz
++ int16_t GfxclkFmax; // MHz
+ uint16_t UclkFmin; // MHz
+ uint16_t UclkFmax; // MHz
+
+@@ -730,7 +740,12 @@ typedef struct {
+ uint8_t MaxOpTemp;
+ uint8_t Padding[4];
+
+- uint32_t Spare[12];
++ uint16_t GfxVoltageFullCtrlMode;
++ uint16_t GfxclkFullCtrlMode;
++ uint16_t UclkFullCtrlMode;
++ int16_t AsicTdc;
++
++ uint32_t Spare[10];
+ uint32_t MmHubPadding[8]; // SMU internal use. Adding here instead of external as a workaround
+ } OverDriveTable_t;
+
+@@ -748,8 +763,8 @@ typedef struct {
+ uint8_t IdlePwrSavingFeaturesCtrl;
+ uint8_t RuntimePwrSavingFeaturesCtrl;
+
+- uint16_t GfxclkFmin; // MHz
+- uint16_t GfxclkFmax; // MHz
++ int16_t GfxclkFmin; // MHz
++ int16_t GfxclkFmax; // MHz
+ uint16_t UclkFmin; // MHz
+ uint16_t UclkFmax; // MHz
+
+@@ -769,7 +784,12 @@ typedef struct {
+ uint8_t MaxOpTemp;
+ uint8_t Padding[4];
+
+- uint32_t Spare[12];
++ uint16_t GfxVoltageFullCtrlMode;
++ uint16_t GfxclkFullCtrlMode;
++ uint16_t UclkFullCtrlMode;
++ int16_t AsicTdc;
++
++ uint32_t Spare[10];
+
+ } OverDriveLimits_t;
+
+@@ -903,7 +923,8 @@ typedef struct {
+ uint16_t FanStartTempMin;
+ uint16_t FanStartTempMax;
+
+- uint32_t Spare[12];
++ uint16_t PowerMinPpt0[POWER_SOURCE_COUNT];
++ uint32_t Spare[11];
+
+ } MsgLimits_t;
+
+@@ -1086,11 +1107,13 @@ typedef struct {
+ uint32_t GfxoffSpare[15];
+
+ // GFX GPO
+- float DfllBtcMasterScalerM;
++ uint32_t DfllBtcMasterScalerM;
+ int32_t DfllBtcMasterScalerB;
+- float DfllBtcSlaveScalerM;
++ uint32_t DfllBtcSlaveScalerM;
+ int32_t DfllBtcSlaveScalerB;
+- uint32_t GfxGpoSpare[12];
++ uint32_t DfllPccAsWaitCtrl; //GDFLL_AS_WAIT_CTRL_PCC register value to be passed to RLC msg
++ uint32_t DfllPccAsStepCtrl; //GDFLL_AS_STEP_CTRL_PCC register value to be passed to RLC msg
++ uint32_t GfxGpoSpare[10];
+
+ // GFX DCS
+
+@@ -1106,7 +1129,10 @@ typedef struct {
+ uint16_t DcsTimeout; //This is the amount of time SMU FW waits for RLC to put GFX into GFXOFF before reverting to the fallback mechanism of throttling GFXCLK to Fmin.
+
+
+- uint32_t DcsSpare[16];
++ uint32_t DcsSpare[14];
++
++ // UCLK section
++ uint16_t ShadowFreqTableUclk[NUM_UCLK_DPM_LEVELS]; // In MHz
+
+ // UCLK section
+ uint8_t UseStrobeModeOptimizations; //Set to indicate that FW should use strobe mode optimizations
+@@ -1163,13 +1189,14 @@ typedef struct {
+ uint16_t IntakeTempHighIntakeAcousticLimit;
+ uint16_t IntakeTempAcouticLimitReleaseRate;
+
+- uint16_t FanStalledTempLimitOffset;
++ int16_t FanAbnormalTempLimitOffset;
+ uint16_t FanStalledTriggerRpm;
+- uint16_t FanAbnormalTriggerRpm;
+- uint16_t FanPadding;
+-
+- uint32_t FanSpare[14];
++ uint16_t FanAbnormalTriggerRpmCoeff;
++ uint16_t FanAbnormalDetectionEnable;
+
++ uint8_t FanIntakeSensorSupport;
++ uint8_t FanIntakePadding[3];
++ uint32_t FanSpare[13];
+ // SECTION: VDD_GFX AVFS
+
+ uint8_t OverrideGfxAvfsFuses;
+@@ -1193,7 +1220,6 @@ typedef struct {
+ uint32_t dGbV_dT_vmin;
+ uint32_t dGbV_dT_vmax;
+
+- //Unused: PMFW-9370
+ uint32_t V2F_vmin_range_low;
+ uint32_t V2F_vmin_range_high;
+ uint32_t V2F_vmax_range_low;
+@@ -1238,8 +1264,21 @@ typedef struct {
+ // SECTION: Advanced Options
+ uint32_t DebugOverrides;
+
++ // Section: Total Board Power idle vs active coefficients
++ uint8_t TotalBoardPowerSupport;
++ uint8_t TotalBoardPowerPadding[3];
++
++ int16_t TotalIdleBoardPowerM;
++ int16_t TotalIdleBoardPowerB;
++ int16_t TotalBoardPowerM;
++ int16_t TotalBoardPowerB;
++
++ QuadraticInt_t qFeffCoeffGameClock[POWER_SOURCE_COUNT];
++ QuadraticInt_t qFeffCoeffBaseClock[POWER_SOURCE_COUNT];
++ QuadraticInt_t qFeffCoeffBoostClock[POWER_SOURCE_COUNT];
++
+ // SECTION: Sku Reserved
+- uint32_t Spare[64];
++ uint32_t Spare[43];
+
+ // Padding for MMHUB - do not modify this
+ uint32_t MmHubPadding[8];
+@@ -1304,7 +1343,8 @@ typedef struct {
+ // SECTION: Clock Spread Spectrum
+
+ // UCLK Spread Spectrum
+- uint16_t UclkSpreadPadding;
++ uint8_t UclkTrainingModeSpreadPercent; // Q4.4
++ uint8_t UclkSpreadPadding;
+ uint16_t UclkSpreadFreq; // kHz
+
+ // UCLK Spread Spectrum
+@@ -1317,11 +1357,7 @@ typedef struct {
+
+ // Section: Memory Config
+ uint8_t DramWidth; // Width of interface to the channel for each DRAM module. See DRAM_BIT_WIDTH_TYPE_e
+- uint8_t PaddingMem1[3];
+-
+- // Section: Total Board Power
+- uint16_t TotalBoardPower; //Only needed for TCP Estimated case, where TCP = TGP+Total Board Power
+- uint16_t BoardPowerPadding;
++ uint8_t PaddingMem1[7];
+
+ // SECTION: UMC feature flags
+ uint8_t HsrEnabled;
+@@ -1423,8 +1459,11 @@ typedef struct {
+ uint16_t Vcn1ActivityPercentage ;
+
+ uint32_t EnergyAccumulator;
+- uint16_t AverageSocketPower ;
++ uint16_t AverageSocketPower;
++ uint16_t AverageTotalBoardPower;
++
+ uint16_t AvgTemperature[TEMP_COUNT];
++ uint16_t AvgTemperatureFanIntake;
+
+ uint8_t PcieRate ;
+ uint8_t PcieWidth ;
+@@ -1592,5 +1631,7 @@ typedef struct {
+ #define IH_INTERRUPT_CONTEXT_ID_AUDIO_D0 0x5
+ #define IH_INTERRUPT_CONTEXT_ID_AUDIO_D3 0x6
+ #define IH_INTERRUPT_CONTEXT_ID_THERMAL_THROTTLING 0x7
++#define IH_INTERRUPT_CONTEXT_ID_FAN_ABNORMAL 0x8
++#define IH_INTERRUPT_CONTEXT_ID_FAN_RECOVERY 0x9
+
+ #endif
+diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0.h b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0.h
+index 3e29fe4cc4ae4..865d6358918d2 100644
+--- a/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0.h
++++ b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0.h
+@@ -30,8 +30,9 @@
+ #define SMU13_DRIVER_IF_VERSION_ALDE 0x08
+ #define SMU13_DRIVER_IF_VERSION_SMU_V13_0_4 0x07
+ #define SMU13_DRIVER_IF_VERSION_SMU_V13_0_5 0x04
+-#define SMU13_DRIVER_IF_VERSION_SMU_V13_0_0 0x30
+-#define SMU13_DRIVER_IF_VERSION_SMU_V13_0_7 0x2C
++#define SMU13_DRIVER_IF_VERSION_SMU_V13_0_0_10 0x32
++#define SMU13_DRIVER_IF_VERSION_SMU_V13_0_7 0x35
++#define SMU13_DRIVER_IF_VERSION_SMU_V13_0_10 0x1D
+
+ #define SMU13_MODE1_RESET_WAIT_TIME_IN_MS 500 //500ms
+
+diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c
+index 33710dcf1eb16..1983e0d29e9db 100644
+--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c
++++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c
+@@ -288,7 +288,8 @@ int smu_v13_0_check_fw_version(struct smu_context *smu)
+ smu->smc_driver_if_version = SMU13_DRIVER_IF_VERSION_ALDE;
+ break;
+ case IP_VERSION(13, 0, 0):
+- smu->smc_driver_if_version = SMU13_DRIVER_IF_VERSION_SMU_V13_0_0;
++ case IP_VERSION(13, 0, 10):
++ smu->smc_driver_if_version = SMU13_DRIVER_IF_VERSION_SMU_V13_0_0_10;
+ break;
+ case IP_VERSION(13, 0, 7):
+ smu->smc_driver_if_version = SMU13_DRIVER_IF_VERSION_SMU_V13_0_7;
+diff --git a/drivers/gpu/drm/i915/gt/intel_gt.c b/drivers/gpu/drm/i915/gt/intel_gt.c
+index f158f6a08e757..4b347318847f5 100644
+--- a/drivers/gpu/drm/i915/gt/intel_gt.c
++++ b/drivers/gpu/drm/i915/gt/intel_gt.c
+@@ -616,8 +616,13 @@ int intel_gt_wait_for_idle(struct intel_gt *gt, long timeout)
+ return -EINTR;
+ }
+
+- return timeout ? timeout : intel_uc_wait_for_idle(&gt->uc,
+- remaining_timeout);
++ if (timeout)
++ return timeout;
++
++ if (remaining_timeout < 0)
++ remaining_timeout = 0;
++
++ return intel_uc_wait_for_idle(&gt->uc, remaining_timeout);
+ }
+
+ int intel_gt_init(struct intel_gt *gt)
+diff --git a/drivers/gpu/drm/i915/gt/intel_gt_requests.c b/drivers/gpu/drm/i915/gt/intel_gt_requests.c
+index edb881d756309..1dfd01668c79c 100644
+--- a/drivers/gpu/drm/i915/gt/intel_gt_requests.c
++++ b/drivers/gpu/drm/i915/gt/intel_gt_requests.c
+@@ -199,7 +199,7 @@ out_active: spin_lock(&timelines->lock);
+ if (remaining_timeout)
+ *remaining_timeout = timeout;
+
+- return active_count ? timeout : 0;
++ return active_count ? timeout ?: -ETIME : 0;
+ }
+
+ static void retire_work_handler(struct work_struct *work)
+diff --git a/drivers/hwmon/asus-ec-sensors.c b/drivers/hwmon/asus-ec-sensors.c
+index 81e688975c6a7..a901e4e33d81d 100644
+--- a/drivers/hwmon/asus-ec-sensors.c
++++ b/drivers/hwmon/asus-ec-sensors.c
+@@ -938,6 +938,8 @@ static int asus_ec_probe(struct platform_device *pdev)
+ ec_data->nr_sensors = hweight_long(ec_data->board_info->sensors);
+ ec_data->sensors = devm_kcalloc(dev, ec_data->nr_sensors,
+ sizeof(struct ec_sensor), GFP_KERNEL);
++ if (!ec_data->sensors)
++ return -ENOMEM;
+
+ status = setup_lock_data(dev);
+ if (status) {
+diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c
+index 8bf32c6c85d95..9bee4d33fbdf0 100644
+--- a/drivers/hwmon/coretemp.c
++++ b/drivers/hwmon/coretemp.c
+@@ -242,10 +242,13 @@ static int adjust_tjmax(struct cpuinfo_x86 *c, u32 id, struct device *dev)
+ */
+ if (host_bridge && host_bridge->vendor == PCI_VENDOR_ID_INTEL) {
+ for (i = 0; i < ARRAY_SIZE(tjmax_pci_table); i++) {
+- if (host_bridge->device == tjmax_pci_table[i].device)
++ if (host_bridge->device == tjmax_pci_table[i].device) {
++ pci_dev_put(host_bridge);
+ return tjmax_pci_table[i].tjmax;
++ }
+ }
+ }
++ pci_dev_put(host_bridge);
+
+ for (i = 0; i < ARRAY_SIZE(tjmax_table); i++) {
+ if (strstr(c->x86_model_id, tjmax_table[i].id))
+@@ -533,6 +536,10 @@ static void coretemp_remove_core(struct platform_data *pdata, int indx)
+ {
+ struct temp_data *tdata = pdata->core_data[indx];
+
++ /* if we errored on add then this is already gone */
++ if (!tdata)
++ return;
++
+ /* Remove the sysfs attributes */
+ sysfs_remove_group(&pdata->hwmon_dev->kobj, &tdata->attr_group);
+
+diff --git a/drivers/hwmon/i5500_temp.c b/drivers/hwmon/i5500_temp.c
+index 05f68e9c9477e..23b9f94fe0a9b 100644
+--- a/drivers/hwmon/i5500_temp.c
++++ b/drivers/hwmon/i5500_temp.c
+@@ -117,7 +117,7 @@ static int i5500_temp_probe(struct pci_dev *pdev,
+ u32 tstimer;
+ s8 tsfsc;
+
+- err = pci_enable_device(pdev);
++ err = pcim_enable_device(pdev);
+ if (err) {
+ dev_err(&pdev->dev, "Failed to enable device\n");
+ return err;
+diff --git a/drivers/hwmon/ibmpex.c b/drivers/hwmon/ibmpex.c
+index f6ec165c0fa8b..1837cccd993c8 100644
+--- a/drivers/hwmon/ibmpex.c
++++ b/drivers/hwmon/ibmpex.c
+@@ -502,6 +502,7 @@ static void ibmpex_register_bmc(int iface, struct device *dev)
+ return;
+
+ out_register:
++ list_del(&data->list);
+ hwmon_device_unregister(data->hwmon_dev);
+ out_user:
+ ipmi_destroy_user(data->user);
+diff --git a/drivers/hwmon/ina3221.c b/drivers/hwmon/ina3221.c
+index 58d3828e2ec0c..14586b2fb17d1 100644
+--- a/drivers/hwmon/ina3221.c
++++ b/drivers/hwmon/ina3221.c
+@@ -228,7 +228,7 @@ static int ina3221_read_value(struct ina3221_data *ina, unsigned int reg,
+ * Shunt Voltage Sum register has 14-bit value with 1-bit shift
+ * Other Shunt Voltage registers have 12 bits with 3-bit shift
+ */
+- if (reg == INA3221_SHUNT_SUM)
++ if (reg == INA3221_SHUNT_SUM || reg == INA3221_CRIT_SUM)
+ *val = sign_extend32(regval >> 1, 14);
+ else
+ *val = sign_extend32(regval >> 3, 12);
+@@ -465,7 +465,7 @@ static int ina3221_write_curr(struct device *dev, u32 attr,
+ * SHUNT_SUM: (1 / 40uV) << 1 = 1 / 20uV
+ * SHUNT[1-3]: (1 / 40uV) << 3 = 1 / 5uV
+ */
+- if (reg == INA3221_SHUNT_SUM)
++ if (reg == INA3221_SHUNT_SUM || reg == INA3221_CRIT_SUM)
+ regval = DIV_ROUND_CLOSEST(voltage_uv, 20) & 0xfffe;
+ else
+ regval = DIV_ROUND_CLOSEST(voltage_uv, 5) & 0xfff8;
+diff --git a/drivers/hwmon/ltc2947-core.c b/drivers/hwmon/ltc2947-core.c
+index 5423466de697a..e918490f3ff75 100644
+--- a/drivers/hwmon/ltc2947-core.c
++++ b/drivers/hwmon/ltc2947-core.c
+@@ -396,7 +396,7 @@ static int ltc2947_read_temp(struct device *dev, const u32 attr, long *val,
+ return ret;
+
+ /* in milidegrees celcius, temp is given by: */
+- *val = (__val * 204) + 550;
++ *val = (__val * 204) + 5500;
+
+ return 0;
+ }
+diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c
+index 3082183bd66a4..fc70920c4ddab 100644
+--- a/drivers/i2c/busses/i2c-imx.c
++++ b/drivers/i2c/busses/i2c-imx.c
+@@ -1132,7 +1132,8 @@ static int i2c_imx_read(struct imx_i2c_struct *i2c_imx, struct i2c_msg *msgs,
+ int i, result;
+ unsigned int temp;
+ int block_data = msgs->flags & I2C_M_RECV_LEN;
+- int use_dma = i2c_imx->dma && msgs->len >= DMA_THRESHOLD && !block_data;
++ int use_dma = i2c_imx->dma && msgs->flags & I2C_M_DMA_SAFE &&
++ msgs->len >= DMA_THRESHOLD && !block_data;
+
+ dev_dbg(&i2c_imx->adapter.dev,
+ "<%s> write slave address: addr=0x%x\n",
+@@ -1298,7 +1299,8 @@ static int i2c_imx_xfer_common(struct i2c_adapter *adapter,
+ result = i2c_imx_read(i2c_imx, &msgs[i], is_lastmsg, atomic);
+ } else {
+ if (!atomic &&
+- i2c_imx->dma && msgs[i].len >= DMA_THRESHOLD)
++ i2c_imx->dma && msgs[i].len >= DMA_THRESHOLD &&
++ msgs[i].flags & I2C_M_DMA_SAFE)
+ result = i2c_imx_dma_write(i2c_imx, &msgs[i]);
+ else
+ result = i2c_imx_write(i2c_imx, &msgs[i], atomic);
+diff --git a/drivers/i2c/busses/i2c-npcm7xx.c b/drivers/i2c/busses/i2c-npcm7xx.c
+index 0c365b57d9572..83457359ec450 100644
+--- a/drivers/i2c/busses/i2c-npcm7xx.c
++++ b/drivers/i2c/busses/i2c-npcm7xx.c
+@@ -2393,8 +2393,17 @@ static struct platform_driver npcm_i2c_bus_driver = {
+
+ static int __init npcm_i2c_init(void)
+ {
++ int ret;
++
+ npcm_i2c_debugfs_dir = debugfs_create_dir("npcm_i2c", NULL);
+- return platform_driver_register(&npcm_i2c_bus_driver);
++
++ ret = platform_driver_register(&npcm_i2c_bus_driver);
++ if (ret) {
++ debugfs_remove_recursive(npcm_i2c_debugfs_dir);
++ return ret;
++ }
++
++ return 0;
+ }
+ module_init(npcm_i2c_init);
+
+diff --git a/drivers/i2c/busses/i2c-qcom-geni.c b/drivers/i2c/busses/i2c-qcom-geni.c
+index 84a77512614d9..8fce98bb77ff9 100644
+--- a/drivers/i2c/busses/i2c-qcom-geni.c
++++ b/drivers/i2c/busses/i2c-qcom-geni.c
+@@ -626,7 +626,6 @@ static int geni_i2c_gpi_xfer(struct geni_i2c_dev *gi2c, struct i2c_msg msgs[], i
+ dev_err(gi2c->se.dev, "I2C timeout gpi flags:%d addr:0x%x\n",
+ gi2c->cur->flags, gi2c->cur->addr);
+ gi2c->err = -ETIMEDOUT;
+- goto err;
+ }
+
+ if (gi2c->err) {
+diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c
+index 91007558bcb26..2477ae860acfa 100644
+--- a/drivers/i2c/i2c-core-base.c
++++ b/drivers/i2c/i2c-core-base.c
+@@ -467,6 +467,7 @@ static int i2c_device_probe(struct device *dev)
+ {
+ struct i2c_client *client = i2c_verify_client(dev);
+ struct i2c_driver *driver;
++ bool do_power_on;
+ int status;
+
+ if (!client)
+@@ -541,8 +542,8 @@ static int i2c_device_probe(struct device *dev)
+ if (status < 0)
+ goto err_clear_wakeup_irq;
+
+- status = dev_pm_domain_attach(&client->dev,
+- !i2c_acpi_waive_d0_probe(dev));
++ do_power_on = !i2c_acpi_waive_d0_probe(dev);
++ status = dev_pm_domain_attach(&client->dev, do_power_on);
+ if (status)
+ goto err_clear_wakeup_irq;
+
+@@ -581,7 +582,7 @@ static int i2c_device_probe(struct device *dev)
+ err_release_driver_resources:
+ devres_release_group(&client->dev, client->devres_group_id);
+ err_detach_pm_domain:
+- dev_pm_domain_detach(&client->dev, !i2c_acpi_waive_d0_probe(dev));
++ dev_pm_domain_detach(&client->dev, do_power_on);
+ err_clear_wakeup_irq:
+ dev_pm_clear_wake_irq(&client->dev);
+ device_init_wakeup(&client->dev, false);
+@@ -610,7 +611,7 @@ static void i2c_device_remove(struct device *dev)
+
+ devres_release_group(&client->dev, client->devres_group_id);
+
+- dev_pm_domain_detach(&client->dev, !i2c_acpi_waive_d0_probe(dev));
++ dev_pm_domain_detach(&client->dev, true);
+
+ dev_pm_clear_wake_irq(&client->dev);
+ device_init_wakeup(&client->dev, false);
+diff --git a/drivers/iio/health/afe4403.c b/drivers/iio/health/afe4403.c
+index 3bb4028c5d747..df3bc5c3d3786 100644
+--- a/drivers/iio/health/afe4403.c
++++ b/drivers/iio/health/afe4403.c
+@@ -245,14 +245,14 @@ static int afe4403_read_raw(struct iio_dev *indio_dev,
+ int *val, int *val2, long mask)
+ {
+ struct afe4403_data *afe = iio_priv(indio_dev);
+- unsigned int reg = afe4403_channel_values[chan->address];
+- unsigned int field = afe4403_channel_leds[chan->address];
++ unsigned int reg, field;
+ int ret;
+
+ switch (chan->type) {
+ case IIO_INTENSITY:
+ switch (mask) {
+ case IIO_CHAN_INFO_RAW:
++ reg = afe4403_channel_values[chan->address];
+ ret = afe4403_read(afe, reg, val);
+ if (ret)
+ return ret;
+@@ -262,6 +262,7 @@ static int afe4403_read_raw(struct iio_dev *indio_dev,
+ case IIO_CURRENT:
+ switch (mask) {
+ case IIO_CHAN_INFO_RAW:
++ field = afe4403_channel_leds[chan->address];
+ ret = regmap_field_read(afe->fields[field], val);
+ if (ret)
+ return ret;
+diff --git a/drivers/iio/health/afe4404.c b/drivers/iio/health/afe4404.c
+index dd7800159051a..f03c466c93854 100644
+--- a/drivers/iio/health/afe4404.c
++++ b/drivers/iio/health/afe4404.c
+@@ -250,20 +250,20 @@ static int afe4404_read_raw(struct iio_dev *indio_dev,
+ int *val, int *val2, long mask)
+ {
+ struct afe4404_data *afe = iio_priv(indio_dev);
+- unsigned int value_reg = afe4404_channel_values[chan->address];
+- unsigned int led_field = afe4404_channel_leds[chan->address];
+- unsigned int offdac_field = afe4404_channel_offdacs[chan->address];
++ unsigned int value_reg, led_field, offdac_field;
+ int ret;
+
+ switch (chan->type) {
+ case IIO_INTENSITY:
+ switch (mask) {
+ case IIO_CHAN_INFO_RAW:
++ value_reg = afe4404_channel_values[chan->address];
+ ret = regmap_read(afe->regmap, value_reg, val);
+ if (ret)
+ return ret;
+ return IIO_VAL_INT;
+ case IIO_CHAN_INFO_OFFSET:
++ offdac_field = afe4404_channel_offdacs[chan->address];
+ ret = regmap_field_read(afe->fields[offdac_field], val);
+ if (ret)
+ return ret;
+@@ -273,6 +273,7 @@ static int afe4404_read_raw(struct iio_dev *indio_dev,
+ case IIO_CURRENT:
+ switch (mask) {
+ case IIO_CHAN_INFO_RAW:
++ led_field = afe4404_channel_leds[chan->address];
+ ret = regmap_field_read(afe->fields[led_field], val);
+ if (ret)
+ return ret;
+@@ -295,19 +296,20 @@ static int afe4404_write_raw(struct iio_dev *indio_dev,
+ int val, int val2, long mask)
+ {
+ struct afe4404_data *afe = iio_priv(indio_dev);
+- unsigned int led_field = afe4404_channel_leds[chan->address];
+- unsigned int offdac_field = afe4404_channel_offdacs[chan->address];
++ unsigned int led_field, offdac_field;
+
+ switch (chan->type) {
+ case IIO_INTENSITY:
+ switch (mask) {
+ case IIO_CHAN_INFO_OFFSET:
++ offdac_field = afe4404_channel_offdacs[chan->address];
+ return regmap_field_write(afe->fields[offdac_field], val);
+ }
+ break;
+ case IIO_CURRENT:
+ switch (mask) {
+ case IIO_CHAN_INFO_RAW:
++ led_field = afe4404_channel_leds[chan->address];
+ return regmap_field_write(afe->fields[led_field], val);
+ }
+ break;
+diff --git a/drivers/iio/light/Kconfig b/drivers/iio/light/Kconfig
+index 8537e88f02e31..c02393009a2cb 100644
+--- a/drivers/iio/light/Kconfig
++++ b/drivers/iio/light/Kconfig
+@@ -293,6 +293,8 @@ config RPR0521
+ tristate "ROHM RPR0521 ALS and proximity sensor driver"
+ depends on I2C
+ select REGMAP_I2C
++ select IIO_BUFFER
++ select IIO_TRIGGERED_BUFFER
+ help
+ Say Y here if you want to build support for ROHM's RPR0521
+ ambient light and proximity sensor device.
+diff --git a/drivers/input/touchscreen/raydium_i2c_ts.c b/drivers/input/touchscreen/raydium_i2c_ts.c
+index 3a4952935366f..3d9c5758d8a44 100644
+--- a/drivers/input/touchscreen/raydium_i2c_ts.c
++++ b/drivers/input/touchscreen/raydium_i2c_ts.c
+@@ -211,12 +211,14 @@ static int raydium_i2c_send(struct i2c_client *client,
+
+ error = raydium_i2c_xfer(client, addr, xfer, ARRAY_SIZE(xfer));
+ if (likely(!error))
+- return 0;
++ goto out;
+
+ msleep(RM_RETRY_DELAY_MS);
+ } while (++tries < RM_MAX_RETRIES);
+
+ dev_err(&client->dev, "%s failed: %d\n", __func__, error);
++out:
++ kfree(tx_buf);
+ return error;
+ }
+
+diff --git a/drivers/iommu/intel/dmar.c b/drivers/iommu/intel/dmar.c
+index 5a8f780e7ffd8..bc94059a5b870 100644
+--- a/drivers/iommu/intel/dmar.c
++++ b/drivers/iommu/intel/dmar.c
+@@ -820,6 +820,7 @@ int __init dmar_dev_scope_init(void)
+ info = dmar_alloc_pci_notify_info(dev,
+ BUS_NOTIFY_ADD_DEVICE);
+ if (!info) {
++ pci_dev_put(dev);
+ return dmar_dev_scope_status;
+ } else {
+ dmar_pci_bus_add_dev(info);
+diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
+index e47700674978c..412b106d2a398 100644
+--- a/drivers/iommu/intel/iommu.c
++++ b/drivers/iommu/intel/iommu.c
+@@ -3844,8 +3844,10 @@ static inline bool has_external_pci(void)
+ struct pci_dev *pdev = NULL;
+
+ for_each_pci_dev(pdev)
+- if (pdev->external_facing)
++ if (pdev->external_facing) {
++ pci_dev_put(pdev);
+ return true;
++ }
+
+ return false;
+ }
+diff --git a/drivers/media/common/videobuf2/frame_vector.c b/drivers/media/common/videobuf2/frame_vector.c
+index 542dde9d2609b..144027035892a 100644
+--- a/drivers/media/common/videobuf2/frame_vector.c
++++ b/drivers/media/common/videobuf2/frame_vector.c
+@@ -35,11 +35,7 @@
+ int get_vaddr_frames(unsigned long start, unsigned int nr_frames,
+ struct frame_vector *vec)
+ {
+- struct mm_struct *mm = current->mm;
+- struct vm_area_struct *vma;
+- int ret_pin_user_pages_fast = 0;
+- int ret = 0;
+- int err;
++ int ret;
+
+ if (nr_frames == 0)
+ return 0;
+@@ -52,57 +48,17 @@ int get_vaddr_frames(unsigned long start, unsigned int nr_frames,
+ ret = pin_user_pages_fast(start, nr_frames,
+ FOLL_FORCE | FOLL_WRITE | FOLL_LONGTERM,
+ (struct page **)(vec->ptrs));
+- if (ret > 0) {
+- vec->got_ref = true;
+- vec->is_pfns = false;
+- goto out_unlocked;
+- }
+- ret_pin_user_pages_fast = ret;
+-
+- mmap_read_lock(mm);
+- vec->got_ref = false;
+- vec->is_pfns = true;
+- ret = 0;
+- do {
+- unsigned long *nums = frame_vector_pfns(vec);
+-
+- vma = vma_lookup(mm, start);
+- if (!vma)
+- break;
+-
+- while (ret < nr_frames && start + PAGE_SIZE <= vma->vm_end) {
+- err = follow_pfn(vma, start, &nums[ret]);
+- if (err) {
+- if (ret)
+- goto out;
+- // If follow_pfn() returns -EINVAL, then this
+- // is not an IO mapping or a raw PFN mapping.
+- // In that case, return the original error from
+- // pin_user_pages_fast(). Otherwise this
+- // function would return -EINVAL when
+- // pin_user_pages_fast() returned -ENOMEM,
+- // which makes debugging hard.
+- if (err == -EINVAL && ret_pin_user_pages_fast)
+- ret = ret_pin_user_pages_fast;
+- else
+- ret = err;
+- goto out;
+- }
+- start += PAGE_SIZE;
+- ret++;
+- }
+- /* Bail out if VMA doesn't completely cover the tail page. */
+- if (start < vma->vm_end)
+- break;
+- } while (ret < nr_frames);
+-out:
+- mmap_read_unlock(mm);
+-out_unlocked:
+- if (!ret)
+- ret = -EFAULT;
+- if (ret > 0)
+- vec->nr_frames = ret;
+- return ret;
++ vec->got_ref = true;
++ vec->is_pfns = false;
++ vec->nr_frames = ret;
++
++ if (likely(ret > 0))
++ return ret;
++
++ /* This used to (racily) return non-refcounted pfns. Let people know */
++ WARN_ONCE(1, "get_vaddr_frames() cannot follow VM_IO mapping");
++ vec->nr_frames = 0;
++ return ret ? ret : -EFAULT;
+ }
+ EXPORT_SYMBOL(get_vaddr_frames);
+
+diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
+index 3d96493257257..557a8f406726d 100644
+--- a/drivers/mmc/core/core.c
++++ b/drivers/mmc/core/core.c
+@@ -1484,6 +1484,11 @@ void mmc_init_erase(struct mmc_card *card)
+ card->pref_erase = 0;
+ }
+
++static bool is_trim_arg(unsigned int arg)
++{
++ return (arg & MMC_TRIM_OR_DISCARD_ARGS) && arg != MMC_DISCARD_ARG;
++}
++
+ static unsigned int mmc_mmc_erase_timeout(struct mmc_card *card,
+ unsigned int arg, unsigned int qty)
+ {
+@@ -1766,7 +1771,7 @@ int mmc_erase(struct mmc_card *card, unsigned int from, unsigned int nr,
+ !(card->ext_csd.sec_feature_support & EXT_CSD_SEC_ER_EN))
+ return -EOPNOTSUPP;
+
+- if (mmc_card_mmc(card) && (arg & MMC_TRIM_ARGS) &&
++ if (mmc_card_mmc(card) && is_trim_arg(arg) &&
+ !(card->ext_csd.sec_feature_support & EXT_CSD_SEC_GB_CL_EN))
+ return -EOPNOTSUPP;
+
+@@ -1796,7 +1801,7 @@ int mmc_erase(struct mmc_card *card, unsigned int from, unsigned int nr,
+ * identified by the card->eg_boundary flag.
+ */
+ rem = card->erase_size - (from % card->erase_size);
+- if ((arg & MMC_TRIM_ARGS) && (card->eg_boundary) && (nr > rem)) {
++ if ((arg & MMC_TRIM_OR_DISCARD_ARGS) && card->eg_boundary && nr > rem) {
+ err = mmc_do_erase(card, from, from + rem - 1, arg);
+ from += rem;
+ if ((err) || (to <= from))
+diff --git a/drivers/mmc/core/mmc_test.c b/drivers/mmc/core/mmc_test.c
+index 8d9bceeff9864..155ce2bdfe622 100644
+--- a/drivers/mmc/core/mmc_test.c
++++ b/drivers/mmc/core/mmc_test.c
+@@ -3179,7 +3179,8 @@ static int __mmc_test_register_dbgfs_file(struct mmc_card *card,
+ struct mmc_test_dbgfs_file *df;
+
+ if (card->debugfs_root)
+- debugfs_create_file(name, mode, card->debugfs_root, card, fops);
++ file = debugfs_create_file(name, mode, card->debugfs_root,
++ card, fops);
+
+ df = kmalloc(sizeof(*df), GFP_KERNEL);
+ if (!df) {
+diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
+index 69d78604d1fc3..1941ac3c141cf 100644
+--- a/drivers/mmc/host/mtk-sd.c
++++ b/drivers/mmc/host/mtk-sd.c
+@@ -2573,13 +2573,11 @@ static int msdc_of_clock_parse(struct platform_device *pdev,
+ return PTR_ERR(host->src_clk_cg);
+ }
+
+- host->sys_clk_cg = devm_clk_get_optional(&pdev->dev, "sys_cg");
++ /* If present, always enable for this clock gate */
++ host->sys_clk_cg = devm_clk_get_optional_enabled(&pdev->dev, "sys_cg");
+ if (IS_ERR(host->sys_clk_cg))
+ host->sys_clk_cg = NULL;
+
+- /* If present, always enable for this clock gate */
+- clk_prepare_enable(host->sys_clk_cg);
+-
+ host->bulk_clks[0].id = "pclk_cg";
+ host->bulk_clks[1].id = "axi_cg";
+ host->bulk_clks[2].id = "ahb_cg";
+diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
+index 31ea0a2fce358..ffeb5759830ff 100644
+--- a/drivers/mmc/host/sdhci-esdhc-imx.c
++++ b/drivers/mmc/host/sdhci-esdhc-imx.c
+@@ -1512,7 +1512,7 @@ static void esdhc_cqe_enable(struct mmc_host *mmc)
+ * system resume back.
+ */
+ cqhci_writel(cq_host, 0, CQHCI_CTL);
+- if (cqhci_readl(cq_host, CQHCI_CTL) && CQHCI_HALT)
++ if (cqhci_readl(cq_host, CQHCI_CTL) & CQHCI_HALT)
+ dev_err(mmc_dev(host->mmc),
+ "failed to exit halt state when enable CQE\n");
+
+diff --git a/drivers/mmc/host/sdhci-sprd.c b/drivers/mmc/host/sdhci-sprd.c
+index 3b88c9d3ddf90..51cb8cfce3236 100644
+--- a/drivers/mmc/host/sdhci-sprd.c
++++ b/drivers/mmc/host/sdhci-sprd.c
+@@ -470,7 +470,7 @@ static int sdhci_sprd_voltage_switch(struct mmc_host *mmc, struct mmc_ios *ios)
+ }
+
+ if (IS_ERR(sprd_host->pinctrl))
+- return 0;
++ goto reset;
+
+ switch (ios->signal_voltage) {
+ case MMC_SIGNAL_VOLTAGE_180:
+@@ -498,6 +498,8 @@ static int sdhci_sprd_voltage_switch(struct mmc_host *mmc, struct mmc_ios *ios)
+
+ /* Wait for 300 ~ 500 us for pin state stable */
+ usleep_range(300, 500);
++
++reset:
+ sdhci_reset(host, SDHCI_RESET_CMD | SDHCI_RESET_DATA);
+
+ return 0;
+diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
+index 251172890af79..3c52c87ada5d3 100644
+--- a/drivers/mmc/host/sdhci.c
++++ b/drivers/mmc/host/sdhci.c
+@@ -339,6 +339,7 @@ static void sdhci_init(struct sdhci_host *host, int soft)
+ if (soft) {
+ /* force clock reconfiguration */
+ host->clock = 0;
++ host->reinit_uhs = true;
+ mmc->ops->set_ios(mmc, &mmc->ios);
+ }
+ }
+@@ -2258,11 +2259,46 @@ void sdhci_set_uhs_signaling(struct sdhci_host *host, unsigned timing)
+ }
+ EXPORT_SYMBOL_GPL(sdhci_set_uhs_signaling);
+
++static bool sdhci_timing_has_preset(unsigned char timing)
++{
++ switch (timing) {
++ case MMC_TIMING_UHS_SDR12:
++ case MMC_TIMING_UHS_SDR25:
++ case MMC_TIMING_UHS_SDR50:
++ case MMC_TIMING_UHS_SDR104:
++ case MMC_TIMING_UHS_DDR50:
++ case MMC_TIMING_MMC_DDR52:
++ return true;
++ };
++ return false;
++}
++
++static bool sdhci_preset_needed(struct sdhci_host *host, unsigned char timing)
++{
++ return !(host->quirks2 & SDHCI_QUIRK2_PRESET_VALUE_BROKEN) &&
++ sdhci_timing_has_preset(timing);
++}
++
++static bool sdhci_presetable_values_change(struct sdhci_host *host, struct mmc_ios *ios)
++{
++ /*
++ * Preset Values are: Driver Strength, Clock Generator and SDCLK/RCLK
++ * Frequency. Check if preset values need to be enabled, or the Driver
++ * Strength needs updating. Note, clock changes are handled separately.
++ */
++ return !host->preset_enabled &&
++ (sdhci_preset_needed(host, ios->timing) || host->drv_type != ios->drv_type);
++}
++
+ void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
+ {
+ struct sdhci_host *host = mmc_priv(mmc);
++ bool reinit_uhs = host->reinit_uhs;
++ bool turning_on_clk = false;
+ u8 ctrl;
+
++ host->reinit_uhs = false;
++
+ if (ios->power_mode == MMC_POWER_UNDEFINED)
+ return;
+
+@@ -2288,6 +2324,8 @@ void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
+ sdhci_enable_preset_value(host, false);
+
+ if (!ios->clock || ios->clock != host->clock) {
++ turning_on_clk = ios->clock && !host->clock;
++
+ host->ops->set_clock(host, ios->clock);
+ host->clock = ios->clock;
+
+@@ -2314,6 +2352,17 @@ void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
+
+ host->ops->set_bus_width(host, ios->bus_width);
+
++ /*
++ * Special case to avoid multiple clock changes during voltage
++ * switching.
++ */
++ if (!reinit_uhs &&
++ turning_on_clk &&
++ host->timing == ios->timing &&
++ host->version >= SDHCI_SPEC_300 &&
++ !sdhci_presetable_values_change(host, ios))
++ return;
++
+ ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
+
+ if (!(host->quirks & SDHCI_QUIRK_NO_HISPD_BIT)) {
+@@ -2357,6 +2406,7 @@ void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
+ }
+
+ sdhci_writew(host, ctrl_2, SDHCI_HOST_CONTROL2);
++ host->drv_type = ios->drv_type;
+ } else {
+ /*
+ * According to SDHC Spec v3.00, if the Preset Value
+@@ -2384,19 +2434,14 @@ void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
+ host->ops->set_uhs_signaling(host, ios->timing);
+ host->timing = ios->timing;
+
+- if (!(host->quirks2 & SDHCI_QUIRK2_PRESET_VALUE_BROKEN) &&
+- ((ios->timing == MMC_TIMING_UHS_SDR12) ||
+- (ios->timing == MMC_TIMING_UHS_SDR25) ||
+- (ios->timing == MMC_TIMING_UHS_SDR50) ||
+- (ios->timing == MMC_TIMING_UHS_SDR104) ||
+- (ios->timing == MMC_TIMING_UHS_DDR50) ||
+- (ios->timing == MMC_TIMING_MMC_DDR52))) {
++ if (sdhci_preset_needed(host, ios->timing)) {
+ u16 preset;
+
+ sdhci_enable_preset_value(host, true);
+ preset = sdhci_get_preset_value(host);
+ ios->drv_type = FIELD_GET(SDHCI_PRESET_DRV_MASK,
+ preset);
++ host->drv_type = ios->drv_type;
+ }
+
+ /* Re-enable SD Clock */
+@@ -3748,6 +3793,7 @@ int sdhci_resume_host(struct sdhci_host *host)
+ sdhci_init(host, 0);
+ host->pwr = 0;
+ host->clock = 0;
++ host->reinit_uhs = true;
+ mmc->ops->set_ios(mmc, &mmc->ios);
+ } else {
+ sdhci_init(host, (mmc->pm_flags & MMC_PM_KEEP_POWER));
+@@ -3810,6 +3856,7 @@ int sdhci_runtime_resume_host(struct sdhci_host *host, int soft_reset)
+ /* Force clock and power re-program */
+ host->pwr = 0;
+ host->clock = 0;
++ host->reinit_uhs = true;
+ mmc->ops->start_signal_voltage_switch(mmc, &mmc->ios);
+ mmc->ops->set_ios(mmc, &mmc->ios);
+
+diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
+index 95a08f09df30e..cf900cc93e91a 100644
+--- a/drivers/mmc/host/sdhci.h
++++ b/drivers/mmc/host/sdhci.h
+@@ -526,6 +526,8 @@ struct sdhci_host {
+
+ unsigned int clock; /* Current clock (MHz) */
+ u8 pwr; /* Current voltage */
++ u8 drv_type; /* Current UHS-I driver type */
++ bool reinit_uhs; /* Force UHS-related re-initialization */
+
+ bool runtime_suspended; /* Host is runtime suspended */
+ bool bus_on; /* Bus power prevents runtime suspend */
+diff --git a/drivers/net/can/can327.c b/drivers/net/can/can327.c
+index 0941977807761..ed3d0b8989a07 100644
+--- a/drivers/net/can/can327.c
++++ b/drivers/net/can/can327.c
+@@ -263,8 +263,10 @@ static void can327_feed_frame_to_netdev(struct can327 *elm, struct sk_buff *skb)
+ {
+ lockdep_assert_held(&elm->lock);
+
+- if (!netif_running(elm->dev))
++ if (!netif_running(elm->dev)) {
++ kfree_skb(skb);
+ return;
++ }
+
+ /* Queue for NAPI pickup.
+ * rx-offload will update stats and LEDs for us.
+diff --git a/drivers/net/can/cc770/cc770_isa.c b/drivers/net/can/cc770/cc770_isa.c
+index 194c86e0f340f..8f6dccd5a5879 100644
+--- a/drivers/net/can/cc770/cc770_isa.c
++++ b/drivers/net/can/cc770/cc770_isa.c
+@@ -264,22 +264,24 @@ static int cc770_isa_probe(struct platform_device *pdev)
+ if (err) {
+ dev_err(&pdev->dev,
+ "couldn't register device (err=%d)\n", err);
+- goto exit_unmap;
++ goto exit_free;
+ }
+
+ dev_info(&pdev->dev, "device registered (reg_base=0x%p, irq=%d)\n",
+ priv->reg_base, dev->irq);
+ return 0;
+
+- exit_unmap:
++exit_free:
++ free_cc770dev(dev);
++exit_unmap:
+ if (mem[idx])
+ iounmap(base);
+- exit_release:
++exit_release:
+ if (mem[idx])
+ release_mem_region(mem[idx], iosize);
+ else
+ release_region(port[idx], iosize);
+- exit:
++exit:
+ return err;
+ }
+
+diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c
+index 4dc67fdfcdb9d..153d8fd08bd88 100644
+--- a/drivers/net/can/m_can/m_can.c
++++ b/drivers/net/can/m_can/m_can.c
+@@ -1910,7 +1910,7 @@ int m_can_class_get_clocks(struct m_can_classdev *cdev)
+ cdev->hclk = devm_clk_get(cdev->dev, "hclk");
+ cdev->cclk = devm_clk_get(cdev->dev, "cclk");
+
+- if (IS_ERR(cdev->cclk)) {
++ if (IS_ERR(cdev->hclk) || IS_ERR(cdev->cclk)) {
+ dev_err(cdev->dev, "no clock found\n");
+ ret = -ENODEV;
+ }
+diff --git a/drivers/net/can/m_can/m_can_pci.c b/drivers/net/can/m_can/m_can_pci.c
+index 8f184a852a0a7..f2219aa2824b3 100644
+--- a/drivers/net/can/m_can/m_can_pci.c
++++ b/drivers/net/can/m_can/m_can_pci.c
+@@ -120,7 +120,7 @@ static int m_can_pci_probe(struct pci_dev *pci, const struct pci_device_id *id)
+
+ ret = pci_alloc_irq_vectors(pci, 1, 1, PCI_IRQ_ALL_TYPES);
+ if (ret < 0)
+- return ret;
++ goto err_free_dev;
+
+ mcan_class->dev = &pci->dev;
+ mcan_class->net->irq = pci_irq_vector(pci, 0);
+@@ -132,7 +132,7 @@ static int m_can_pci_probe(struct pci_dev *pci, const struct pci_device_id *id)
+
+ ret = m_can_class_register(mcan_class);
+ if (ret)
+- goto err;
++ goto err_free_irq;
+
+ /* Enable interrupt control at CAN wrapper IP */
+ writel(0x1, base + CTL_CSR_INT_CTL_OFFSET);
+@@ -144,8 +144,10 @@ static int m_can_pci_probe(struct pci_dev *pci, const struct pci_device_id *id)
+
+ return 0;
+
+-err:
++err_free_irq:
+ pci_free_irq_vectors(pci);
++err_free_dev:
++ m_can_class_free_dev(mcan_class->net);
+ return ret;
+ }
+
+@@ -161,6 +163,7 @@ static void m_can_pci_remove(struct pci_dev *pci)
+ writel(0x0, priv->base + CTL_CSR_INT_CTL_OFFSET);
+
+ m_can_class_unregister(mcan_class);
++ m_can_class_free_dev(mcan_class->net);
+ pci_free_irq_vectors(pci);
+ }
+
+diff --git a/drivers/net/can/sja1000/sja1000_isa.c b/drivers/net/can/sja1000/sja1000_isa.c
+index d513fac507185..db3e767d5320f 100644
+--- a/drivers/net/can/sja1000/sja1000_isa.c
++++ b/drivers/net/can/sja1000/sja1000_isa.c
+@@ -202,22 +202,24 @@ static int sja1000_isa_probe(struct platform_device *pdev)
+ if (err) {
+ dev_err(&pdev->dev, "registering %s failed (err=%d)\n",
+ DRV_NAME, err);
+- goto exit_unmap;
++ goto exit_free;
+ }
+
+ dev_info(&pdev->dev, "%s device registered (reg_base=0x%p, irq=%d)\n",
+ DRV_NAME, priv->reg_base, dev->irq);
+ return 0;
+
+- exit_unmap:
++exit_free:
++ free_sja1000dev(dev);
++exit_unmap:
+ if (mem[idx])
+ iounmap(base);
+- exit_release:
++exit_release:
+ if (mem[idx])
+ release_mem_region(mem[idx], iosize);
+ else
+ release_region(port[idx], iosize);
+- exit:
++exit:
+ return err;
+ }
+
+diff --git a/drivers/net/can/usb/etas_es58x/es58x_core.c b/drivers/net/can/usb/etas_es58x/es58x_core.c
+index 25f863b4f5f06..ddb7c5735c9ac 100644
+--- a/drivers/net/can/usb/etas_es58x/es58x_core.c
++++ b/drivers/net/can/usb/etas_es58x/es58x_core.c
+@@ -2091,8 +2091,11 @@ static int es58x_init_netdev(struct es58x_device *es58x_dev, int channel_idx)
+ netdev->dev_port = channel_idx;
+
+ ret = register_candev(netdev);
+- if (ret)
++ if (ret) {
++ es58x_dev->netdev[channel_idx] = NULL;
++ free_candev(netdev);
+ return ret;
++ }
+
+ netdev_queue_set_dql_min_limit(netdev_get_tx_queue(netdev, 0),
+ es58x_dev->param->dql_min_limit);
+diff --git a/drivers/net/dsa/lan9303-core.c b/drivers/net/dsa/lan9303-core.c
+index e03ff1f267bba..1de62604434d8 100644
+--- a/drivers/net/dsa/lan9303-core.c
++++ b/drivers/net/dsa/lan9303-core.c
+@@ -959,7 +959,7 @@ static const struct lan9303_mib_desc lan9303_mib[] = {
+ { .offset = LAN9303_MAC_TX_BRDCST_CNT_0, .name = "TxBroad", },
+ { .offset = LAN9303_MAC_TX_PAUSE_CNT_0, .name = "TxPause", },
+ { .offset = LAN9303_MAC_TX_MULCST_CNT_0, .name = "TxMulti", },
+- { .offset = LAN9303_MAC_RX_UNDSZE_CNT_0, .name = "TxUnderRun", },
++ { .offset = LAN9303_MAC_RX_UNDSZE_CNT_0, .name = "RxShort", },
+ { .offset = LAN9303_MAC_TX_64_CNT_0, .name = "Tx64Byte", },
+ { .offset = LAN9303_MAC_TX_127_CNT_0, .name = "Tx128Byte", },
+ { .offset = LAN9303_MAC_TX_255_CNT_0, .name = "Tx256Byte", },
+diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c b/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c
+index 1daecd483b8d6..9c1378c22a8ed 100644
+--- a/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c
++++ b/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c
+@@ -13,6 +13,7 @@
+ #include "aq_ptp.h"
+ #include "aq_filters.h"
+ #include "aq_macsec.h"
++#include "aq_main.h"
+
+ #include <linux/ptp_clock_kernel.h>
+
+@@ -858,7 +859,7 @@ static int aq_set_ringparam(struct net_device *ndev,
+
+ if (netif_running(ndev)) {
+ ndev_running = true;
+- dev_close(ndev);
++ aq_ndev_close(ndev);
+ }
+
+ cfg->rxds = max(ring->rx_pending, hw_caps->rxds_min);
+@@ -874,7 +875,7 @@ static int aq_set_ringparam(struct net_device *ndev,
+ goto err_exit;
+
+ if (ndev_running)
+- err = dev_open(ndev, NULL);
++ err = aq_ndev_open(ndev);
+
+ err_exit:
+ return err;
+diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_main.c b/drivers/net/ethernet/aquantia/atlantic/aq_main.c
+index 8a0af371e7dc7..77609dc0a08d6 100644
+--- a/drivers/net/ethernet/aquantia/atlantic/aq_main.c
++++ b/drivers/net/ethernet/aquantia/atlantic/aq_main.c
+@@ -58,7 +58,7 @@ struct net_device *aq_ndev_alloc(void)
+ return ndev;
+ }
+
+-static int aq_ndev_open(struct net_device *ndev)
++int aq_ndev_open(struct net_device *ndev)
+ {
+ struct aq_nic_s *aq_nic = netdev_priv(ndev);
+ int err = 0;
+@@ -88,7 +88,7 @@ err_exit:
+ return err;
+ }
+
+-static int aq_ndev_close(struct net_device *ndev)
++int aq_ndev_close(struct net_device *ndev)
+ {
+ struct aq_nic_s *aq_nic = netdev_priv(ndev);
+ int err = 0;
+diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_main.h b/drivers/net/ethernet/aquantia/atlantic/aq_main.h
+index 99870865f66db..a78c1a168d8ef 100644
+--- a/drivers/net/ethernet/aquantia/atlantic/aq_main.h
++++ b/drivers/net/ethernet/aquantia/atlantic/aq_main.h
+@@ -16,5 +16,7 @@ DECLARE_STATIC_KEY_FALSE(aq_xdp_locking_key);
+
+ void aq_ndev_schedule_work(struct work_struct *work);
+ struct net_device *aq_ndev_alloc(void);
++int aq_ndev_open(struct net_device *ndev);
++int aq_ndev_close(struct net_device *ndev);
+
+ #endif /* AQ_MAIN_H */
+diff --git a/drivers/net/ethernet/intel/e100.c b/drivers/net/ethernet/intel/e100.c
+index 11a884aa5082c..90a2ba20e902b 100644
+--- a/drivers/net/ethernet/intel/e100.c
++++ b/drivers/net/ethernet/intel/e100.c
+@@ -1741,11 +1741,8 @@ static int e100_xmit_prepare(struct nic *nic, struct cb *cb,
+ dma_addr = dma_map_single(&nic->pdev->dev, skb->data, skb->len,
+ DMA_TO_DEVICE);
+ /* If we can't map the skb, have the upper layer try later */
+- if (dma_mapping_error(&nic->pdev->dev, dma_addr)) {
+- dev_kfree_skb_any(skb);
+- skb = NULL;
++ if (dma_mapping_error(&nic->pdev->dev, dma_addr))
+ return -ENOMEM;
+- }
+
+ /*
+ * Use the last 4 bytes of the SKB payload packet as the CRC, used for
+diff --git a/drivers/net/ethernet/intel/fm10k/fm10k_main.c b/drivers/net/ethernet/intel/fm10k/fm10k_main.c
+index 3362f26d7f999..1b273446621c5 100644
+--- a/drivers/net/ethernet/intel/fm10k/fm10k_main.c
++++ b/drivers/net/ethernet/intel/fm10k/fm10k_main.c
+@@ -32,6 +32,8 @@ struct workqueue_struct *fm10k_workqueue;
+ **/
+ static int __init fm10k_init_module(void)
+ {
++ int ret;
++
+ pr_info("%s\n", fm10k_driver_string);
+ pr_info("%s\n", fm10k_copyright);
+
+@@ -43,7 +45,13 @@ static int __init fm10k_init_module(void)
+
+ fm10k_dbg_init();
+
+- return fm10k_register_pci_driver();
++ ret = fm10k_register_pci_driver();
++ if (ret) {
++ fm10k_dbg_exit();
++ destroy_workqueue(fm10k_workqueue);
++ }
++
++ return ret;
+ }
+ module_init(fm10k_init_module);
+
+diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
+index b3336d31f8a9d..023685cca2c1c 100644
+--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
++++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
+@@ -16652,6 +16652,8 @@ static struct pci_driver i40e_driver = {
+ **/
+ static int __init i40e_init_module(void)
+ {
++ int err;
++
+ pr_info("%s: %s\n", i40e_driver_name, i40e_driver_string);
+ pr_info("%s: %s\n", i40e_driver_name, i40e_copyright);
+
+@@ -16669,7 +16671,14 @@ static int __init i40e_init_module(void)
+ }
+
+ i40e_dbg_init();
+- return pci_register_driver(&i40e_driver);
++ err = pci_register_driver(&i40e_driver);
++ if (err) {
++ destroy_workqueue(i40e_wq);
++ i40e_dbg_exit();
++ return err;
++ }
++
++ return 0;
+ }
+ module_init(i40e_init_module);
+
+diff --git a/drivers/net/ethernet/intel/iavf/iavf_main.c b/drivers/net/ethernet/intel/iavf/iavf_main.c
+index cff03723f4f9f..4e03712726f2f 100644
+--- a/drivers/net/ethernet/intel/iavf/iavf_main.c
++++ b/drivers/net/ethernet/intel/iavf/iavf_main.c
+@@ -5196,6 +5196,8 @@ static struct pci_driver iavf_driver = {
+ **/
+ static int __init iavf_init_module(void)
+ {
++ int ret;
++
+ pr_info("iavf: %s\n", iavf_driver_string);
+
+ pr_info("%s\n", iavf_copyright);
+@@ -5206,7 +5208,12 @@ static int __init iavf_init_module(void)
+ pr_err("%s: Failed to create workqueue\n", iavf_driver_name);
+ return -ENOMEM;
+ }
+- return pci_register_driver(&iavf_driver);
++
++ ret = pci_register_driver(&iavf_driver);
++ if (ret)
++ destroy_workqueue(iavf_wq);
++
++ return ret;
+ }
+
+ module_init(iavf_init_module);
+diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
+index 2f12fbe229c15..624b8aa4508c6 100644
+--- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
++++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
+@@ -4869,6 +4869,8 @@ static struct pci_driver ixgbevf_driver = {
+ **/
+ static int __init ixgbevf_init_module(void)
+ {
++ int err;
++
+ pr_info("%s\n", ixgbevf_driver_string);
+ pr_info("%s\n", ixgbevf_copyright);
+ ixgbevf_wq = create_singlethread_workqueue(ixgbevf_driver_name);
+@@ -4877,7 +4879,13 @@ static int __init ixgbevf_init_module(void)
+ return -ENOMEM;
+ }
+
+- return pci_register_driver(&ixgbevf_driver);
++ err = pci_register_driver(&ixgbevf_driver);
++ if (err) {
++ destroy_workqueue(ixgbevf_wq);
++ return err;
++ }
++
++ return 0;
+ }
+
+ module_init(ixgbevf_init_module);
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/cmd.c b/drivers/net/ethernet/mellanox/mlx5/core/cmd.c
+index 74bd05e5dda23..e7a894ba5c3ea 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/cmd.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/cmd.c
+@@ -1497,8 +1497,8 @@ static ssize_t outlen_write(struct file *filp, const char __user *buf,
+ return -EFAULT;
+
+ err = sscanf(outlen_str, "%d", &outlen);
+- if (err < 0)
+- return err;
++ if (err != 1)
++ return -EINVAL;
+
+ ptr = kzalloc(outlen, GFP_KERNEL);
+ if (!ptr)
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
+index 4d8b8f6143cc9..59cffa49e4b58 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
+@@ -1363,6 +1363,9 @@ void mlx5_eswitch_disable_sriov(struct mlx5_eswitch *esw, bool clear_vf)
+ esw_offloads_del_send_to_vport_meta_rules(esw);
+ devl_rate_nodes_destroy(devlink);
+ }
++ /* Destroy legacy fdb when disabling sriov in legacy mode. */
++ if (esw->mode == MLX5_ESWITCH_LEGACY)
++ mlx5_eswitch_disable_locked(esw);
+
+ esw->esw_funcs.num_vfs = 0;
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
+index 87ce5a208cb52..5ceed4e6c6581 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
++++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
+@@ -731,6 +731,14 @@ void mlx5_eswitch_offloads_destroy_single_fdb(struct mlx5_eswitch *master_esw,
+ struct mlx5_eswitch *slave_esw);
+ int mlx5_eswitch_reload_reps(struct mlx5_eswitch *esw);
+
++static inline int mlx5_eswitch_num_vfs(struct mlx5_eswitch *esw)
++{
++ if (mlx5_esw_allowed(esw))
++ return esw->esw_funcs.num_vfs;
++
++ return 0;
++}
++
+ #else /* CONFIG_MLX5_ESWITCH */
+ /* eswitch API stubs */
+ static inline int mlx5_eswitch_init(struct mlx5_core_dev *dev) { return 0; }
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
+index 061ac87993546..11cb7d28e1f89 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
+@@ -3270,6 +3270,13 @@ static int esw_offloads_stop(struct mlx5_eswitch *esw,
+ int err;
+
+ esw->mode = MLX5_ESWITCH_LEGACY;
++
++ /* If changing from switchdev to legacy mode without sriov enabled,
++ * no need to create legacy fdb.
++ */
++ if (!mlx5_sriov_is_enabled(esw->dev))
++ return 0;
++
+ err = mlx5_eswitch_enable_locked(esw, MLX5_ESWITCH_IGNORE_NUM_VFS);
+ if (err)
+ NL_SET_ERR_MSG_MOD(extack, "Failed setting eswitch to legacy");
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads_termtbl.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads_termtbl.c
+index 108a3503f413c..edd9102583144 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads_termtbl.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads_termtbl.c
+@@ -312,6 +312,8 @@ revert_changes:
+ for (curr_dest = 0; curr_dest < num_vport_dests; curr_dest++) {
+ struct mlx5_termtbl_handle *tt = attr->dests[curr_dest].termtbl;
+
++ attr->dests[curr_dest].termtbl = NULL;
++
+ /* search for the destination associated with the
+ * current term table
+ */
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c b/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c
+index 065102278cb80..48f86e12f5c05 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c
+@@ -648,10 +648,13 @@ static bool mlx5_lag_check_prereq(struct mlx5_lag *ldev)
+ return false;
+
+ #ifdef CONFIG_MLX5_ESWITCH
+- dev = ldev->pf[MLX5_LAG_P1].dev;
+- if ((mlx5_sriov_is_enabled(dev)) && !is_mdev_switchdev_mode(dev))
+- return false;
++ for (i = 0; i < ldev->ports; i++) {
++ dev = ldev->pf[i].dev;
++ if (mlx5_eswitch_num_vfs(dev->priv.eswitch) && !is_mdev_switchdev_mode(dev))
++ return false;
++ }
+
++ dev = ldev->pf[MLX5_LAG_P1].dev;
+ mode = mlx5_eswitch_mode(dev);
+ for (i = 0; i < ldev->ports; i++)
+ if (mlx5_eswitch_mode(ldev->pf[i].dev) != mode)
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_table.c b/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_table.c
+index 31d443dd83862..f68461b133912 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_table.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_table.c
+@@ -46,7 +46,7 @@ static int dr_table_set_miss_action_nic(struct mlx5dr_domain *dmn,
+ int mlx5dr_table_set_miss_action(struct mlx5dr_table *tbl,
+ struct mlx5dr_action *action)
+ {
+- int ret;
++ int ret = -EOPNOTSUPP;
+
+ if (action && action->action_type != DR_ACTION_TYP_FT)
+ return -EOPNOTSUPP;
+@@ -67,6 +67,9 @@ int mlx5dr_table_set_miss_action(struct mlx5dr_table *tbl,
+ goto out;
+ }
+
++ if (ret)
++ goto out;
++
+ /* Release old action */
+ if (tbl->miss_action)
+ refcount_dec(&tbl->miss_action->refcount);
+diff --git a/drivers/net/ethernet/ni/nixge.c b/drivers/net/ethernet/ni/nixge.c
+index 4fc279a175629..bef3f05064876 100644
+--- a/drivers/net/ethernet/ni/nixge.c
++++ b/drivers/net/ethernet/ni/nixge.c
+@@ -249,25 +249,26 @@ static void nixge_hw_dma_bd_release(struct net_device *ndev)
+ struct sk_buff *skb;
+ int i;
+
+- for (i = 0; i < RX_BD_NUM; i++) {
+- phys_addr = nixge_hw_dma_bd_get_addr(&priv->rx_bd_v[i],
+- phys);
+-
+- dma_unmap_single(ndev->dev.parent, phys_addr,
+- NIXGE_MAX_JUMBO_FRAME_SIZE,
+- DMA_FROM_DEVICE);
+-
+- skb = (struct sk_buff *)(uintptr_t)
+- nixge_hw_dma_bd_get_addr(&priv->rx_bd_v[i],
+- sw_id_offset);
+- dev_kfree_skb(skb);
+- }
++ if (priv->rx_bd_v) {
++ for (i = 0; i < RX_BD_NUM; i++) {
++ phys_addr = nixge_hw_dma_bd_get_addr(&priv->rx_bd_v[i],
++ phys);
++
++ dma_unmap_single(ndev->dev.parent, phys_addr,
++ NIXGE_MAX_JUMBO_FRAME_SIZE,
++ DMA_FROM_DEVICE);
++
++ skb = (struct sk_buff *)(uintptr_t)
++ nixge_hw_dma_bd_get_addr(&priv->rx_bd_v[i],
++ sw_id_offset);
++ dev_kfree_skb(skb);
++ }
+
+- if (priv->rx_bd_v)
+ dma_free_coherent(ndev->dev.parent,
+ sizeof(*priv->rx_bd_v) * RX_BD_NUM,
+ priv->rx_bd_v,
+ priv->rx_bd_p);
++ }
+
+ if (priv->tx_skb)
+ devm_kfree(ndev->dev.parent, priv->tx_skb);
+diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
+index bd06076803295..2fd5c6fdb5003 100644
+--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
++++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
+@@ -2991,7 +2991,7 @@ static void qlcnic_83xx_recover_driver_lock(struct qlcnic_adapter *adapter)
+ QLCWRX(adapter->ahw, QLC_83XX_RECOVER_DRV_LOCK, val);
+ dev_info(&adapter->pdev->dev,
+ "%s: lock recovery initiated\n", __func__);
+- msleep(QLC_83XX_DRV_LOCK_RECOVERY_DELAY);
++ mdelay(QLC_83XX_DRV_LOCK_RECOVERY_DELAY);
+ val = QLCRDX(adapter->ahw, QLC_83XX_RECOVER_DRV_LOCK);
+ id = ((val >> 2) & 0xF);
+ if (id == adapter->portnum) {
+@@ -3027,7 +3027,7 @@ int qlcnic_83xx_lock_driver(struct qlcnic_adapter *adapter)
+ if (status)
+ break;
+
+- msleep(QLC_83XX_DRV_LOCK_WAIT_DELAY);
++ mdelay(QLC_83XX_DRV_LOCK_WAIT_DELAY);
+ i++;
+
+ if (i == 1)
+diff --git a/drivers/net/ethernet/renesas/ravb_main.c b/drivers/net/ethernet/renesas/ravb_main.c
+index 7e32b04eb0c75..44f9b31f8b99b 100644
+--- a/drivers/net/ethernet/renesas/ravb_main.c
++++ b/drivers/net/ethernet/renesas/ravb_main.c
+@@ -3013,6 +3013,7 @@ static int __maybe_unused ravb_resume(struct device *dev)
+ ret = ravb_open(ndev);
+ if (ret < 0)
+ return ret;
++ ravb_set_rx_mode(ndev);
+ netif_device_attach(ndev);
+ }
+
+diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
+index d8f1fbc25bdd3..3d171cbc31b6e 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
+@@ -749,6 +749,8 @@ static void dwmac4_flow_ctrl(struct mac_device_info *hw, unsigned int duplex,
+ if (fc & FLOW_RX) {
+ pr_debug("\tReceive Flow-Control ON\n");
+ flow |= GMAC_RX_FLOW_CTRL_RFE;
++ } else {
++ pr_debug("\tReceive Flow-Control OFF\n");
+ }
+ writel(flow, ioaddr + GMAC_RX_FLOW_CTRL);
+
+diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+index 02827829463f6..0f080bfe8b176 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+@@ -1061,8 +1061,16 @@ static void stmmac_mac_link_up(struct phylink_config *config,
+ ctrl |= priv->hw->link.duplex;
+
+ /* Flow Control operation */
+- if (tx_pause && rx_pause)
+- stmmac_mac_flow_ctrl(priv, duplex);
++ if (rx_pause && tx_pause)
++ priv->flow_ctrl = FLOW_AUTO;
++ else if (rx_pause && !tx_pause)
++ priv->flow_ctrl = FLOW_RX;
++ else if (!rx_pause && tx_pause)
++ priv->flow_ctrl = FLOW_TX;
++ else
++ priv->flow_ctrl = FLOW_OFF;
++
++ stmmac_mac_flow_ctrl(priv, duplex);
+
+ if (ctrl != old_ctrl)
+ writel(ctrl, priv->ioaddr + MAC_CTRL_REG);
+diff --git a/drivers/net/ethernet/ti/am65-cpsw-nuss.c b/drivers/net/ethernet/ti/am65-cpsw-nuss.c
+index 348201e10d497..95baacd6c7610 100644
+--- a/drivers/net/ethernet/ti/am65-cpsw-nuss.c
++++ b/drivers/net/ethernet/ti/am65-cpsw-nuss.c
+@@ -2061,7 +2061,7 @@ static void am65_cpsw_nuss_cleanup_ndev(struct am65_cpsw_common *common)
+
+ for (i = 0; i < common->port_num; i++) {
+ port = &common->ports[i];
+- if (port->ndev)
++ if (port->ndev && port->ndev->reg_state == NETREG_REGISTERED)
+ unregister_netdev(port->ndev);
+ }
+ }
+diff --git a/drivers/net/mdio/fwnode_mdio.c b/drivers/net/mdio/fwnode_mdio.c
+index 1c1584fca6327..40e745a1d1854 100644
+--- a/drivers/net/mdio/fwnode_mdio.c
++++ b/drivers/net/mdio/fwnode_mdio.c
+@@ -120,7 +120,7 @@ int fwnode_mdiobus_register_phy(struct mii_bus *bus,
+ /* Associate the fwnode with the device structure so it
+ * can be looked up later.
+ */
+- phy->mdio.dev.fwnode = child;
++ phy->mdio.dev.fwnode = fwnode_handle_get(child);
+
+ /* All data is now stored in the phy struct, so register it */
+ rc = phy_device_register(phy);
+diff --git a/drivers/net/ntb_netdev.c b/drivers/net/ntb_netdev.c
+index 80bdc07f2cd33..dd7e273c90cbd 100644
+--- a/drivers/net/ntb_netdev.c
++++ b/drivers/net/ntb_netdev.c
+@@ -484,7 +484,14 @@ static int __init ntb_netdev_init_module(void)
+ rc = ntb_transport_register_client_dev(KBUILD_MODNAME);
+ if (rc)
+ return rc;
+- return ntb_transport_register_client(&ntb_netdev_client);
++
++ rc = ntb_transport_register_client(&ntb_netdev_client);
++ if (rc) {
++ ntb_transport_unregister_client_dev(KBUILD_MODNAME);
++ return rc;
++ }
++
++ return 0;
+ }
+ module_init(ntb_netdev_init_module);
+
+diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
+index 4df8c337221bd..3607077cf86f8 100644
+--- a/drivers/net/phy/phy_device.c
++++ b/drivers/net/phy/phy_device.c
+@@ -216,6 +216,7 @@ static void phy_mdio_device_free(struct mdio_device *mdiodev)
+
+ static void phy_device_release(struct device *dev)
+ {
++ fwnode_handle_put(dev->fwnode);
+ kfree(to_phy_device(dev));
+ }
+
+@@ -1518,6 +1519,7 @@ error:
+
+ error_module_put:
+ module_put(d->driver->owner);
++ d->driver = NULL;
+ error_put_device:
+ put_device(d);
+ if (ndev_owner != bus->owner)
+diff --git a/drivers/net/tun.c b/drivers/net/tun.c
+index 3387074a2bdb8..167e6a3784ca1 100644
+--- a/drivers/net/tun.c
++++ b/drivers/net/tun.c
+@@ -686,7 +686,6 @@ static void __tun_detach(struct tun_file *tfile, bool clean)
+ if (tun)
+ xdp_rxq_info_unreg(&tfile->xdp_rxq);
+ ptr_ring_cleanup(&tfile->tx_ring, tun_ptr_free);
+- sock_put(&tfile->sk);
+ }
+ }
+
+@@ -702,6 +701,9 @@ static void tun_detach(struct tun_file *tfile, bool clean)
+ if (dev)
+ netdev_state_change(dev);
+ rtnl_unlock();
++
++ if (clean)
++ sock_put(&tfile->sk);
+ }
+
+ static void tun_detach_all(struct net_device *dev)
+diff --git a/drivers/net/wwan/iosm/iosm_ipc_mux_codec.c b/drivers/net/wwan/iosm/iosm_ipc_mux_codec.c
+index d41e373f9c0ad..d6b166fc5c0ef 100644
+--- a/drivers/net/wwan/iosm/iosm_ipc_mux_codec.c
++++ b/drivers/net/wwan/iosm/iosm_ipc_mux_codec.c
+@@ -365,7 +365,8 @@ static void ipc_mux_dl_cmd_decode(struct iosm_mux *ipc_mux, struct sk_buff *skb)
+ /* Pass the DL packet to the netif layer. */
+ static int ipc_mux_net_receive(struct iosm_mux *ipc_mux, int if_id,
+ struct iosm_wwan *wwan, u32 offset,
+- u8 service_class, struct sk_buff *skb)
++ u8 service_class, struct sk_buff *skb,
++ u32 pkt_len)
+ {
+ struct sk_buff *dest_skb = skb_clone(skb, GFP_ATOMIC);
+
+@@ -373,7 +374,7 @@ static int ipc_mux_net_receive(struct iosm_mux *ipc_mux, int if_id,
+ return -ENOMEM;
+
+ skb_pull(dest_skb, offset);
+- skb_set_tail_pointer(dest_skb, dest_skb->len);
++ skb_trim(dest_skb, pkt_len);
+ /* Pass the packet to the netif layer. */
+ dest_skb->priority = service_class;
+
+@@ -429,7 +430,7 @@ static void ipc_mux_dl_fcth_decode(struct iosm_mux *ipc_mux,
+ static void ipc_mux_dl_adgh_decode(struct iosm_mux *ipc_mux,
+ struct sk_buff *skb)
+ {
+- u32 pad_len, packet_offset;
++ u32 pad_len, packet_offset, adgh_len;
+ struct iosm_wwan *wwan;
+ struct mux_adgh *adgh;
+ u8 *block = skb->data;
+@@ -470,10 +471,12 @@ static void ipc_mux_dl_adgh_decode(struct iosm_mux *ipc_mux,
+ packet_offset = sizeof(*adgh) + pad_len;
+
+ if_id += ipc_mux->wwan_q_offset;
++ adgh_len = le16_to_cpu(adgh->length);
+
+ /* Pass the packet to the netif layer */
+ rc = ipc_mux_net_receive(ipc_mux, if_id, wwan, packet_offset,
+- adgh->service_class, skb);
++ adgh->service_class, skb,
++ adgh_len - packet_offset);
+ if (rc) {
+ dev_err(ipc_mux->dev, "mux adgh decoding error");
+ return;
+@@ -547,7 +550,7 @@ static int mux_dl_process_dg(struct iosm_mux *ipc_mux, struct mux_adbh *adbh,
+ int if_id, int nr_of_dg)
+ {
+ u32 dl_head_pad_len = ipc_mux->session[if_id].dl_head_pad_len;
+- u32 packet_offset, i, rc;
++ u32 packet_offset, i, rc, dg_len;
+
+ for (i = 0; i < nr_of_dg; i++, dg++) {
+ if (le32_to_cpu(dg->datagram_index)
+@@ -562,11 +565,12 @@ static int mux_dl_process_dg(struct iosm_mux *ipc_mux, struct mux_adbh *adbh,
+ packet_offset =
+ le32_to_cpu(dg->datagram_index) +
+ dl_head_pad_len;
++ dg_len = le16_to_cpu(dg->datagram_length);
+ /* Pass the packet to the netif layer. */
+ rc = ipc_mux_net_receive(ipc_mux, if_id, ipc_mux->wwan,
+ packet_offset,
+- dg->service_class,
+- skb);
++ dg->service_class, skb,
++ dg_len - dl_head_pad_len);
+ if (rc)
+ goto dg_error;
+ }
+@@ -1207,10 +1211,9 @@ static int mux_ul_dg_update_tbl_index(struct iosm_mux *ipc_mux,
+ qlth_n_ql_size, ul_list);
+ ipc_mux_ul_adb_finish(ipc_mux);
+ if (ipc_mux_ul_adb_allocate(ipc_mux, adb, &ipc_mux->size_needed,
+- IOSM_AGGR_MUX_SIG_ADBH)) {
+- dev_kfree_skb(src_skb);
++ IOSM_AGGR_MUX_SIG_ADBH))
+ return -ENOMEM;
+- }
++
+ ipc_mux->size_needed = le32_to_cpu(adb->adbh->block_length);
+
+ ipc_mux->size_needed += offsetof(struct mux_adth, dg);
+@@ -1471,8 +1474,7 @@ void ipc_mux_ul_encoded_process(struct iosm_mux *ipc_mux, struct sk_buff *skb)
+ ipc_mux->ul_data_pend_bytes);
+
+ /* Reset the skb settings. */
+- skb->tail = 0;
+- skb->len = 0;
++ skb_trim(skb, 0);
+
+ /* Add the consumed ADB to the free list. */
+ skb_queue_tail((&ipc_mux->ul_adb.free_list), skb);
+diff --git a/drivers/net/wwan/iosm/iosm_ipc_protocol.h b/drivers/net/wwan/iosm/iosm_ipc_protocol.h
+index 9b3a6d86ece7a..289397c4ea6ce 100644
+--- a/drivers/net/wwan/iosm/iosm_ipc_protocol.h
++++ b/drivers/net/wwan/iosm/iosm_ipc_protocol.h
+@@ -122,7 +122,7 @@ struct iosm_protocol {
+ struct iosm_imem *imem;
+ struct ipc_rsp *rsp_ring[IPC_MEM_MSG_ENTRIES];
+ struct device *dev;
+- phys_addr_t phy_ap_shm;
++ dma_addr_t phy_ap_shm;
+ u32 old_msg_tail;
+ };
+
+diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
+index 01c36284e5428..f612a0ba64d00 100644
+--- a/drivers/nvme/host/core.c
++++ b/drivers/nvme/host/core.c
+@@ -4297,7 +4297,7 @@ static void nvme_ns_remove(struct nvme_ns *ns)
+ mutex_unlock(&ns->ctrl->subsys->lock);
+
+ /* guarantee not available in head->list */
+- synchronize_rcu();
++ synchronize_srcu(&ns->head->srcu);
+
+ if (!nvme_ns_head_multipath(ns->head))
+ nvme_cdev_del(&ns->cdev, &ns->cdev_device);
+diff --git a/drivers/nvme/host/multipath.c b/drivers/nvme/host/multipath.c
+index b9cf17cbbbd5d..114e2b9359f83 100644
+--- a/drivers/nvme/host/multipath.c
++++ b/drivers/nvme/host/multipath.c
+@@ -174,11 +174,14 @@ void nvme_mpath_revalidate_paths(struct nvme_ns *ns)
+ struct nvme_ns_head *head = ns->head;
+ sector_t capacity = get_capacity(head->disk);
+ int node;
++ int srcu_idx;
+
++ srcu_idx = srcu_read_lock(&head->srcu);
+ list_for_each_entry_rcu(ns, &head->list, siblings) {
+ if (capacity != get_capacity(ns->disk))
+ clear_bit(NVME_NS_READY, &ns->flags);
+ }
++ srcu_read_unlock(&head->srcu, srcu_idx);
+
+ for_each_node(node)
+ rcu_assign_pointer(head->current_path[node], NULL);
+diff --git a/drivers/nvmem/rmem.c b/drivers/nvmem/rmem.c
+index b11c3c974b3d6..80cb187f14817 100644
+--- a/drivers/nvmem/rmem.c
++++ b/drivers/nvmem/rmem.c
+@@ -37,9 +37,9 @@ static int rmem_read(void *context, unsigned int offset,
+ * but as of Dec 2020 this isn't possible on arm64.
+ */
+ addr = memremap(priv->mem->base, available, MEMREMAP_WB);
+- if (IS_ERR(addr)) {
++ if (!addr) {
+ dev_err(priv->dev, "Failed to remap memory region\n");
+- return PTR_ERR(addr);
++ return -ENOMEM;
+ }
+
+ count = memory_read_from_buffer(val, bytes, &off, addr, available);
+diff --git a/drivers/of/property.c b/drivers/of/property.c
+index 967f79b590165..134cfc980b70b 100644
+--- a/drivers/of/property.c
++++ b/drivers/of/property.c
+@@ -993,8 +993,10 @@ of_fwnode_get_reference_args(const struct fwnode_handle *fwnode,
+ nargs, index, &of_args);
+ if (ret < 0)
+ return ret;
+- if (!args)
++ if (!args) {
++ of_node_put(of_args.np);
+ return 0;
++ }
+
+ args->nargs = of_args.args_count;
+ args->fwnode = of_fwnode_handle(of_args.np);
+diff --git a/drivers/pinctrl/intel/pinctrl-intel.c b/drivers/pinctrl/intel/pinctrl-intel.c
+index 52ecd66ce357f..047a8374b4fdc 100644
+--- a/drivers/pinctrl/intel/pinctrl-intel.c
++++ b/drivers/pinctrl/intel/pinctrl-intel.c
+@@ -436,9 +436,14 @@ static void __intel_gpio_set_direction(void __iomem *padcfg0, bool input)
+ writel(value, padcfg0);
+ }
+
++static int __intel_gpio_get_gpio_mode(u32 value)
++{
++ return (value & PADCFG0_PMODE_MASK) >> PADCFG0_PMODE_SHIFT;
++}
++
+ static int intel_gpio_get_gpio_mode(void __iomem *padcfg0)
+ {
+- return (readl(padcfg0) & PADCFG0_PMODE_MASK) >> PADCFG0_PMODE_SHIFT;
++ return __intel_gpio_get_gpio_mode(readl(padcfg0));
+ }
+
+ static void intel_gpio_set_gpio_mode(void __iomem *padcfg0)
+@@ -1674,6 +1679,7 @@ EXPORT_SYMBOL_GPL(intel_pinctrl_get_soc_data);
+ static bool intel_pinctrl_should_save(struct intel_pinctrl *pctrl, unsigned int pin)
+ {
+ const struct pin_desc *pd = pin_desc_get(pctrl->pctldev, pin);
++ u32 value;
+
+ if (!pd || !intel_pad_usable(pctrl, pin))
+ return false;
+@@ -1688,6 +1694,25 @@ static bool intel_pinctrl_should_save(struct intel_pinctrl *pctrl, unsigned int
+ gpiochip_line_is_irq(&pctrl->chip, intel_pin_to_gpio(pctrl, pin)))
+ return true;
+
++ /*
++ * The firmware on some systems may configure GPIO pins to be
++ * an interrupt source in so called "direct IRQ" mode. In such
++ * cases the GPIO controller driver has no idea if those pins
++ * are being used or not. At the same time, there is a known bug
++ * in the firmwares that don't restore the pin settings correctly
++ * after suspend, i.e. by an unknown reason the Rx value becomes
++ * inverted.
++ *
++ * Hence, let's save and restore the pins that are configured
++ * as GPIOs in the input mode with GPIROUTIOXAPIC bit set.
++ *
++ * See https://bugzilla.kernel.org/show_bug.cgi?id=214749.
++ */
++ value = readl(intel_get_padcfg(pctrl, pin, PADCFG0));
++ if ((value & PADCFG0_GPIROUTIOXAPIC) && (value & PADCFG0_GPIOTXDIS) &&
++ (__intel_gpio_get_gpio_mode(value) == PADCFG0_PMODE_GPIO))
++ return true;
++
+ return false;
+ }
+
+diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c
+index 67bec7ea0f8b0..414ee6bb8ac98 100644
+--- a/drivers/pinctrl/pinctrl-single.c
++++ b/drivers/pinctrl/pinctrl-single.c
+@@ -727,7 +727,7 @@ static int pcs_allocate_pin_table(struct pcs_device *pcs)
+
+ mux_bytes = pcs->width / BITS_PER_BYTE;
+
+- if (pcs->bits_per_mux) {
++ if (pcs->bits_per_mux && pcs->fmask) {
+ pcs->bits_per_pin = fls(pcs->fmask);
+ nr_pins = (pcs->size * BITS_PER_BYTE) / pcs->bits_per_pin;
+ } else {
+diff --git a/fs/afs/fs_probe.c b/fs/afs/fs_probe.c
+index c0031a3ab42f5..3ac5fcf98d0d6 100644
+--- a/fs/afs/fs_probe.c
++++ b/fs/afs/fs_probe.c
+@@ -167,8 +167,8 @@ responded:
+ clear_bit(AFS_SERVER_FL_HAS_FS64, &server->flags);
+ }
+
+- if (rxrpc_kernel_get_srtt(call->net->socket, call->rxcall, &rtt_us) &&
+- rtt_us < server->probe.rtt) {
++ rxrpc_kernel_get_srtt(call->net->socket, call->rxcall, &rtt_us);
++ if (rtt_us < server->probe.rtt) {
+ server->probe.rtt = rtt_us;
+ server->rtt = rtt_us;
+ alist->preferred = index;
+diff --git a/fs/afs/server.c b/fs/afs/server.c
+index 4981baf97835c..b5237206eac3e 100644
+--- a/fs/afs/server.c
++++ b/fs/afs/server.c
+@@ -406,7 +406,7 @@ void afs_put_server(struct afs_net *net, struct afs_server *server,
+ if (!server)
+ return;
+
+- a = atomic_inc_return(&server->active);
++ a = atomic_read(&server->active);
+ zero = __refcount_dec_and_test(&server->ref, &r);
+ trace_afs_server(debug_id, r - 1, a, reason);
+ if (unlikely(zero))
+diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c
+index ba323dcb0a0b8..db56e0c0e9acc 100644
+--- a/fs/btrfs/qgroup.c
++++ b/fs/btrfs/qgroup.c
+@@ -2920,14 +2920,7 @@ int btrfs_qgroup_inherit(struct btrfs_trans_handle *trans, u64 srcid,
+ dstgroup->rsv_rfer = inherit->lim.rsv_rfer;
+ dstgroup->rsv_excl = inherit->lim.rsv_excl;
+
+- ret = update_qgroup_limit_item(trans, dstgroup);
+- if (ret) {
+- fs_info->qgroup_flags |= BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT;
+- btrfs_info(fs_info,
+- "unable to update quota limit for %llu",
+- dstgroup->qgroupid);
+- goto unlock;
+- }
++ qgroup_dirty(fs_info, dstgroup);
+ }
+
+ if (srcid) {
+diff --git a/fs/ksmbd/vfs.c b/fs/ksmbd/vfs.c
+index 78d01033604c6..c5c801e38b63c 100644
+--- a/fs/ksmbd/vfs.c
++++ b/fs/ksmbd/vfs.c
+@@ -1784,9 +1784,9 @@ int ksmbd_vfs_copy_file_ranges(struct ksmbd_work *work,
+ ret = vfs_copy_file_range(src_fp->filp, src_off,
+ dst_fp->filp, dst_off, len, 0);
+ if (ret == -EOPNOTSUPP || ret == -EXDEV)
+- ret = generic_copy_file_range(src_fp->filp, src_off,
+- dst_fp->filp, dst_off,
+- len, 0);
++ ret = vfs_copy_file_range(src_fp->filp, src_off,
++ dst_fp->filp, dst_off, len,
++ COPY_FILE_SPLICE);
+ if (ret < 0)
+ return ret;
+
+diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
+index f3cd614e1f1e9..dc24d67d0ca4e 100644
+--- a/fs/nfsd/vfs.c
++++ b/fs/nfsd/vfs.c
+@@ -572,8 +572,8 @@ ssize_t nfsd_copy_file_range(struct file *src, u64 src_pos, struct file *dst,
+ ret = vfs_copy_file_range(src, src_pos, dst, dst_pos, count, 0);
+
+ if (ret == -EOPNOTSUPP || ret == -EXDEV)
+- ret = generic_copy_file_range(src, src_pos, dst, dst_pos,
+- count, 0);
++ ret = vfs_copy_file_range(src, src_pos, dst, dst_pos, count,
++ COPY_FILE_SPLICE);
+ return ret;
+ }
+
+diff --git a/fs/nilfs2/dat.c b/fs/nilfs2/dat.c
+index 3b55e239705f4..9930fa901039f 100644
+--- a/fs/nilfs2/dat.c
++++ b/fs/nilfs2/dat.c
+@@ -111,6 +111,13 @@ static void nilfs_dat_commit_free(struct inode *dat,
+ kunmap_atomic(kaddr);
+
+ nilfs_dat_commit_entry(dat, req);
++
++ if (unlikely(req->pr_desc_bh == NULL || req->pr_bitmap_bh == NULL)) {
++ nilfs_error(dat->i_sb,
++ "state inconsistency probably due to duplicate use of vblocknr = %llu",
++ (unsigned long long)req->pr_entry_nr);
++ return;
++ }
+ nilfs_palloc_commit_free_entry(dat, req);
+ }
+
+diff --git a/fs/read_write.c b/fs/read_write.c
+index 328ce8cf9a85e..24b9668d63770 100644
+--- a/fs/read_write.c
++++ b/fs/read_write.c
+@@ -1388,6 +1388,8 @@ ssize_t generic_copy_file_range(struct file *file_in, loff_t pos_in,
+ struct file *file_out, loff_t pos_out,
+ size_t len, unsigned int flags)
+ {
++ lockdep_assert(sb_write_started(file_inode(file_out)->i_sb));
++
+ return do_splice_direct(file_in, &pos_in, file_out, &pos_out,
+ len > MAX_RW_COUNT ? MAX_RW_COUNT : len, 0);
+ }
+@@ -1424,7 +1426,9 @@ static int generic_copy_file_checks(struct file *file_in, loff_t pos_in,
+ * and several different sets of file_operations, but they all end up
+ * using the same ->copy_file_range() function pointer.
+ */
+- if (file_out->f_op->copy_file_range) {
++ if (flags & COPY_FILE_SPLICE) {
++ /* cross sb splice is allowed */
++ } else if (file_out->f_op->copy_file_range) {
+ if (file_in->f_op->copy_file_range !=
+ file_out->f_op->copy_file_range)
+ return -EXDEV;
+@@ -1474,8 +1478,9 @@ ssize_t vfs_copy_file_range(struct file *file_in, loff_t pos_in,
+ size_t len, unsigned int flags)
+ {
+ ssize_t ret;
++ bool splice = flags & COPY_FILE_SPLICE;
+
+- if (flags != 0)
++ if (flags & ~COPY_FILE_SPLICE)
+ return -EINVAL;
+
+ ret = generic_copy_file_checks(file_in, pos_in, file_out, pos_out, &len,
+@@ -1501,14 +1506,14 @@ ssize_t vfs_copy_file_range(struct file *file_in, loff_t pos_in,
+ * same sb using clone, but for filesystems where both clone and copy
+ * are supported (e.g. nfs,cifs), we only call the copy method.
+ */
+- if (file_out->f_op->copy_file_range) {
++ if (!splice && file_out->f_op->copy_file_range) {
+ ret = file_out->f_op->copy_file_range(file_in, pos_in,
+ file_out, pos_out,
+ len, flags);
+ goto done;
+ }
+
+- if (file_in->f_op->remap_file_range &&
++ if (!splice && file_in->f_op->remap_file_range &&
+ file_inode(file_in)->i_sb == file_inode(file_out)->i_sb) {
+ ret = file_in->f_op->remap_file_range(file_in, pos_in,
+ file_out, pos_out,
+@@ -1528,6 +1533,8 @@ ssize_t vfs_copy_file_range(struct file *file_in, loff_t pos_in,
+ * consistent story about which filesystems support copy_file_range()
+ * and which filesystems do not, that will allow userspace tools to
+ * make consistent desicions w.r.t using copy_file_range().
++ *
++ * We also get here if caller (e.g. nfsd) requested COPY_FILE_SPLICE.
+ */
+ ret = generic_copy_file_range(file_in, pos_in, file_out, pos_out, len,
+ flags);
+@@ -1582,6 +1589,10 @@ SYSCALL_DEFINE6(copy_file_range, int, fd_in, loff_t __user *, off_in,
+ pos_out = f_out.file->f_pos;
+ }
+
++ ret = -EINVAL;
++ if (flags != 0)
++ goto out;
++
+ ret = vfs_copy_file_range(f_in.file, pos_in, f_out.file, pos_out, len,
+ flags);
+ if (ret > 0) {
+diff --git a/include/linux/damon.h b/include/linux/damon.h
+index 7b1f4a4882308..98e622c34d44f 100644
+--- a/include/linux/damon.h
++++ b/include/linux/damon.h
+@@ -216,13 +216,26 @@ struct damos_stat {
+ };
+
+ /**
+- * struct damos - Represents a Data Access Monitoring-based Operation Scheme.
++ * struct damos_access_pattern - Target access pattern of the given scheme.
+ * @min_sz_region: Minimum size of target regions.
+ * @max_sz_region: Maximum size of target regions.
+ * @min_nr_accesses: Minimum ``->nr_accesses`` of target regions.
+ * @max_nr_accesses: Maximum ``->nr_accesses`` of target regions.
+ * @min_age_region: Minimum age of target regions.
+ * @max_age_region: Maximum age of target regions.
++ */
++struct damos_access_pattern {
++ unsigned long min_sz_region;
++ unsigned long max_sz_region;
++ unsigned int min_nr_accesses;
++ unsigned int max_nr_accesses;
++ unsigned int min_age_region;
++ unsigned int max_age_region;
++};
++
++/**
++ * struct damos - Represents a Data Access Monitoring-based Operation Scheme.
++ * @pattern: Access pattern of target regions.
+ * @action: &damo_action to be applied to the target regions.
+ * @quota: Control the aggressiveness of this scheme.
+ * @wmarks: Watermarks for automated (in)activation of this scheme.
+@@ -230,10 +243,8 @@ struct damos_stat {
+ * @list: List head for siblings.
+ *
+ * For each aggregation interval, DAMON finds regions which fit in the
+- * condition (&min_sz_region, &max_sz_region, &min_nr_accesses,
+- * &max_nr_accesses, &min_age_region, &max_age_region) and applies &action to
+- * those. To avoid consuming too much CPU time or IO resources for the
+- * &action, &quota is used.
++ * &pattern and applies &action to those. To avoid consuming too much
++ * CPU time or IO resources for the &action, &quota is used.
+ *
+ * To do the work only when needed, schemes can be activated for specific
+ * system situations using &wmarks. If all schemes that registered to the
+@@ -248,12 +259,7 @@ struct damos_stat {
+ * &action is applied.
+ */
+ struct damos {
+- unsigned long min_sz_region;
+- unsigned long max_sz_region;
+- unsigned int min_nr_accesses;
+- unsigned int max_nr_accesses;
+- unsigned int min_age_region;
+- unsigned int max_age_region;
++ struct damos_access_pattern pattern;
+ enum damos_action action;
+ struct damos_quota quota;
+ struct damos_watermarks wmarks;
+@@ -501,12 +507,9 @@ void damon_destroy_region(struct damon_region *r, struct damon_target *t);
+ int damon_set_regions(struct damon_target *t, struct damon_addr_range *ranges,
+ unsigned int nr_ranges);
+
+-struct damos *damon_new_scheme(
+- unsigned long min_sz_region, unsigned long max_sz_region,
+- unsigned int min_nr_accesses, unsigned int max_nr_accesses,
+- unsigned int min_age_region, unsigned int max_age_region,
+- enum damos_action action, struct damos_quota *quota,
+- struct damos_watermarks *wmarks);
++struct damos *damon_new_scheme(struct damos_access_pattern *pattern,
++ enum damos_action action, struct damos_quota *quota,
++ struct damos_watermarks *wmarks);
+ void damon_add_scheme(struct damon_ctx *ctx, struct damos *s);
+ void damon_destroy_scheme(struct damos *s);
+
+diff --git a/include/linux/fs.h b/include/linux/fs.h
+index 7203f5582fd44..be074b6895b97 100644
+--- a/include/linux/fs.h
++++ b/include/linux/fs.h
+@@ -2087,6 +2087,14 @@ struct dir_context {
+ */
+ #define REMAP_FILE_ADVISORY (REMAP_FILE_CAN_SHORTEN)
+
++/*
++ * These flags control the behavior of vfs_copy_file_range().
++ * They are not available to the user via syscall.
++ *
++ * COPY_FILE_SPLICE: call splice direct instead of fs clone/copy ops
++ */
++#define COPY_FILE_SPLICE (1 << 0)
++
+ struct iov_iter;
+ struct io_uring_cmd;
+
+diff --git a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h
+index 9c50bc40f8ff3..6f7993803ee78 100644
+--- a/include/linux/mmc/mmc.h
++++ b/include/linux/mmc/mmc.h
+@@ -451,7 +451,7 @@ static inline bool mmc_ready_for_data(u32 status)
+ #define MMC_SECURE_TRIM1_ARG 0x80000001
+ #define MMC_SECURE_TRIM2_ARG 0x80008000
+ #define MMC_SECURE_ARGS 0x80000000
+-#define MMC_TRIM_ARGS 0x00008001
++#define MMC_TRIM_OR_DISCARD_ARGS 0x00008003
+
+ #define mmc_driver_type_mask(n) (1 << (n))
+
+diff --git a/include/net/sctp/stream_sched.h b/include/net/sctp/stream_sched.h
+index 01a70b27e026b..65058faea4db1 100644
+--- a/include/net/sctp/stream_sched.h
++++ b/include/net/sctp/stream_sched.h
+@@ -26,6 +26,8 @@ struct sctp_sched_ops {
+ int (*init)(struct sctp_stream *stream);
+ /* Init a stream */
+ int (*init_sid)(struct sctp_stream *stream, __u16 sid, gfp_t gfp);
++ /* free a stream */
++ void (*free_sid)(struct sctp_stream *stream, __u16 sid);
+ /* Frees the entire thing */
+ void (*free)(struct sctp_stream *stream);
+
+diff --git a/ipc/sem.c b/ipc/sem.c
+index c8496f98b1391..00f88aa01ac5a 100644
+--- a/ipc/sem.c
++++ b/ipc/sem.c
+@@ -2179,14 +2179,15 @@ long __do_semtimedop(int semid, struct sembuf *sops,
+ * scenarios where we were awakened externally, during the
+ * window between wake_q_add() and wake_up_q().
+ */
++ rcu_read_lock();
+ error = READ_ONCE(queue.status);
+ if (error != -EINTR) {
+ /* see SEM_BARRIER_2 for purpose/pairing */
+ smp_acquire__after_ctrl_dep();
++ rcu_read_unlock();
+ goto out;
+ }
+
+- rcu_read_lock();
+ locknum = sem_lock(sma, sops, nsops);
+
+ if (!ipc_valid_object(&sma->sem_perm))
+diff --git a/kernel/bpf/bpf_local_storage.c b/kernel/bpf/bpf_local_storage.c
+index d13ffb00e9813..cbe918ba9035d 100644
+--- a/kernel/bpf/bpf_local_storage.c
++++ b/kernel/bpf/bpf_local_storage.c
+@@ -74,7 +74,7 @@ bpf_selem_alloc(struct bpf_local_storage_map *smap, void *owner,
+ gfp_flags | __GFP_NOWARN);
+ if (selem) {
+ if (value)
+- memcpy(SDATA(selem)->data, value, smap->map.value_size);
++ copy_map_value(&smap->map, SDATA(selem)->data, value);
+ return selem;
+ }
+
+diff --git a/kernel/events/core.c b/kernel/events/core.c
+index bec18d81b1161..8dcbefd90b7f6 100644
+--- a/kernel/events/core.c
++++ b/kernel/events/core.c
+@@ -9006,7 +9006,7 @@ static void perf_event_bpf_emit_ksymbols(struct bpf_prog *prog,
+ PERF_RECORD_KSYMBOL_TYPE_BPF,
+ (u64)(unsigned long)subprog->bpf_func,
+ subprog->jited_len, unregister,
+- prog->aux->ksym.name);
++ subprog->aux->ksym.name);
+ }
+ }
+ }
+diff --git a/kernel/sysctl.c b/kernel/sysctl.c
+index 205d605cacc5b..e9a3094c52e57 100644
+--- a/kernel/sysctl.c
++++ b/kernel/sysctl.c
+@@ -265,13 +265,14 @@ int proc_dostring(struct ctl_table *table, int write,
+ ppos);
+ }
+
+-static size_t proc_skip_spaces(char **buf)
++static void proc_skip_spaces(char **buf, size_t *size)
+ {
+- size_t ret;
+- char *tmp = skip_spaces(*buf);
+- ret = tmp - *buf;
+- *buf = tmp;
+- return ret;
++ while (*size) {
++ if (!isspace(**buf))
++ break;
++ (*size)--;
++ (*buf)++;
++ }
+ }
+
+ static void proc_skip_char(char **buf, size_t *size, const char v)
+@@ -340,13 +341,12 @@ static int proc_get_long(char **buf, size_t *size,
+ unsigned long *val, bool *neg,
+ const char *perm_tr, unsigned perm_tr_len, char *tr)
+ {
+- int len;
+ char *p, tmp[TMPBUFLEN];
++ ssize_t len = *size;
+
+- if (!*size)
++ if (len <= 0)
+ return -EINVAL;
+
+- len = *size;
+ if (len > TMPBUFLEN - 1)
+ len = TMPBUFLEN - 1;
+
+@@ -519,7 +519,7 @@ static int __do_proc_dointvec(void *tbl_data, struct ctl_table *table,
+ bool neg;
+
+ if (write) {
+- left -= proc_skip_spaces(&p);
++ proc_skip_spaces(&p, &left);
+
+ if (!left)
+ break;
+@@ -546,7 +546,7 @@ static int __do_proc_dointvec(void *tbl_data, struct ctl_table *table,
+ if (!write && !first && left && !err)
+ proc_put_char(&buffer, &left, '\n');
+ if (write && !err && left)
+- left -= proc_skip_spaces(&p);
++ proc_skip_spaces(&p, &left);
+ if (write && first)
+ return err ? : -EINVAL;
+ *lenp -= left;
+@@ -588,7 +588,7 @@ static int do_proc_douintvec_w(unsigned int *tbl_data,
+ if (left > PAGE_SIZE - 1)
+ left = PAGE_SIZE - 1;
+
+- left -= proc_skip_spaces(&p);
++ proc_skip_spaces(&p, &left);
+ if (!left) {
+ err = -EINVAL;
+ goto out_free;
+@@ -608,7 +608,7 @@ static int do_proc_douintvec_w(unsigned int *tbl_data,
+ }
+
+ if (!err && left)
+- left -= proc_skip_spaces(&p);
++ proc_skip_spaces(&p, &left);
+
+ out_free:
+ if (err)
+@@ -1073,7 +1073,7 @@ static int __do_proc_doulongvec_minmax(void *data, struct ctl_table *table,
+ if (write) {
+ bool neg;
+
+- left -= proc_skip_spaces(&p);
++ proc_skip_spaces(&p, &left);
+ if (!left)
+ break;
+
+@@ -1102,7 +1102,7 @@ static int __do_proc_doulongvec_minmax(void *data, struct ctl_table *table,
+ if (!write && !first && left && !err)
+ proc_put_char(&buffer, &left, '\n');
+ if (write && !err)
+- left -= proc_skip_spaces(&p);
++ proc_skip_spaces(&p, &left);
+ if (write && first)
+ return err ? : -EINVAL;
+ *lenp -= left;
+diff --git a/kernel/trace/trace_dynevent.c b/kernel/trace/trace_dynevent.c
+index 154996684fb54..4376887e0d8aa 100644
+--- a/kernel/trace/trace_dynevent.c
++++ b/kernel/trace/trace_dynevent.c
+@@ -118,6 +118,7 @@ int dyn_event_release(const char *raw_command, struct dyn_event_operations *type
+ if (ret)
+ break;
+ }
++ tracing_reset_all_online_cpus();
+ mutex_unlock(&event_mutex);
+ out:
+ argv_free(argv);
+@@ -214,6 +215,7 @@ int dyn_events_release_all(struct dyn_event_operations *type)
+ break;
+ }
+ out:
++ tracing_reset_all_online_cpus();
+ mutex_unlock(&event_mutex);
+
+ return ret;
+diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c
+index 0356cae0cf74e..bf18b13495713 100644
+--- a/kernel/trace/trace_events.c
++++ b/kernel/trace/trace_events.c
+@@ -2880,7 +2880,10 @@ static int probe_remove_event_call(struct trace_event_call *call)
+ * TRACE_REG_UNREGISTER.
+ */
+ if (file->flags & EVENT_FILE_FL_ENABLED)
+- return -EBUSY;
++ goto busy;
++
++ if (file->flags & EVENT_FILE_FL_WAS_ENABLED)
++ tr->clear_trace = true;
+ /*
+ * The do_for_each_event_file_safe() is
+ * a double loop. After finding the call for this
+@@ -2893,6 +2896,12 @@ static int probe_remove_event_call(struct trace_event_call *call)
+ __trace_remove_event_call(call);
+
+ return 0;
++ busy:
++ /* No need to clear the trace now */
++ list_for_each_entry(tr, &ftrace_trace_arrays, list) {
++ tr->clear_trace = false;
++ }
++ return -EBUSY;
+ }
+
+ /* Remove an event_call */
+diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c
+index fdf784620c283..49243e8617148 100644
+--- a/kernel/trace/trace_events_hist.c
++++ b/kernel/trace/trace_events_hist.c
+@@ -5051,6 +5051,9 @@ static void event_hist_trigger(struct event_trigger_data *data,
+ void *key = NULL;
+ unsigned int i;
+
++ if (unlikely(!rbe))
++ return;
++
+ memset(compound_key, 0, hist_data->key_size);
+
+ for_each_hist_key_field(i, hist_data) {
+diff --git a/kernel/trace/trace_osnoise.c b/kernel/trace/trace_osnoise.c
+index 78d536d3ff3db..4300c5dc4e5db 100644
+--- a/kernel/trace/trace_osnoise.c
++++ b/kernel/trace/trace_osnoise.c
+@@ -917,7 +917,7 @@ void osnoise_trace_irq_entry(int id)
+ void osnoise_trace_irq_exit(int id, const char *desc)
+ {
+ struct osnoise_variables *osn_var = this_cpu_osn_var();
+- int duration;
++ s64 duration;
+
+ if (!osn_var->sampling)
+ return;
+@@ -1048,7 +1048,7 @@ static void trace_softirq_entry_callback(void *data, unsigned int vec_nr)
+ static void trace_softirq_exit_callback(void *data, unsigned int vec_nr)
+ {
+ struct osnoise_variables *osn_var = this_cpu_osn_var();
+- int duration;
++ s64 duration;
+
+ if (!osn_var->sampling)
+ return;
+@@ -1144,7 +1144,7 @@ thread_entry(struct osnoise_variables *osn_var, struct task_struct *t)
+ static void
+ thread_exit(struct osnoise_variables *osn_var, struct task_struct *t)
+ {
+- int duration;
++ s64 duration;
+
+ if (!osn_var->sampling)
+ return;
+diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
+index 997d23641448a..88f34cdeef023 100644
+--- a/lib/Kconfig.debug
++++ b/lib/Kconfig.debug
+@@ -398,6 +398,7 @@ config FRAME_WARN
+ default 2048 if GCC_PLUGIN_LATENT_ENTROPY
+ default 2048 if PARISC
+ default 1536 if (!64BIT && XTENSA)
++ default 1280 if KASAN && !64BIT
+ default 1024 if !64BIT
+ default 2048 if 64BIT
+ help
+@@ -1862,8 +1863,14 @@ config NETDEV_NOTIFIER_ERROR_INJECT
+ If unsure, say N.
+
+ config FUNCTION_ERROR_INJECTION
+- def_bool y
++ bool "Fault-injections of functions"
+ depends on HAVE_FUNCTION_ERROR_INJECTION && KPROBES
++ help
++ Add fault injections into various functions that are annotated with
++ ALLOW_ERROR_INJECTION() in the kernel. BPF may also modify the return
++ value of theses functions. This is useful to test error paths of code.
++
++ If unsure, say N
+
+ config FAULT_INJECTION
+ bool "Fault-injection framework"
+diff --git a/mm/compaction.c b/mm/compaction.c
+index 640fa76228dd9..88fea74c3a86b 100644
+--- a/mm/compaction.c
++++ b/mm/compaction.c
+@@ -986,29 +986,29 @@ isolate_migratepages_block(struct compact_control *cc, unsigned long low_pfn,
+ goto isolate_fail;
+ }
+
++ /*
++ * Be careful not to clear PageLRU until after we're
++ * sure the page is not being freed elsewhere -- the
++ * page release code relies on it.
++ */
++ if (unlikely(!get_page_unless_zero(page)))
++ goto isolate_fail;
++
+ /*
+ * Migration will fail if an anonymous page is pinned in memory,
+ * so avoid taking lru_lock and isolating it unnecessarily in an
+ * admittedly racy check.
+ */
+ mapping = page_mapping(page);
+- if (!mapping && page_count(page) > page_mapcount(page))
+- goto isolate_fail;
++ if (!mapping && (page_count(page) - 1) > total_mapcount(page))
++ goto isolate_fail_put;
+
+ /*
+ * Only allow to migrate anonymous pages in GFP_NOFS context
+ * because those do not depend on fs locks.
+ */
+ if (!(cc->gfp_mask & __GFP_FS) && mapping)
+- goto isolate_fail;
+-
+- /*
+- * Be careful not to clear PageLRU until after we're
+- * sure the page is not being freed elsewhere -- the
+- * page release code relies on it.
+- */
+- if (unlikely(!get_page_unless_zero(page)))
+- goto isolate_fail;
++ goto isolate_fail_put;
+
+ /* Only take pages on LRU: a check now makes later tests safe */
+ if (!PageLRU(page))
+diff --git a/mm/damon/core.c b/mm/damon/core.c
+index 7d25dc582fe34..7d5a9ae6f4ac9 100644
+--- a/mm/damon/core.c
++++ b/mm/damon/core.c
+@@ -230,24 +230,21 @@ int damon_set_regions(struct damon_target *t, struct damon_addr_range *ranges,
+ return 0;
+ }
+
+-struct damos *damon_new_scheme(
+- unsigned long min_sz_region, unsigned long max_sz_region,
+- unsigned int min_nr_accesses, unsigned int max_nr_accesses,
+- unsigned int min_age_region, unsigned int max_age_region,
+- enum damos_action action, struct damos_quota *quota,
+- struct damos_watermarks *wmarks)
++struct damos *damon_new_scheme(struct damos_access_pattern *pattern,
++ enum damos_action action, struct damos_quota *quota,
++ struct damos_watermarks *wmarks)
+ {
+ struct damos *scheme;
+
+ scheme = kmalloc(sizeof(*scheme), GFP_KERNEL);
+ if (!scheme)
+ return NULL;
+- scheme->min_sz_region = min_sz_region;
+- scheme->max_sz_region = max_sz_region;
+- scheme->min_nr_accesses = min_nr_accesses;
+- scheme->max_nr_accesses = max_nr_accesses;
+- scheme->min_age_region = min_age_region;
+- scheme->max_age_region = max_age_region;
++ scheme->pattern.min_sz_region = pattern->min_sz_region;
++ scheme->pattern.max_sz_region = pattern->max_sz_region;
++ scheme->pattern.min_nr_accesses = pattern->min_nr_accesses;
++ scheme->pattern.max_nr_accesses = pattern->max_nr_accesses;
++ scheme->pattern.min_age_region = pattern->min_age_region;
++ scheme->pattern.max_age_region = pattern->max_age_region;
+ scheme->action = action;
+ scheme->stat = (struct damos_stat){};
+ INIT_LIST_HEAD(&scheme->list);
+@@ -667,10 +664,12 @@ static bool __damos_valid_target(struct damon_region *r, struct damos *s)
+ unsigned long sz;
+
+ sz = r->ar.end - r->ar.start;
+- return s->min_sz_region <= sz && sz <= s->max_sz_region &&
+- s->min_nr_accesses <= r->nr_accesses &&
+- r->nr_accesses <= s->max_nr_accesses &&
+- s->min_age_region <= r->age && r->age <= s->max_age_region;
++ return s->pattern.min_sz_region <= sz &&
++ sz <= s->pattern.max_sz_region &&
++ s->pattern.min_nr_accesses <= r->nr_accesses &&
++ r->nr_accesses <= s->pattern.max_nr_accesses &&
++ s->pattern.min_age_region <= r->age &&
++ r->age <= s->pattern.max_age_region;
+ }
+
+ static bool damos_valid_target(struct damon_ctx *c, struct damon_target *t,
+diff --git a/mm/damon/dbgfs.c b/mm/damon/dbgfs.c
+index dafe7e71329b8..61214cb9a5d3c 100644
+--- a/mm/damon/dbgfs.c
++++ b/mm/damon/dbgfs.c
+@@ -131,9 +131,12 @@ static ssize_t sprint_schemes(struct damon_ctx *c, char *buf, ssize_t len)
+ damon_for_each_scheme(s, c) {
+ rc = scnprintf(&buf[written], len - written,
+ "%lu %lu %u %u %u %u %d %lu %lu %lu %u %u %u %d %lu %lu %lu %lu %lu %lu %lu %lu %lu\n",
+- s->min_sz_region, s->max_sz_region,
+- s->min_nr_accesses, s->max_nr_accesses,
+- s->min_age_region, s->max_age_region,
++ s->pattern.min_sz_region,
++ s->pattern.max_sz_region,
++ s->pattern.min_nr_accesses,
++ s->pattern.max_nr_accesses,
++ s->pattern.min_age_region,
++ s->pattern.max_age_region,
+ damos_action_to_dbgfs_scheme_action(s->action),
+ s->quota.ms, s->quota.sz,
+ s->quota.reset_interval,
+@@ -221,8 +224,6 @@ static struct damos **str_to_schemes(const char *str, ssize_t len,
+ struct damos *scheme, **schemes;
+ const int max_nr_schemes = 256;
+ int pos = 0, parsed, ret;
+- unsigned long min_sz, max_sz;
+- unsigned int min_nr_a, max_nr_a, min_age, max_age;
+ unsigned int action_input;
+ enum damos_action action;
+
+@@ -233,13 +234,18 @@ static struct damos **str_to_schemes(const char *str, ssize_t len,
+
+ *nr_schemes = 0;
+ while (pos < len && *nr_schemes < max_nr_schemes) {
++ struct damos_access_pattern pattern = {};
+ struct damos_quota quota = {};
+ struct damos_watermarks wmarks;
+
+ ret = sscanf(&str[pos],
+ "%lu %lu %u %u %u %u %u %lu %lu %lu %u %u %u %u %lu %lu %lu %lu%n",
+- &min_sz, &max_sz, &min_nr_a, &max_nr_a,
+- &min_age, &max_age, &action_input, &quota.ms,
++ &pattern.min_sz_region, &pattern.max_sz_region,
++ &pattern.min_nr_accesses,
++ &pattern.max_nr_accesses,
++ &pattern.min_age_region,
++ &pattern.max_age_region,
++ &action_input, &quota.ms,
+ &quota.sz, &quota.reset_interval,
+ &quota.weight_sz, &quota.weight_nr_accesses,
+ &quota.weight_age, &wmarks.metric,
+@@ -251,7 +257,9 @@ static struct damos **str_to_schemes(const char *str, ssize_t len,
+ if ((int)action < 0)
+ goto fail;
+
+- if (min_sz > max_sz || min_nr_a > max_nr_a || min_age > max_age)
++ if (pattern.min_sz_region > pattern.max_sz_region ||
++ pattern.min_nr_accesses > pattern.max_nr_accesses ||
++ pattern.min_age_region > pattern.max_age_region)
+ goto fail;
+
+ if (wmarks.high < wmarks.mid || wmarks.high < wmarks.low ||
+@@ -259,8 +267,7 @@ static struct damos **str_to_schemes(const char *str, ssize_t len,
+ goto fail;
+
+ pos += parsed;
+- scheme = damon_new_scheme(min_sz, max_sz, min_nr_a, max_nr_a,
+- min_age, max_age, action, &quota, &wmarks);
++ scheme = damon_new_scheme(&pattern, action, &quota, &wmarks);
+ if (!scheme)
+ goto fail;
+
+diff --git a/mm/damon/lru_sort.c b/mm/damon/lru_sort.c
+index 9de6f00a71c5d..0184ed4828b7e 100644
+--- a/mm/damon/lru_sort.c
++++ b/mm/damon/lru_sort.c
+@@ -293,6 +293,17 @@ static bool get_monitoring_region(unsigned long *start, unsigned long *end)
+ /* Create a DAMON-based operation scheme for hot memory regions */
+ static struct damos *damon_lru_sort_new_hot_scheme(unsigned int hot_thres)
+ {
++ struct damos_access_pattern pattern = {
++ /* Find regions having PAGE_SIZE or larger size */
++ .min_sz_region = PAGE_SIZE,
++ .max_sz_region = ULONG_MAX,
++ /* and accessed for more than the threshold */
++ .min_nr_accesses = hot_thres,
++ .max_nr_accesses = UINT_MAX,
++ /* no matter its age */
++ .min_age_region = 0,
++ .max_age_region = UINT_MAX,
++ };
+ struct damos_watermarks wmarks = {
+ .metric = DAMOS_WMARK_FREE_MEM_RATE,
+ .interval = wmarks_interval,
+@@ -313,26 +324,31 @@ static struct damos *damon_lru_sort_new_hot_scheme(unsigned int hot_thres)
+ .weight_nr_accesses = 1,
+ .weight_age = 0,
+ };
+- struct damos *scheme = damon_new_scheme(
+- /* Find regions having PAGE_SIZE or larger size */
+- PAGE_SIZE, ULONG_MAX,
+- /* and accessed for more than the threshold */
+- hot_thres, UINT_MAX,
+- /* no matter its age */
+- 0, UINT_MAX,
++
++ return damon_new_scheme(
++ &pattern,
+ /* prioritize those on LRU lists, as soon as found */
+ DAMOS_LRU_PRIO,
+ /* under the quota. */
+ &quota,
+ /* (De)activate this according to the watermarks. */
+ &wmarks);
+-
+- return scheme;
+ }
+
+ /* Create a DAMON-based operation scheme for cold memory regions */
+ static struct damos *damon_lru_sort_new_cold_scheme(unsigned int cold_thres)
+ {
++ struct damos_access_pattern pattern = {
++ /* Find regions having PAGE_SIZE or larger size */
++ .min_sz_region = PAGE_SIZE,
++ .max_sz_region = ULONG_MAX,
++ /* and not accessed at all */
++ .min_nr_accesses = 0,
++ .max_nr_accesses = 0,
++ /* for min_age or more micro-seconds */
++ .min_age_region = cold_thres,
++ .max_age_region = UINT_MAX,
++ };
+ struct damos_watermarks wmarks = {
+ .metric = DAMOS_WMARK_FREE_MEM_RATE,
+ .interval = wmarks_interval,
+@@ -354,21 +370,15 @@ static struct damos *damon_lru_sort_new_cold_scheme(unsigned int cold_thres)
+ .weight_nr_accesses = 0,
+ .weight_age = 1,
+ };
+- struct damos *scheme = damon_new_scheme(
+- /* Find regions having PAGE_SIZE or larger size */
+- PAGE_SIZE, ULONG_MAX,
+- /* and not accessed at all */
+- 0, 0,
+- /* for cold_thres or more micro-seconds, and */
+- cold_thres, UINT_MAX,
++
++ return damon_new_scheme(
++ &pattern,
+ /* mark those as not accessed, as soon as found */
+ DAMOS_LRU_DEPRIO,
+ /* under the quota. */
+ &quota,
+ /* (De)activate this according to the watermarks. */
+ &wmarks);
+-
+- return scheme;
+ }
+
+ static int damon_lru_sort_apply_parameters(void)
+diff --git a/mm/damon/reclaim.c b/mm/damon/reclaim.c
+index a7faf51b4bd4a..5aeca0b9e88ec 100644
+--- a/mm/damon/reclaim.c
++++ b/mm/damon/reclaim.c
+@@ -264,6 +264,17 @@ static bool get_monitoring_region(unsigned long *start, unsigned long *end)
+
+ static struct damos *damon_reclaim_new_scheme(void)
+ {
++ struct damos_access_pattern pattern = {
++ /* Find regions having PAGE_SIZE or larger size */
++ .min_sz_region = PAGE_SIZE,
++ .max_sz_region = ULONG_MAX,
++ /* and not accessed at all */
++ .min_nr_accesses = 0,
++ .max_nr_accesses = 0,
++ /* for min_age or more micro-seconds */
++ .min_age_region = min_age / aggr_interval,
++ .max_age_region = UINT_MAX,
++ };
+ struct damos_watermarks wmarks = {
+ .metric = DAMOS_WMARK_FREE_MEM_RATE,
+ .interval = wmarks_interval,
+@@ -284,21 +295,15 @@ static struct damos *damon_reclaim_new_scheme(void)
+ .weight_nr_accesses = 0,
+ .weight_age = 1
+ };
+- struct damos *scheme = damon_new_scheme(
+- /* Find regions having PAGE_SIZE or larger size */
+- PAGE_SIZE, ULONG_MAX,
+- /* and not accessed at all */
+- 0, 0,
+- /* for min_age or more micro-seconds, and */
+- min_age / aggr_interval, UINT_MAX,
++
++ return damon_new_scheme(
++ &pattern,
+ /* page out those, as soon as found */
+ DAMOS_PAGEOUT,
+ /* under the quota. */
+ &quota,
+ /* (De)activate this according to the watermarks. */
+ &wmarks);
+-
+- return scheme;
+ }
+
+ static int damon_reclaim_apply_parameters(void)
+diff --git a/mm/damon/sysfs.c b/mm/damon/sysfs.c
+index b4b9614eecbed..1b782ca413965 100644
+--- a/mm/damon/sysfs.c
++++ b/mm/damon/sysfs.c
+@@ -2259,11 +2259,20 @@ static int damon_sysfs_set_targets(struct damon_ctx *ctx,
+ static struct damos *damon_sysfs_mk_scheme(
+ struct damon_sysfs_scheme *sysfs_scheme)
+ {
+- struct damon_sysfs_access_pattern *pattern =
++ struct damon_sysfs_access_pattern *access_pattern =
+ sysfs_scheme->access_pattern;
+ struct damon_sysfs_quotas *sysfs_quotas = sysfs_scheme->quotas;
+ struct damon_sysfs_weights *sysfs_weights = sysfs_quotas->weights;
+ struct damon_sysfs_watermarks *sysfs_wmarks = sysfs_scheme->watermarks;
++
++ struct damos_access_pattern pattern = {
++ .min_sz_region = access_pattern->sz->min,
++ .max_sz_region = access_pattern->sz->max,
++ .min_nr_accesses = access_pattern->nr_accesses->min,
++ .max_nr_accesses = access_pattern->nr_accesses->max,
++ .min_age_region = access_pattern->age->min,
++ .max_age_region = access_pattern->age->max,
++ };
+ struct damos_quota quota = {
+ .ms = sysfs_quotas->ms,
+ .sz = sysfs_quotas->sz,
+@@ -2280,18 +2289,58 @@ static struct damos *damon_sysfs_mk_scheme(
+ .low = sysfs_wmarks->low,
+ };
+
+- return damon_new_scheme(pattern->sz->min, pattern->sz->max,
+- pattern->nr_accesses->min, pattern->nr_accesses->max,
+- pattern->age->min, pattern->age->max,
+- sysfs_scheme->action, &quota, &wmarks);
++ return damon_new_scheme(&pattern, sysfs_scheme->action, &quota,
++ &wmarks);
++}
++
++static void damon_sysfs_update_scheme(struct damos *scheme,
++ struct damon_sysfs_scheme *sysfs_scheme)
++{
++ struct damon_sysfs_access_pattern *access_pattern =
++ sysfs_scheme->access_pattern;
++ struct damon_sysfs_quotas *sysfs_quotas = sysfs_scheme->quotas;
++ struct damon_sysfs_weights *sysfs_weights = sysfs_quotas->weights;
++ struct damon_sysfs_watermarks *sysfs_wmarks = sysfs_scheme->watermarks;
++
++ scheme->pattern.min_sz_region = access_pattern->sz->min;
++ scheme->pattern.max_sz_region = access_pattern->sz->max;
++ scheme->pattern.min_nr_accesses = access_pattern->nr_accesses->min;
++ scheme->pattern.max_nr_accesses = access_pattern->nr_accesses->max;
++ scheme->pattern.min_age_region = access_pattern->age->min;
++ scheme->pattern.max_age_region = access_pattern->age->max;
++
++ scheme->action = sysfs_scheme->action;
++
++ scheme->quota.ms = sysfs_quotas->ms;
++ scheme->quota.sz = sysfs_quotas->sz;
++ scheme->quota.reset_interval = sysfs_quotas->reset_interval_ms;
++ scheme->quota.weight_sz = sysfs_weights->sz;
++ scheme->quota.weight_nr_accesses = sysfs_weights->nr_accesses;
++ scheme->quota.weight_age = sysfs_weights->age;
++
++ scheme->wmarks.metric = sysfs_wmarks->metric;
++ scheme->wmarks.interval = sysfs_wmarks->interval_us;
++ scheme->wmarks.high = sysfs_wmarks->high;
++ scheme->wmarks.mid = sysfs_wmarks->mid;
++ scheme->wmarks.low = sysfs_wmarks->low;
+ }
+
+ static int damon_sysfs_set_schemes(struct damon_ctx *ctx,
+ struct damon_sysfs_schemes *sysfs_schemes)
+ {
+- int i;
++ struct damos *scheme, *next;
++ int i = 0;
++
++ damon_for_each_scheme_safe(scheme, next, ctx) {
++ if (i < sysfs_schemes->nr)
++ damon_sysfs_update_scheme(scheme,
++ sysfs_schemes->schemes_arr[i]);
++ else
++ damon_destroy_scheme(scheme);
++ i++;
++ }
+
+- for (i = 0; i < sysfs_schemes->nr; i++) {
++ for (; i < sysfs_schemes->nr; i++) {
+ struct damos *scheme, *next;
+
+ scheme = damon_sysfs_mk_scheme(sysfs_schemes->schemes_arr[i]);
+diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c
+index 8487321c1fc78..3e056fb043bb1 100644
+--- a/net/9p/trans_fd.c
++++ b/net/9p/trans_fd.c
+@@ -862,8 +862,10 @@ static int p9_socket_open(struct p9_client *client, struct socket *csocket)
+ struct file *file;
+
+ p = kzalloc(sizeof(struct p9_trans_fd), GFP_KERNEL);
+- if (!p)
++ if (!p) {
++ sock_release(csocket);
+ return -ENOMEM;
++ }
+
+ csocket->sk->sk_allocation = GFP_NOIO;
+ file = sock_alloc_file(csocket, 0, NULL);
+diff --git a/net/hsr/hsr_forward.c b/net/hsr/hsr_forward.c
+index a50429a62f744..56bb27d67a2ee 100644
+--- a/net/hsr/hsr_forward.c
++++ b/net/hsr/hsr_forward.c
+@@ -351,17 +351,18 @@ static void hsr_deliver_master(struct sk_buff *skb, struct net_device *dev,
+ struct hsr_node *node_src)
+ {
+ bool was_multicast_frame;
+- int res;
++ int res, recv_len;
+
+ was_multicast_frame = (skb->pkt_type == PACKET_MULTICAST);
+ hsr_addr_subst_source(node_src, skb);
+ skb_pull(skb, ETH_HLEN);
++ recv_len = skb->len;
+ res = netif_rx(skb);
+ if (res == NET_RX_DROP) {
+ dev->stats.rx_dropped++;
+ } else {
+ dev->stats.rx_packets++;
+- dev->stats.rx_bytes += skb->len;
++ dev->stats.rx_bytes += recv_len;
+ if (was_multicast_frame)
+ dev->stats.multicast++;
+ }
+diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c
+index 2dc97583d2790..cb24260692e10 100644
+--- a/net/ipv4/fib_semantics.c
++++ b/net/ipv4/fib_semantics.c
+@@ -888,13 +888,15 @@ int fib_nh_match(struct net *net, struct fib_config *cfg, struct fib_info *fi,
+ return 1;
+ }
+
++ if (fi->nh) {
++ if (cfg->fc_oif || cfg->fc_gw_family || cfg->fc_mp)
++ return 1;
++ return 0;
++ }
++
+ if (cfg->fc_oif || cfg->fc_gw_family) {
+ struct fib_nh *nh;
+
+- /* cannot match on nexthop object attributes */
+- if (fi->nh)
+- return 1;
+-
+ nh = fib_info_nh(fi, 0);
+ if (cfg->fc_encap) {
+ if (fib_encap_match(net, cfg->fc_encap_type,
+diff --git a/net/mac80211/airtime.c b/net/mac80211/airtime.c
+index 2e66598fac791..e8ebd343e2bff 100644
+--- a/net/mac80211/airtime.c
++++ b/net/mac80211/airtime.c
+@@ -452,6 +452,9 @@ static u32 ieee80211_get_rate_duration(struct ieee80211_hw *hw,
+ (status->encoding == RX_ENC_HE && streams > 8)))
+ return 0;
+
++ if (idx >= MCS_GROUP_RATES)
++ return 0;
++
+ duration = airtime_mcs_groups[group].duration[idx];
+ duration <<= airtime_mcs_groups[group].shift;
+ *overhead = 36 + (streams << 2);
+diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
+index b568f55998f3c..42d5e0a7952ae 100644
+--- a/net/mptcp/protocol.c
++++ b/net/mptcp/protocol.c
+@@ -2297,12 +2297,7 @@ static void __mptcp_close_ssk(struct sock *sk, struct sock *ssk,
+ goto out;
+ }
+
+- /* if we are invoked by the msk cleanup code, the subflow is
+- * already orphaned
+- */
+- if (ssk->sk_socket)
+- sock_orphan(ssk);
+-
++ sock_orphan(ssk);
+ subflow->disposable = 1;
+
+ /* if ssk hit tcp_done(), tcp_cleanup_ulp() cleared the related ops
+@@ -2833,7 +2828,11 @@ cleanup:
+ if (ssk == msk->first)
+ subflow->fail_tout = 0;
+
+- sock_orphan(ssk);
++ /* detach from the parent socket, but allow data_ready to
++ * push incoming data into the mptcp stack, to properly ack it
++ */
++ ssk->sk_socket = NULL;
++ ssk->sk_wq = NULL;
+ unlock_sock_fast(ssk, slow);
+ }
+ sock_orphan(sk);
+diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c
+index 02a54d59697b5..2159b5f9988f8 100644
+--- a/net/mptcp/subflow.c
++++ b/net/mptcp/subflow.c
+@@ -1745,16 +1745,16 @@ void mptcp_subflow_queue_clean(struct sock *listener_ssk)
+
+ for (msk = head; msk; msk = next) {
+ struct sock *sk = (struct sock *)msk;
+- bool slow, do_cancel_work;
++ bool do_cancel_work;
+
+ sock_hold(sk);
+- slow = lock_sock_fast_nested(sk);
++ lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
+ next = msk->dl_next;
+ msk->first = NULL;
+ msk->dl_next = NULL;
+
+ do_cancel_work = __mptcp_close(sk, 0);
+- unlock_sock_fast(sk, slow);
++ release_sock(sk);
+ if (do_cancel_work)
+ mptcp_cancel_work(sk);
+ sock_put(sk);
+diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
+index 5cbe07116e04e..5727cb7ec1747 100644
+--- a/net/packet/af_packet.c
++++ b/net/packet/af_packet.c
+@@ -2293,8 +2293,7 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev,
+ if (skb->ip_summed == CHECKSUM_PARTIAL)
+ status |= TP_STATUS_CSUMNOTREADY;
+ else if (skb->pkt_type != PACKET_OUTGOING &&
+- (skb->ip_summed == CHECKSUM_COMPLETE ||
+- skb_csum_unnecessary(skb)))
++ skb_csum_unnecessary(skb))
+ status |= TP_STATUS_CSUM_VALID;
+
+ if (snaplen > res)
+@@ -3520,8 +3519,7 @@ static int packet_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
+ if (skb->ip_summed == CHECKSUM_PARTIAL)
+ aux.tp_status |= TP_STATUS_CSUMNOTREADY;
+ else if (skb->pkt_type != PACKET_OUTGOING &&
+- (skb->ip_summed == CHECKSUM_COMPLETE ||
+- skb_csum_unnecessary(skb)))
++ skb_csum_unnecessary(skb))
+ aux.tp_status |= TP_STATUS_CSUM_VALID;
+
+ aux.tp_len = origlen;
+diff --git a/net/sctp/stream.c b/net/sctp/stream.c
+index ef9fceadef8d5..ee6514af830f7 100644
+--- a/net/sctp/stream.c
++++ b/net/sctp/stream.c
+@@ -52,6 +52,19 @@ static void sctp_stream_shrink_out(struct sctp_stream *stream, __u16 outcnt)
+ }
+ }
+
++static void sctp_stream_free_ext(struct sctp_stream *stream, __u16 sid)
++{
++ struct sctp_sched_ops *sched;
++
++ if (!SCTP_SO(stream, sid)->ext)
++ return;
++
++ sched = sctp_sched_ops_from_stream(stream);
++ sched->free_sid(stream, sid);
++ kfree(SCTP_SO(stream, sid)->ext);
++ SCTP_SO(stream, sid)->ext = NULL;
++}
++
+ /* Migrates chunks from stream queues to new stream queues if needed,
+ * but not across associations. Also, removes those chunks to streams
+ * higher than the new max.
+@@ -70,16 +83,14 @@ static void sctp_stream_outq_migrate(struct sctp_stream *stream,
+ * sctp_stream_update will swap ->out pointers.
+ */
+ for (i = 0; i < outcnt; i++) {
+- kfree(SCTP_SO(new, i)->ext);
++ sctp_stream_free_ext(new, i);
+ SCTP_SO(new, i)->ext = SCTP_SO(stream, i)->ext;
+ SCTP_SO(stream, i)->ext = NULL;
+ }
+ }
+
+- for (i = outcnt; i < stream->outcnt; i++) {
+- kfree(SCTP_SO(stream, i)->ext);
+- SCTP_SO(stream, i)->ext = NULL;
+- }
++ for (i = outcnt; i < stream->outcnt; i++)
++ sctp_stream_free_ext(stream, i);
+ }
+
+ static int sctp_stream_alloc_out(struct sctp_stream *stream, __u16 outcnt,
+@@ -174,9 +185,9 @@ void sctp_stream_free(struct sctp_stream *stream)
+ struct sctp_sched_ops *sched = sctp_sched_ops_from_stream(stream);
+ int i;
+
+- sched->free(stream);
++ sched->unsched_all(stream);
+ for (i = 0; i < stream->outcnt; i++)
+- kfree(SCTP_SO(stream, i)->ext);
++ sctp_stream_free_ext(stream, i);
+ genradix_free(&stream->out);
+ genradix_free(&stream->in);
+ }
+diff --git a/net/sctp/stream_sched.c b/net/sctp/stream_sched.c
+index 1ad565ed56273..7c8f9d89e16a8 100644
+--- a/net/sctp/stream_sched.c
++++ b/net/sctp/stream_sched.c
+@@ -46,6 +46,10 @@ static int sctp_sched_fcfs_init_sid(struct sctp_stream *stream, __u16 sid,
+ return 0;
+ }
+
++static void sctp_sched_fcfs_free_sid(struct sctp_stream *stream, __u16 sid)
++{
++}
++
+ static void sctp_sched_fcfs_free(struct sctp_stream *stream)
+ {
+ }
+@@ -96,6 +100,7 @@ static struct sctp_sched_ops sctp_sched_fcfs = {
+ .get = sctp_sched_fcfs_get,
+ .init = sctp_sched_fcfs_init,
+ .init_sid = sctp_sched_fcfs_init_sid,
++ .free_sid = sctp_sched_fcfs_free_sid,
+ .free = sctp_sched_fcfs_free,
+ .enqueue = sctp_sched_fcfs_enqueue,
+ .dequeue = sctp_sched_fcfs_dequeue,
+diff --git a/net/sctp/stream_sched_prio.c b/net/sctp/stream_sched_prio.c
+index 80b5a2c4cbc7b..4fc9f2923ed11 100644
+--- a/net/sctp/stream_sched_prio.c
++++ b/net/sctp/stream_sched_prio.c
+@@ -204,6 +204,24 @@ static int sctp_sched_prio_init_sid(struct sctp_stream *stream, __u16 sid,
+ return sctp_sched_prio_set(stream, sid, 0, gfp);
+ }
+
++static void sctp_sched_prio_free_sid(struct sctp_stream *stream, __u16 sid)
++{
++ struct sctp_stream_priorities *prio = SCTP_SO(stream, sid)->ext->prio_head;
++ int i;
++
++ if (!prio)
++ return;
++
++ SCTP_SO(stream, sid)->ext->prio_head = NULL;
++ for (i = 0; i < stream->outcnt; i++) {
++ if (SCTP_SO(stream, i)->ext &&
++ SCTP_SO(stream, i)->ext->prio_head == prio)
++ return;
++ }
++
++ kfree(prio);
++}
++
+ static void sctp_sched_prio_free(struct sctp_stream *stream)
+ {
+ struct sctp_stream_priorities *prio, *n;
+@@ -323,6 +341,7 @@ static struct sctp_sched_ops sctp_sched_prio = {
+ .get = sctp_sched_prio_get,
+ .init = sctp_sched_prio_init,
+ .init_sid = sctp_sched_prio_init_sid,
++ .free_sid = sctp_sched_prio_free_sid,
+ .free = sctp_sched_prio_free,
+ .enqueue = sctp_sched_prio_enqueue,
+ .dequeue = sctp_sched_prio_dequeue,
+diff --git a/net/sctp/stream_sched_rr.c b/net/sctp/stream_sched_rr.c
+index ff425aed62c7f..cc444fe0d67c2 100644
+--- a/net/sctp/stream_sched_rr.c
++++ b/net/sctp/stream_sched_rr.c
+@@ -90,6 +90,10 @@ static int sctp_sched_rr_init_sid(struct sctp_stream *stream, __u16 sid,
+ return 0;
+ }
+
++static void sctp_sched_rr_free_sid(struct sctp_stream *stream, __u16 sid)
++{
++}
++
+ static void sctp_sched_rr_free(struct sctp_stream *stream)
+ {
+ sctp_sched_rr_unsched_all(stream);
+@@ -177,6 +181,7 @@ static struct sctp_sched_ops sctp_sched_rr = {
+ .get = sctp_sched_rr_get,
+ .init = sctp_sched_rr_init,
+ .init_sid = sctp_sched_rr_init_sid,
++ .free_sid = sctp_sched_rr_free_sid,
+ .free = sctp_sched_rr_free,
+ .enqueue = sctp_sched_rr_enqueue,
+ .dequeue = sctp_sched_rr_dequeue,
+diff --git a/net/tipc/crypto.c b/net/tipc/crypto.c
+index f09316a9035f4..d67440de011e7 100644
+--- a/net/tipc/crypto.c
++++ b/net/tipc/crypto.c
+@@ -1971,6 +1971,9 @@ rcv:
+ /* Ok, everything's fine, try to synch own keys according to peers' */
+ tipc_crypto_key_synch(rx, *skb);
+
++ /* Re-fetch skb cb as skb might be changed in tipc_msg_validate */
++ skb_cb = TIPC_SKB_CB(*skb);
++
+ /* Mark skb decrypted */
+ skb_cb->decrypted = 1;
+
+diff --git a/net/wireless/scan.c b/net/wireless/scan.c
+index 9067e4b70855a..b4d7885729924 100644
+--- a/net/wireless/scan.c
++++ b/net/wireless/scan.c
+@@ -330,7 +330,8 @@ static size_t cfg80211_gen_new_ie(const u8 *ie, size_t ielen,
+ * determine if they are the same ie.
+ */
+ if (tmp_old[0] == WLAN_EID_VENDOR_SPECIFIC) {
+- if (!memcmp(tmp_old + 2, tmp + 2, 5)) {
++ if (tmp_old[1] >= 5 && tmp[1] >= 5 &&
++ !memcmp(tmp_old + 2, tmp + 2, 5)) {
+ /* same vendor ie, copy from
+ * subelement
+ */
+@@ -2526,10 +2527,15 @@ cfg80211_inform_bss_frame_data(struct wiphy *wiphy,
+ const struct cfg80211_bss_ies *ies1, *ies2;
+ size_t ielen = len - offsetof(struct ieee80211_mgmt,
+ u.probe_resp.variable);
+- struct cfg80211_non_tx_bss non_tx_data;
++ struct cfg80211_non_tx_bss non_tx_data = {};
+
+ res = cfg80211_inform_single_bss_frame_data(wiphy, data, mgmt,
+ len, gfp);
++
++ /* don't do any further MBSSID handling for S1G */
++ if (ieee80211_is_s1g_beacon(mgmt->frame_control))
++ return res;
++
+ if (!res || !wiphy->support_mbssid ||
+ !cfg80211_find_elem(WLAN_EID_MULTIPLE_BSSID, ie, ielen))
+ return res;
+diff --git a/scripts/faddr2line b/scripts/faddr2line
+index 5514c23f45c24..0e73aca4f9089 100755
+--- a/scripts/faddr2line
++++ b/scripts/faddr2line
+@@ -74,7 +74,8 @@ command -v ${ADDR2LINE} >/dev/null 2>&1 || die "${ADDR2LINE} isn't installed"
+ find_dir_prefix() {
+ local objfile=$1
+
+- local start_kernel_addr=$(${READELF} --symbols --wide $objfile | ${AWK} '$8 == "start_kernel" {printf "0x%s", $2}')
++ local start_kernel_addr=$(${READELF} --symbols --wide $objfile | sed 's/\[.*\]//' |
++ ${AWK} '$8 == "start_kernel" {printf "0x%s", $2}')
+ [[ -z $start_kernel_addr ]] && return
+
+ local file_line=$(${ADDR2LINE} -e $objfile $start_kernel_addr)
+@@ -178,7 +179,7 @@ __faddr2line() {
+ found=2
+ break
+ fi
+- done < <(${READELF} --symbols --wide $objfile | ${AWK} -v sec=$sym_sec '$7 == sec' | sort --key=2)
++ done < <(${READELF} --symbols --wide $objfile | sed 's/\[.*\]//' | ${AWK} -v sec=$sym_sec '$7 == sec' | sort --key=2)
+
+ if [[ $found = 0 ]]; then
+ warn "can't find symbol: sym_name: $sym_name sym_sec: $sym_sec sym_addr: $sym_addr sym_elf_size: $sym_elf_size"
+@@ -259,7 +260,7 @@ __faddr2line() {
+
+ DONE=1
+
+- done < <(${READELF} --symbols --wide $objfile | ${AWK} -v fn=$sym_name '$4 == "FUNC" && $8 == fn')
++ done < <(${READELF} --symbols --wide $objfile | sed 's/\[.*\]//' | ${AWK} -v fn=$sym_name '$4 == "FUNC" && $8 == fn')
+ }
+
+ [[ $# -lt 2 ]] && usage
+diff --git a/sound/firewire/dice/dice-stream.c b/sound/firewire/dice/dice-stream.c
+index f99e00083141e..4c677c8546c71 100644
+--- a/sound/firewire/dice/dice-stream.c
++++ b/sound/firewire/dice/dice-stream.c
+@@ -59,7 +59,7 @@ int snd_dice_stream_get_rate_mode(struct snd_dice *dice, unsigned int rate,
+
+ static int select_clock(struct snd_dice *dice, unsigned int rate)
+ {
+- __be32 reg;
++ __be32 reg, new;
+ u32 data;
+ int i;
+ int err;
+@@ -83,15 +83,17 @@ static int select_clock(struct snd_dice *dice, unsigned int rate)
+ if (completion_done(&dice->clock_accepted))
+ reinit_completion(&dice->clock_accepted);
+
+- reg = cpu_to_be32(data);
++ new = cpu_to_be32(data);
+ err = snd_dice_transaction_write_global(dice, GLOBAL_CLOCK_SELECT,
+- &reg, sizeof(reg));
++ &new, sizeof(new));
+ if (err < 0)
+ return err;
+
+ if (wait_for_completion_timeout(&dice->clock_accepted,
+- msecs_to_jiffies(NOTIFICATION_TIMEOUT_MS)) == 0)
+- return -ETIMEDOUT;
++ msecs_to_jiffies(NOTIFICATION_TIMEOUT_MS)) == 0) {
++ if (reg != new)
++ return -ETIMEDOUT;
++ }
+
+ return 0;
+ }
+diff --git a/sound/soc/codecs/tlv320adc3xxx.c b/sound/soc/codecs/tlv320adc3xxx.c
+index 8a0965cd3e667..297c458c4d8b0 100644
+--- a/sound/soc/codecs/tlv320adc3xxx.c
++++ b/sound/soc/codecs/tlv320adc3xxx.c
+@@ -14,6 +14,7 @@
+
+ #include <dt-bindings/sound/tlv320adc3xxx.h>
+ #include <linux/clk.h>
++#include <linux/gpio/consumer.h>
+ #include <linux/module.h>
+ #include <linux/moduleparam.h>
+ #include <linux/io.h>
+@@ -1025,7 +1026,9 @@ static const struct gpio_chip adc3xxx_gpio_chip = {
+
+ static void adc3xxx_free_gpio(struct adc3xxx *adc3xxx)
+ {
++#ifdef CONFIG_GPIOLIB
+ gpiochip_remove(&adc3xxx->gpio_chip);
++#endif
+ }
+
+ static void adc3xxx_init_gpio(struct adc3xxx *adc3xxx)
+diff --git a/sound/soc/soc-ops.c b/sound/soc/soc-ops.c
+index bd88de0563583..47691119306fb 100644
+--- a/sound/soc/soc-ops.c
++++ b/sound/soc/soc-ops.c
+@@ -452,7 +452,7 @@ int snd_soc_put_volsw_sx(struct snd_kcontrol *kcontrol,
+ val = ucontrol->value.integer.value[0];
+ if (mc->platform_max && val > mc->platform_max)
+ return -EINVAL;
+- if (val > max - min)
++ if (val > max)
+ return -EINVAL;
+ val_mask = mask << shift;
+ val = (val + min) & mask;
+diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
+index e36c44090720e..79ea83be21ce9 100644
+--- a/tools/lib/bpf/libbpf.c
++++ b/tools/lib/bpf/libbpf.c
+@@ -11143,7 +11143,7 @@ static int attach_raw_tp(const struct bpf_program *prog, long cookie, struct bpf
+ }
+
+ *link = bpf_program__attach_raw_tracepoint(prog, tp_name);
+- return libbpf_get_error(link);
++ return libbpf_get_error(*link);
+ }
+
+ /* Common logic for all BPF program types that attach to a btf_id */
+diff --git a/tools/lib/bpf/ringbuf.c b/tools/lib/bpf/ringbuf.c
+index 8bc117bcc7bcd..c42ba9358d8ce 100644
+--- a/tools/lib/bpf/ringbuf.c
++++ b/tools/lib/bpf/ringbuf.c
+@@ -59,6 +59,7 @@ int ring_buffer__add(struct ring_buffer *rb, int map_fd,
+ __u32 len = sizeof(info);
+ struct epoll_event *e;
+ struct ring *r;
++ __u64 mmap_sz;
+ void *tmp;
+ int err;
+
+@@ -97,8 +98,7 @@ int ring_buffer__add(struct ring_buffer *rb, int map_fd,
+ r->mask = info.max_entries - 1;
+
+ /* Map writable consumer page */
+- tmp = mmap(NULL, rb->page_size, PROT_READ | PROT_WRITE, MAP_SHARED,
+- map_fd, 0);
++ tmp = mmap(NULL, rb->page_size, PROT_READ | PROT_WRITE, MAP_SHARED, map_fd, 0);
+ if (tmp == MAP_FAILED) {
+ err = -errno;
+ pr_warn("ringbuf: failed to mmap consumer page for map fd=%d: %d\n",
+@@ -111,8 +111,12 @@ int ring_buffer__add(struct ring_buffer *rb, int map_fd,
+ * data size to allow simple reading of samples that wrap around the
+ * end of a ring buffer. See kernel implementation for details.
+ * */
+- tmp = mmap(NULL, rb->page_size + 2 * info.max_entries, PROT_READ,
+- MAP_SHARED, map_fd, rb->page_size);
++ mmap_sz = rb->page_size + 2 * (__u64)info.max_entries;
++ if (mmap_sz != (__u64)(size_t)mmap_sz) {
++ pr_warn("ringbuf: ring buffer size (%u) is too big\n", info.max_entries);
++ return libbpf_err(-E2BIG);
++ }
++ tmp = mmap(NULL, (size_t)mmap_sz, PROT_READ, MAP_SHARED, map_fd, rb->page_size);
+ if (tmp == MAP_FAILED) {
+ err = -errno;
+ ringbuf_unmap_ring(rb, r);
+diff --git a/tools/testing/selftests/net/fib_nexthops.sh b/tools/testing/selftests/net/fib_nexthops.sh
+index d5a0dd548989b..a47b26ab48f23 100755
+--- a/tools/testing/selftests/net/fib_nexthops.sh
++++ b/tools/testing/selftests/net/fib_nexthops.sh
+@@ -1223,6 +1223,22 @@ ipv4_fcnal()
+ log_test $rc 0 "Delete nexthop route warning"
+ run_cmd "$IP route delete 172.16.101.1/32 nhid 12"
+ run_cmd "$IP nexthop del id 12"
++
++ run_cmd "$IP nexthop add id 21 via 172.16.1.6 dev veth1"
++ run_cmd "$IP ro add 172.16.101.0/24 nhid 21"
++ run_cmd "$IP ro del 172.16.101.0/24 nexthop via 172.16.1.7 dev veth1 nexthop via 172.16.1.8 dev veth1"
++ log_test $? 2 "Delete multipath route with only nh id based entry"
++
++ run_cmd "$IP nexthop add id 22 via 172.16.1.6 dev veth1"
++ run_cmd "$IP ro add 172.16.102.0/24 nhid 22"
++ run_cmd "$IP ro del 172.16.102.0/24 dev veth1"
++ log_test $? 2 "Delete route when specifying only nexthop device"
++
++ run_cmd "$IP ro del 172.16.102.0/24 via 172.16.1.6"
++ log_test $? 2 "Delete route when specifying only gateway"
++
++ run_cmd "$IP ro del 172.16.102.0/24"
++ log_test $? 0 "Delete route when not specifying nexthop attributes"
+ }
+
+ ipv4_grp_fcnal()
+diff --git a/tools/vm/slabinfo-gnuplot.sh b/tools/vm/slabinfo-gnuplot.sh
+index 26e193ffd2a2f..873a892147e57 100644
+--- a/tools/vm/slabinfo-gnuplot.sh
++++ b/tools/vm/slabinfo-gnuplot.sh
+@@ -150,7 +150,7 @@ do_preprocess()
+ let lines=3
+ out=`basename "$in"`"-slabs-by-loss"
+ `cat "$in" | grep -A "$lines" 'Slabs sorted by loss' |\
+- egrep -iv '\-\-|Name|Slabs'\
++ grep -E -iv '\-\-|Name|Slabs'\
+ | awk '{print $1" "$4+$2*$3" "$4}' > "$out"`
+ if [ $? -eq 0 ]; then
+ do_slabs_plotting "$out"
+@@ -159,7 +159,7 @@ do_preprocess()
+ let lines=3
+ out=`basename "$in"`"-slabs-by-size"
+ `cat "$in" | grep -A "$lines" 'Slabs sorted by size' |\
+- egrep -iv '\-\-|Name|Slabs'\
++ grep -E -iv '\-\-|Name|Slabs'\
+ | awk '{print $1" "$4" "$4-$2*$3}' > "$out"`
+ if [ $? -eq 0 ]; then
+ do_slabs_plotting "$out"