commit: a22076563c524b29a4fa861e53a0acad37cac392 Author: Mike Pagano <mpagano <AT> gentoo <DOT> org> AuthorDate: Thu Dec 19 18:08:29 2024 +0000 Commit: Mike Pagano <mpagano <AT> gentoo <DOT> org> CommitDate: Thu Dec 19 18:08:29 2024 +0000 URL: https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=a2207656
Linux patch 6.1.121 Signed-off-by: Mike Pagano <mpagano <AT> gentoo.org> 0000_README | 4 + 1120_linux-6.1.121.patch | 3415 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 3419 insertions(+) diff --git a/0000_README b/0000_README index d5468676..e4617888 100644 --- a/0000_README +++ b/0000_README @@ -527,6 +527,10 @@ Patch: 1119_linux-6.1.120.patch From: https://www.kernel.org Desc: Linux 6.1.120 +Patch: 1120_linux-6.1.121.patch +From: https://www.kernel.org +Desc: Linux 6.1.121 + 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/1120_linux-6.1.121.patch b/1120_linux-6.1.121.patch new file mode 100644 index 00000000..e79a8050 --- /dev/null +++ b/1120_linux-6.1.121.patch @@ -0,0 +1,3415 @@ +diff --git a/Documentation/power/runtime_pm.rst b/Documentation/power/runtime_pm.rst +index 65b86e487afe00..b6d5a3a8febc10 100644 +--- a/Documentation/power/runtime_pm.rst ++++ b/Documentation/power/runtime_pm.rst +@@ -347,7 +347,9 @@ drivers/base/power/runtime.c and include/linux/pm_runtime.h: + + `int pm_runtime_resume_and_get(struct device *dev);` + - run pm_runtime_resume(dev) and if successful, increment the device's +- usage counter; return the result of pm_runtime_resume ++ usage counter; returns 0 on success (whether or not the device's ++ runtime PM status was already 'active') or the error code from ++ pm_runtime_resume() on failure. + + `int pm_request_idle(struct device *dev);` + - submit a request to execute the subsystem-level idle callback for the +diff --git a/Makefile b/Makefile +index 5a7eaf74ff15db..ddb75912d2a84a 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,7 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0 + VERSION = 6 + PATCHLEVEL = 1 +-SUBLEVEL = 120 ++SUBLEVEL = 121 + EXTRAVERSION = + NAME = Curry Ramen + +diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h +index d2b93b68fe563c..d8fd09de63d5b1 100644 +--- a/arch/x86/include/asm/processor.h ++++ b/arch/x86/include/asm/processor.h +@@ -199,6 +199,8 @@ static inline unsigned long long l1tf_pfn_limit(void) + return BIT_ULL(boot_cpu_data.x86_cache_bits - 1 - PAGE_SHIFT); + } + ++void init_cpu_devs(void); ++void get_cpu_vendor(struct cpuinfo_x86 *c); + extern void early_cpu_init(void); + extern void identify_boot_cpu(void); + extern void identify_secondary_cpu(struct cpuinfo_x86 *); +diff --git a/arch/x86/include/asm/static_call.h b/arch/x86/include/asm/static_call.h +index 343b722ccaf21d..35d75c19b1e328 100644 +--- a/arch/x86/include/asm/static_call.h ++++ b/arch/x86/include/asm/static_call.h +@@ -65,4 +65,19 @@ + + extern bool __static_call_fixup(void *tramp, u8 op, void *dest); + ++extern void __static_call_update_early(void *tramp, void *func); ++ ++#define static_call_update_early(name, _func) \ ++({ \ ++ typeof(&STATIC_CALL_TRAMP(name)) __F = (_func); \ ++ if (static_call_initialized) { \ ++ __static_call_update(&STATIC_CALL_KEY(name), \ ++ STATIC_CALL_TRAMP_ADDR(name), __F);\ ++ } else { \ ++ WRITE_ONCE(STATIC_CALL_KEY(name).func, _func); \ ++ __static_call_update_early(STATIC_CALL_TRAMP_ADDR(name),\ ++ __F); \ ++ } \ ++}) ++ + #endif /* _ASM_STATIC_CALL_H */ +diff --git a/arch/x86/include/asm/sync_core.h b/arch/x86/include/asm/sync_core.h +index ab7382f92aff27..96bda43538ee70 100644 +--- a/arch/x86/include/asm/sync_core.h ++++ b/arch/x86/include/asm/sync_core.h +@@ -8,7 +8,7 @@ + #include <asm/special_insns.h> + + #ifdef CONFIG_X86_32 +-static inline void iret_to_self(void) ++static __always_inline void iret_to_self(void) + { + asm volatile ( + "pushfl\n\t" +@@ -19,7 +19,7 @@ static inline void iret_to_self(void) + : ASM_CALL_CONSTRAINT : : "memory"); + } + #else +-static inline void iret_to_self(void) ++static __always_inline void iret_to_self(void) + { + unsigned int tmp; + +@@ -55,7 +55,7 @@ static inline void iret_to_self(void) + * Like all of Linux's memory ordering operations, this is a + * compiler barrier as well. + */ +-static inline void sync_core(void) ++static __always_inline void sync_core(void) + { + /* + * The SERIALIZE instruction is the most straightforward way to +diff --git a/arch/x86/include/asm/xen/hypercall.h b/arch/x86/include/asm/xen/hypercall.h +index e5e0fe10c69240..9b4eddd5833aec 100644 +--- a/arch/x86/include/asm/xen/hypercall.h ++++ b/arch/x86/include/asm/xen/hypercall.h +@@ -39,9 +39,11 @@ + #include <linux/string.h> + #include <linux/types.h> + #include <linux/pgtable.h> ++#include <linux/instrumentation.h> + + #include <trace/events/xen.h> + ++#include <asm/alternative.h> + #include <asm/page.h> + #include <asm/smap.h> + #include <asm/nospec-branch.h> +@@ -86,11 +88,20 @@ struct xen_dm_op_buf; + * there aren't more than 5 arguments...) + */ + +-extern struct { char _entry[32]; } hypercall_page[]; ++void xen_hypercall_func(void); ++DECLARE_STATIC_CALL(xen_hypercall, xen_hypercall_func); + +-#define __HYPERCALL "call hypercall_page+%c[offset]" +-#define __HYPERCALL_ENTRY(x) \ +- [offset] "i" (__HYPERVISOR_##x * sizeof(hypercall_page[0])) ++#ifdef MODULE ++#define __ADDRESSABLE_xen_hypercall ++#else ++#define __ADDRESSABLE_xen_hypercall __ADDRESSABLE_ASM_STR(__SCK__xen_hypercall) ++#endif ++ ++#define __HYPERCALL \ ++ __ADDRESSABLE_xen_hypercall \ ++ "call __SCT__xen_hypercall" ++ ++#define __HYPERCALL_ENTRY(x) "a" (x) + + #ifdef CONFIG_X86_32 + #define __HYPERCALL_RETREG "eax" +@@ -148,7 +159,7 @@ extern struct { char _entry[32]; } hypercall_page[]; + __HYPERCALL_0ARG(); \ + asm volatile (__HYPERCALL \ + : __HYPERCALL_0PARAM \ +- : __HYPERCALL_ENTRY(name) \ ++ : __HYPERCALL_ENTRY(__HYPERVISOR_ ## name) \ + : __HYPERCALL_CLOBBER0); \ + (type)__res; \ + }) +@@ -159,7 +170,7 @@ extern struct { char _entry[32]; } hypercall_page[]; + __HYPERCALL_1ARG(a1); \ + asm volatile (__HYPERCALL \ + : __HYPERCALL_1PARAM \ +- : __HYPERCALL_ENTRY(name) \ ++ : __HYPERCALL_ENTRY(__HYPERVISOR_ ## name) \ + : __HYPERCALL_CLOBBER1); \ + (type)__res; \ + }) +@@ -170,7 +181,7 @@ extern struct { char _entry[32]; } hypercall_page[]; + __HYPERCALL_2ARG(a1, a2); \ + asm volatile (__HYPERCALL \ + : __HYPERCALL_2PARAM \ +- : __HYPERCALL_ENTRY(name) \ ++ : __HYPERCALL_ENTRY(__HYPERVISOR_ ## name) \ + : __HYPERCALL_CLOBBER2); \ + (type)__res; \ + }) +@@ -181,7 +192,7 @@ extern struct { char _entry[32]; } hypercall_page[]; + __HYPERCALL_3ARG(a1, a2, a3); \ + asm volatile (__HYPERCALL \ + : __HYPERCALL_3PARAM \ +- : __HYPERCALL_ENTRY(name) \ ++ : __HYPERCALL_ENTRY(__HYPERVISOR_ ## name) \ + : __HYPERCALL_CLOBBER3); \ + (type)__res; \ + }) +@@ -192,7 +203,7 @@ extern struct { char _entry[32]; } hypercall_page[]; + __HYPERCALL_4ARG(a1, a2, a3, a4); \ + asm volatile (__HYPERCALL \ + : __HYPERCALL_4PARAM \ +- : __HYPERCALL_ENTRY(name) \ ++ : __HYPERCALL_ENTRY(__HYPERVISOR_ ## name) \ + : __HYPERCALL_CLOBBER4); \ + (type)__res; \ + }) +@@ -206,12 +217,9 @@ xen_single_call(unsigned int call, + __HYPERCALL_DECLS; + __HYPERCALL_5ARG(a1, a2, a3, a4, a5); + +- if (call >= PAGE_SIZE / sizeof(hypercall_page[0])) +- return -EINVAL; +- +- asm volatile(CALL_NOSPEC ++ asm volatile(__HYPERCALL + : __HYPERCALL_5PARAM +- : [thunk_target] "a" (&hypercall_page[call]) ++ : __HYPERCALL_ENTRY(call) + : __HYPERCALL_CLOBBER5); + + return (long)__res; +diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c +index d85423ec5beaad..62aaabea7e33f2 100644 +--- a/arch/x86/kernel/cpu/common.c ++++ b/arch/x86/kernel/cpu/common.c +@@ -906,7 +906,7 @@ void detect_ht(struct cpuinfo_x86 *c) + #endif + } + +-static void get_cpu_vendor(struct cpuinfo_x86 *c) ++void get_cpu_vendor(struct cpuinfo_x86 *c) + { + char *v = c->x86_vendor_id; + int i; +@@ -1672,15 +1672,11 @@ static void __init early_identify_cpu(struct cpuinfo_x86 *c) + detect_nopl(); + } + +-void __init early_cpu_init(void) ++void __init init_cpu_devs(void) + { + const struct cpu_dev *const *cdev; + int count = 0; + +-#ifdef CONFIG_PROCESSOR_SELECT +- pr_info("KERNEL supported cpus:\n"); +-#endif +- + for (cdev = __x86_cpu_dev_start; cdev < __x86_cpu_dev_end; cdev++) { + const struct cpu_dev *cpudev = *cdev; + +@@ -1688,20 +1684,30 @@ void __init early_cpu_init(void) + break; + cpu_devs[count] = cpudev; + count++; ++ } ++} + ++void __init early_cpu_init(void) ++{ + #ifdef CONFIG_PROCESSOR_SELECT +- { +- unsigned int j; +- +- for (j = 0; j < 2; j++) { +- if (!cpudev->c_ident[j]) +- continue; +- pr_info(" %s %s\n", cpudev->c_vendor, +- cpudev->c_ident[j]); +- } +- } ++ unsigned int i, j; ++ ++ pr_info("KERNEL supported cpus:\n"); + #endif ++ ++ init_cpu_devs(); ++ ++#ifdef CONFIG_PROCESSOR_SELECT ++ for (i = 0; i < X86_VENDOR_NUM && cpu_devs[i]; i++) { ++ for (j = 0; j < 2; j++) { ++ if (!cpu_devs[i]->c_ident[j]) ++ continue; ++ pr_info(" %s %s\n", cpu_devs[i]->c_vendor, ++ cpu_devs[i]->c_ident[j]); ++ } + } ++#endif ++ + early_identify_cpu(&boot_cpu_data); + } + +diff --git a/arch/x86/kernel/static_call.c b/arch/x86/kernel/static_call.c +index b32134b093ec80..587975eca72811 100644 +--- a/arch/x86/kernel/static_call.c ++++ b/arch/x86/kernel/static_call.c +@@ -170,6 +170,15 @@ void arch_static_call_transform(void *site, void *tramp, void *func, bool tail) + } + EXPORT_SYMBOL_GPL(arch_static_call_transform); + ++noinstr void __static_call_update_early(void *tramp, void *func) ++{ ++ BUG_ON(system_state != SYSTEM_BOOTING); ++ BUG_ON(!early_boot_irqs_disabled); ++ BUG_ON(static_call_initialized); ++ __text_gen_insn(tramp, JMP32_INSN_OPCODE, tramp, func, JMP32_INSN_SIZE); ++ sync_core(); ++} ++ + #ifdef CONFIG_RETHUNK + /* + * This is called by apply_returns() to fix up static call trampolines, +diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c +index 3c61bb98c10e28..31f4a4dd8c62af 100644 +--- a/arch/x86/xen/enlighten.c ++++ b/arch/x86/xen/enlighten.c +@@ -5,6 +5,7 @@ + #endif + #include <linux/console.h> + #include <linux/cpu.h> ++#include <linux/instrumentation.h> + #include <linux/kexec.h> + #include <linux/slab.h> + #include <linux/panic_notifier.h> +@@ -25,7 +26,8 @@ + #include "smp.h" + #include "pmu.h" + +-EXPORT_SYMBOL_GPL(hypercall_page); ++DEFINE_STATIC_CALL(xen_hypercall, xen_hypercall_hvm); ++EXPORT_STATIC_CALL_TRAMP(xen_hypercall); + + /* + * Pointer to the xen_vcpu_info structure or +@@ -72,6 +74,67 @@ EXPORT_SYMBOL(xen_start_flags); + */ + struct shared_info *HYPERVISOR_shared_info = &xen_dummy_shared_info; + ++static __ref void xen_get_vendor(void) ++{ ++ init_cpu_devs(); ++ cpu_detect(&boot_cpu_data); ++ get_cpu_vendor(&boot_cpu_data); ++} ++ ++void xen_hypercall_setfunc(void) ++{ ++ if (static_call_query(xen_hypercall) != xen_hypercall_hvm) ++ return; ++ ++ if ((boot_cpu_data.x86_vendor == X86_VENDOR_AMD || ++ boot_cpu_data.x86_vendor == X86_VENDOR_HYGON)) ++ static_call_update(xen_hypercall, xen_hypercall_amd); ++ else ++ static_call_update(xen_hypercall, xen_hypercall_intel); ++} ++ ++/* ++ * Evaluate processor vendor in order to select the correct hypercall ++ * function for HVM/PVH guests. ++ * Might be called very early in boot before vendor has been set by ++ * early_cpu_init(). ++ */ ++noinstr void *__xen_hypercall_setfunc(void) ++{ ++ void (*func)(void); ++ ++ /* ++ * Xen is supported only on CPUs with CPUID, so testing for ++ * X86_FEATURE_CPUID is a test for early_cpu_init() having been ++ * run. ++ * ++ * Note that __xen_hypercall_setfunc() is noinstr only due to a nasty ++ * dependency chain: it is being called via the xen_hypercall static ++ * call when running as a PVH or HVM guest. Hypercalls need to be ++ * noinstr due to PV guests using hypercalls in noinstr code. So we ++ * can safely tag the function body as "instrumentation ok", since ++ * the PV guest requirement is not of interest here (xen_get_vendor() ++ * calls noinstr functions, and static_call_update_early() might do ++ * so, too). ++ */ ++ instrumentation_begin(); ++ ++ if (!boot_cpu_has(X86_FEATURE_CPUID)) ++ xen_get_vendor(); ++ ++ if ((boot_cpu_data.x86_vendor == X86_VENDOR_AMD || ++ boot_cpu_data.x86_vendor == X86_VENDOR_HYGON)) ++ func = xen_hypercall_amd; ++ else ++ func = xen_hypercall_intel; ++ ++ static_call_update_early(xen_hypercall, func); ++ ++ instrumentation_end(); ++ ++ return func; ++} ++ + static int xen_cpu_up_online(unsigned int cpu) + { + xen_init_lock_cpu(cpu); +diff --git a/arch/x86/xen/enlighten_hvm.c b/arch/x86/xen/enlighten_hvm.c +index c66807dd027039..3a453207f3c7f5 100644 +--- a/arch/x86/xen/enlighten_hvm.c ++++ b/arch/x86/xen/enlighten_hvm.c +@@ -108,15 +108,8 @@ static void __init init_hvm_pv_info(void) + /* PVH set up hypercall page in xen_prepare_pvh(). */ + if (xen_pvh_domain()) + pv_info.name = "Xen PVH"; +- else { +- u64 pfn; +- uint32_t msr; +- ++ else + pv_info.name = "Xen HVM"; +- msr = cpuid_ebx(base + 2); +- pfn = __pa(hypercall_page); +- wrmsr_safe(msr, (u32)pfn, (u32)(pfn >> 32)); +- } + + xen_setup_features(); + +@@ -299,6 +292,10 @@ static uint32_t __init xen_platform_hvm(void) + if (xen_pv_domain()) + return 0; + ++ /* Set correct hypercall function. */ ++ if (xen_domain) ++ xen_hypercall_setfunc(); ++ + if (xen_pvh_domain() && nopv) { + /* Guest booting via the Xen-PVH boot entry goes here */ + pr_info("\"nopv\" parameter is ignored in PVH guest\n"); +diff --git a/arch/x86/xen/enlighten_pv.c b/arch/x86/xen/enlighten_pv.c +index 9280e15de3af55..ee8f452cc58bb9 100644 +--- a/arch/x86/xen/enlighten_pv.c ++++ b/arch/x86/xen/enlighten_pv.c +@@ -1248,6 +1248,9 @@ asmlinkage __visible void __init xen_start_kernel(struct start_info *si) + + xen_domain_type = XEN_PV_DOMAIN; + xen_start_flags = xen_start_info->flags; ++ /* Interrupts are guaranteed to be off initially. */ ++ early_boot_irqs_disabled = true; ++ static_call_update_early(xen_hypercall, xen_hypercall_pv); + + xen_setup_features(); + +@@ -1340,7 +1343,6 @@ asmlinkage __visible void __init xen_start_kernel(struct start_info *si) + WARN_ON(xen_cpuhp_setup(xen_cpu_up_prepare_pv, xen_cpu_dead_pv)); + + local_irq_disable(); +- early_boot_irqs_disabled = true; + + xen_raw_console_write("mapping kernel into physical memory\n"); + xen_setup_kernel_pagetable((pgd_t *)xen_start_info->pt_base, +diff --git a/arch/x86/xen/enlighten_pvh.c b/arch/x86/xen/enlighten_pvh.c +index ada3868c02c231..00ee9399fd0c32 100644 +--- a/arch/x86/xen/enlighten_pvh.c ++++ b/arch/x86/xen/enlighten_pvh.c +@@ -27,17 +27,10 @@ EXPORT_SYMBOL_GPL(xen_pvh); + + void __init xen_pvh_init(struct boot_params *boot_params) + { +- u32 msr; +- u64 pfn; +- + xen_pvh = 1; + xen_domain_type = XEN_HVM_DOMAIN; + xen_start_flags = pvh_start_info.flags; + +- msr = cpuid_ebx(xen_cpuid_base() + 2); +- pfn = __pa(hypercall_page); +- wrmsr_safe(msr, (u32)pfn, (u32)(pfn >> 32)); +- + if (xen_initial_domain()) + x86_init.oem.arch_setup = xen_add_preferred_consoles; + x86_init.oem.banner = xen_banner; +diff --git a/arch/x86/xen/xen-asm.S b/arch/x86/xen/xen-asm.S +index dec5e03e7a2cf7..aa2676a7e2a477 100644 +--- a/arch/x86/xen/xen-asm.S ++++ b/arch/x86/xen/xen-asm.S +@@ -20,9 +20,32 @@ + + #include <linux/init.h> + #include <linux/linkage.h> ++#include <linux/objtool.h> + #include <../entry/calling.h> + + .pushsection .noinstr.text, "ax" ++/* ++ * PV hypercall interface to the hypervisor. ++ * ++ * Called via inline asm(), so better preserve %rcx and %r11. ++ * ++ * Input: ++ * %eax: hypercall number ++ * %rdi, %rsi, %rdx, %r10, %r8: args 1..5 for the hypercall ++ * Output: %rax ++ */ ++SYM_FUNC_START(xen_hypercall_pv) ++ ANNOTATE_NOENDBR ++ push %rcx ++ push %r11 ++ UNWIND_HINT_SAVE ++ syscall ++ UNWIND_HINT_RESTORE ++ pop %r11 ++ pop %rcx ++ RET ++SYM_FUNC_END(xen_hypercall_pv) ++ + /* + * Disabling events is simply a matter of making the event mask + * non-zero. +@@ -176,7 +199,6 @@ SYM_CODE_START(xen_early_idt_handler_array) + SYM_CODE_END(xen_early_idt_handler_array) + __FINIT + +-hypercall_iret = hypercall_page + __HYPERVISOR_iret * 32 + /* + * Xen64 iret frame: + * +@@ -186,17 +208,28 @@ hypercall_iret = hypercall_page + __HYPERVISOR_iret * 32 + * cs + * rip <-- standard iret frame + * +- * flags ++ * flags <-- xen_iret must push from here on + * +- * rcx } +- * r11 }<-- pushed by hypercall page +- * rsp->rax } ++ * rcx ++ * r11 ++ * rsp->rax + */ ++.macro xen_hypercall_iret ++ pushq $0 /* Flags */ ++ push %rcx ++ push %r11 ++ push %rax ++ mov $__HYPERVISOR_iret, %eax ++ syscall /* Do the IRET. */ ++#ifdef CONFIG_MITIGATION_SLS ++ int3 ++#endif ++.endm ++ + SYM_CODE_START(xen_iret) + UNWIND_HINT_EMPTY + ANNOTATE_NOENDBR +- pushq $0 +- jmp hypercall_iret ++ xen_hypercall_iret + SYM_CODE_END(xen_iret) + + /* +@@ -301,8 +334,7 @@ SYM_CODE_START(xen_entry_SYSENTER_compat) + ENDBR + lea 16(%rsp), %rsp /* strip %rcx, %r11 */ + mov $-ENOSYS, %rax +- pushq $0 +- jmp hypercall_iret ++ xen_hypercall_iret + SYM_CODE_END(xen_entry_SYSENTER_compat) + SYM_CODE_END(xen_entry_SYSCALL_compat) + +diff --git a/arch/x86/xen/xen-head.S b/arch/x86/xen/xen-head.S +index ffaa62167f6e8d..1cf94caa7600c2 100644 +--- a/arch/x86/xen/xen-head.S ++++ b/arch/x86/xen/xen-head.S +@@ -6,9 +6,11 @@ + + #include <linux/elfnote.h> + #include <linux/init.h> ++#include <linux/instrumentation.h> + + #include <asm/boot.h> + #include <asm/asm.h> ++#include <asm/frame.h> + #include <asm/msr.h> + #include <asm/page_types.h> + #include <asm/percpu.h> +@@ -20,28 +22,6 @@ + #include <xen/interface/xen-mca.h> + #include <asm/xen/interface.h> + +-.pushsection .noinstr.text, "ax" +- .balign PAGE_SIZE +-SYM_CODE_START(hypercall_page) +- .rept (PAGE_SIZE / 32) +- UNWIND_HINT_FUNC +- ANNOTATE_NOENDBR +- ANNOTATE_UNRET_SAFE +- ret +- /* +- * Xen will write the hypercall page, and sort out ENDBR. +- */ +- .skip 31, 0xcc +- .endr +- +-#define HYPERCALL(n) \ +- .equ xen_hypercall_##n, hypercall_page + __HYPERVISOR_##n * 32; \ +- .type xen_hypercall_##n, @function; .size xen_hypercall_##n, 32 +-#include <asm/xen-hypercalls.h> +-#undef HYPERCALL +-SYM_CODE_END(hypercall_page) +-.popsection +- + #ifdef CONFIG_XEN_PV + __INIT + SYM_CODE_START(startup_xen) +@@ -80,6 +60,87 @@ SYM_CODE_END(asm_cpu_bringup_and_idle) + #endif + #endif + ++ .pushsection .noinstr.text, "ax" ++/* ++ * Xen hypercall interface to the hypervisor. ++ * ++ * Input: ++ * %eax: hypercall number ++ * 32-bit: ++ * %ebx, %ecx, %edx, %esi, %edi: args 1..5 for the hypercall ++ * 64-bit: ++ * %rdi, %rsi, %rdx, %r10, %r8: args 1..5 for the hypercall ++ * Output: %[er]ax ++ */ ++SYM_FUNC_START(xen_hypercall_hvm) ++ ENDBR ++ FRAME_BEGIN ++ /* Save all relevant registers (caller save and arguments). */ ++#ifdef CONFIG_X86_32 ++ push %eax ++ push %ebx ++ push %ecx ++ push %edx ++ push %esi ++ push %edi ++#else ++ push %rax ++ push %rcx ++ push %rdx ++ push %rdi ++ push %rsi ++ push %r11 ++ push %r10 ++ push %r9 ++ push %r8 ++#ifdef CONFIG_FRAME_POINTER ++ pushq $0 /* Dummy push for stack alignment. */ ++#endif ++#endif ++ /* Set the vendor specific function. */ ++ call __xen_hypercall_setfunc ++ /* Set ZF = 1 if AMD, Restore saved registers. */ ++#ifdef CONFIG_X86_32 ++ lea xen_hypercall_amd, %ebx ++ cmp %eax, %ebx ++ pop %edi ++ pop %esi ++ pop %edx ++ pop %ecx ++ pop %ebx ++ pop %eax ++#else ++ lea xen_hypercall_amd(%rip), %rbx ++ cmp %rax, %rbx ++#ifdef CONFIG_FRAME_POINTER ++ pop %rax /* Dummy pop. */ ++#endif ++ pop %r8 ++ pop %r9 ++ pop %r10 ++ pop %r11 ++ pop %rsi ++ pop %rdi ++ pop %rdx ++ pop %rcx ++ pop %rax ++#endif ++ /* Use correct hypercall function. */ ++ jz xen_hypercall_amd ++ jmp xen_hypercall_intel ++SYM_FUNC_END(xen_hypercall_hvm) ++ ++SYM_FUNC_START(xen_hypercall_amd) ++ vmmcall ++ RET ++SYM_FUNC_END(xen_hypercall_amd) ++ ++SYM_FUNC_START(xen_hypercall_intel) ++ vmcall ++ RET ++SYM_FUNC_END(xen_hypercall_intel) ++ .popsection ++ + ELFNOTE(Xen, XEN_ELFNOTE_GUEST_OS, .asciz "linux") + ELFNOTE(Xen, XEN_ELFNOTE_GUEST_VERSION, .asciz "2.6") + ELFNOTE(Xen, XEN_ELFNOTE_XEN_VERSION, .asciz "xen-3.0") +@@ -93,7 +154,6 @@ SYM_CODE_END(asm_cpu_bringup_and_idle) + #ifdef CONFIG_XEN_PV + ELFNOTE(Xen, XEN_ELFNOTE_ENTRY, _ASM_PTR startup_xen) + #endif +- ELFNOTE(Xen, XEN_ELFNOTE_HYPERCALL_PAGE, _ASM_PTR hypercall_page) + ELFNOTE(Xen, XEN_ELFNOTE_FEATURES, + .ascii "!writable_page_tables|pae_pgdir_above_4gb") + ELFNOTE(Xen, XEN_ELFNOTE_SUPPORTED_FEATURES, +diff --git a/arch/x86/xen/xen-ops.h b/arch/x86/xen/xen-ops.h +index b2b2f4315b78da..3a939418a2f2fa 100644 +--- a/arch/x86/xen/xen-ops.h ++++ b/arch/x86/xen/xen-ops.h +@@ -162,4 +162,13 @@ void xen_hvm_post_suspend(int suspend_cancelled); + static inline void xen_hvm_post_suspend(int suspend_cancelled) {} + #endif + ++#ifdef CONFIG_XEN_PV ++void xen_hypercall_pv(void); ++#endif ++void xen_hypercall_hvm(void); ++void xen_hypercall_amd(void); ++void xen_hypercall_intel(void); ++void xen_hypercall_setfunc(void); ++void *__xen_hypercall_setfunc(void); ++ + #endif /* XEN_OPS_H */ +diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c +index 1b7fd1fc2f3370..b7bf1cfdbb4b3a 100644 +--- a/block/blk-cgroup.c ++++ b/block/blk-cgroup.c +@@ -1110,10 +1110,14 @@ void blkcg_unpin_online(struct cgroup_subsys_state *blkcg_css) + struct blkcg *blkcg = css_to_blkcg(blkcg_css); + + do { ++ struct blkcg *parent; ++ + if (!refcount_dec_and_test(&blkcg->online_pin)) + break; ++ ++ parent = blkcg_parent(blkcg); + blkcg_destroy_blkgs(blkcg); +- blkcg = blkcg_parent(blkcg); ++ blkcg = parent; + } while (blkcg); + } + +diff --git a/block/blk-iocost.c b/block/blk-iocost.c +index 772e909e9fbfdc..e270e64ba3429e 100644 +--- a/block/blk-iocost.c ++++ b/block/blk-iocost.c +@@ -1082,7 +1082,14 @@ static void __propagate_weights(struct ioc_gq *iocg, u32 active, u32 inuse, + inuse = DIV64_U64_ROUND_UP(active * iocg->child_inuse_sum, + iocg->child_active_sum); + } else { +- inuse = clamp_t(u32, inuse, 1, active); ++ /* ++ * It may be tempting to turn this into a clamp expression with ++ * a lower limit of 1 but active may be 0, which cannot be used ++ * as an upper limit in that situation. This expression allows ++ * active to clamp inuse unless it is 0, in which case inuse ++ * becomes 1. ++ */ ++ inuse = min(inuse, active) ?: 1; + } + + iocg->last_inuse = iocg->inuse; +diff --git a/drivers/acpi/acpica/evxfregn.c b/drivers/acpi/acpica/evxfregn.c +index 0a8372bf6a77d1..6fa6b485e30d55 100644 +--- a/drivers/acpi/acpica/evxfregn.c ++++ b/drivers/acpi/acpica/evxfregn.c +@@ -201,8 +201,6 @@ acpi_remove_address_space_handler(acpi_handle device, + + /* Now we can delete the handler object */ + +- acpi_os_release_mutex(handler_obj->address_space. +- context_mutex); + acpi_ut_remove_reference(handler_obj); + goto unlock_and_exit; + } +diff --git a/drivers/acpi/nfit/core.c b/drivers/acpi/nfit/core.c +index 6d4ac934cd499a..1535fe19664655 100644 +--- a/drivers/acpi/nfit/core.c ++++ b/drivers/acpi/nfit/core.c +@@ -454,8 +454,13 @@ int acpi_nfit_ctl(struct nvdimm_bus_descriptor *nd_desc, struct nvdimm *nvdimm, + if (cmd_rc) + *cmd_rc = -EINVAL; + +- if (cmd == ND_CMD_CALL) ++ if (cmd == ND_CMD_CALL) { ++ if (!buf || buf_len < sizeof(*call_pkg)) ++ return -EINVAL; ++ + call_pkg = buf; ++ } ++ + func = cmd_to_func(nfit_mem, cmd, call_pkg, &family); + if (func < 0) + return func; +diff --git a/drivers/acpi/resource.c b/drivers/acpi/resource.c +index d57bc814dec45e..b36b8592667d5f 100644 +--- a/drivers/acpi/resource.c ++++ b/drivers/acpi/resource.c +@@ -250,6 +250,9 @@ static bool acpi_decode_space(struct resource_win *win, + switch (addr->resource_type) { + case ACPI_MEMORY_RANGE: + acpi_dev_memresource_flags(res, len, wp); ++ ++ if (addr->info.mem.caching == ACPI_PREFETCHABLE_MEMORY) ++ res->flags |= IORESOURCE_PREFETCH; + break; + case ACPI_IO_RANGE: + acpi_dev_ioresource_flags(res, len, iodec, +@@ -265,9 +268,6 @@ static bool acpi_decode_space(struct resource_win *win, + if (addr->producer_consumer == ACPI_PRODUCER) + res->flags |= IORESOURCE_WINDOW; + +- if (addr->info.mem.caching == ACPI_PREFETCHABLE_MEMORY) +- res->flags |= IORESOURCE_PREFETCH; +- + return !(res->flags & IORESOURCE_DISABLED); + } + +diff --git a/drivers/ata/sata_highbank.c b/drivers/ata/sata_highbank.c +index dfbf9493e45194..88a44543c598d2 100644 +--- a/drivers/ata/sata_highbank.c ++++ b/drivers/ata/sata_highbank.c +@@ -348,6 +348,7 @@ static int highbank_initialize_phys(struct device *dev, void __iomem *addr) + phy_nodes[phy] = phy_data.np; + cphy_base[phy] = of_iomap(phy_nodes[phy], 0); + if (cphy_base[phy] == NULL) { ++ of_node_put(phy_data.np); + return 0; + } + phy_count += 1; +diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c b/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c +index e668b3baa8c609..1c5d79528ca75e 100644 +--- a/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c ++++ b/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c +@@ -1284,7 +1284,7 @@ static int uvd_v7_0_ring_patch_cs_in_place(struct amdgpu_cs_parser *p, + struct amdgpu_job *job, + struct amdgpu_ib *ib) + { +- struct amdgpu_ring *ring = to_amdgpu_ring(job->base.sched); ++ struct amdgpu_ring *ring = amdgpu_job_ring(job); + unsigned i; + + /* No patching necessary for the first instance */ +diff --git a/drivers/gpu/drm/i915/i915_scheduler.c b/drivers/gpu/drm/i915/i915_scheduler.c +index 762127dd56c538..70a854557e6ec5 100644 +--- a/drivers/gpu/drm/i915/i915_scheduler.c ++++ b/drivers/gpu/drm/i915/i915_scheduler.c +@@ -506,6 +506,6 @@ int __init i915_scheduler_module_init(void) + return 0; + + err_priorities: +- kmem_cache_destroy(slab_priorities); ++ kmem_cache_destroy(slab_dependencies); + return -ENOMEM; + } +diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c +index 26a9f99882e61c..ded9e369e40385 100644 +--- a/drivers/net/bonding/bond_main.c ++++ b/drivers/net/bonding/bond_main.c +@@ -1454,6 +1454,7 @@ static netdev_features_t bond_fix_features(struct net_device *dev, + + #define BOND_VLAN_FEATURES (NETIF_F_HW_CSUM | NETIF_F_SG | \ + NETIF_F_FRAGLIST | NETIF_F_GSO_SOFTWARE | \ ++ NETIF_F_GSO_ENCAP_ALL | \ + NETIF_F_HIGHDMA | NETIF_F_LRO) + + #define BOND_ENC_FEATURES (NETIF_F_HW_CSUM | NETIF_F_SG | \ +diff --git a/drivers/net/dsa/ocelot/felix_vsc9959.c b/drivers/net/dsa/ocelot/felix_vsc9959.c +index 0186482194d206..391c4e3cb66f40 100644 +--- a/drivers/net/dsa/ocelot/felix_vsc9959.c ++++ b/drivers/net/dsa/ocelot/felix_vsc9959.c +@@ -22,7 +22,7 @@ + #define VSC9959_NUM_PORTS 6 + + #define VSC9959_TAS_GCL_ENTRY_MAX 63 +-#define VSC9959_TAS_MIN_GATE_LEN_NS 33 ++#define VSC9959_TAS_MIN_GATE_LEN_NS 35 + #define VSC9959_VCAP_POLICER_BASE 63 + #define VSC9959_VCAP_POLICER_MAX 383 + #define VSC9959_SWITCH_PCI_BAR 4 +@@ -1057,11 +1057,15 @@ static void vsc9959_mdio_bus_free(struct ocelot *ocelot) + mdiobus_free(felix->imdio); + } + +-/* The switch considers any frame (regardless of size) as eligible for +- * transmission if the traffic class gate is open for at least 33 ns. ++/* The switch considers any frame (regardless of size) as eligible ++ * for transmission if the traffic class gate is open for at least ++ * VSC9959_TAS_MIN_GATE_LEN_NS. ++ * + * Overruns are prevented by cropping an interval at the end of the gate time +- * slot for which egress scheduling is blocked, but we need to still keep 33 ns +- * available for one packet to be transmitted, otherwise the port tc will hang. ++ * slot for which egress scheduling is blocked, but we need to still keep ++ * VSC9959_TAS_MIN_GATE_LEN_NS available for one packet to be transmitted, ++ * otherwise the port tc will hang. ++ * + * This function returns the size of a gate interval that remains available for + * setting the guard band, after reserving the space for one egress frame. + */ +@@ -1293,7 +1297,8 @@ static void vsc9959_tas_guard_bands_update(struct ocelot *ocelot, int port) + * per-tc static guard band lengths, so it reduces the + * useful gate interval length. Therefore, be careful + * to calculate a guard band (and therefore max_sdu) +- * that still leaves 33 ns available in the time slot. ++ * that still leaves VSC9959_TAS_MIN_GATE_LEN_NS ++ * available in the time slot. + */ + max_sdu = div_u64(remaining_gate_len_ps, picos_per_byte); + /* A TC gate may be completely closed, which is a +diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h +index 5657ac8cfca001..f1a8ae04782118 100644 +--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h ++++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h +@@ -2084,7 +2084,7 @@ void t4_idma_monitor(struct adapter *adapter, + struct sge_idma_monitor_state *idma, + int hz, int ticks); + int t4_set_vf_mac_acl(struct adapter *adapter, unsigned int vf, +- unsigned int naddr, u8 *addr); ++ u8 start, unsigned int naddr, u8 *addr); + void t4_tp_pio_read(struct adapter *adap, u32 *buff, u32 nregs, + u32 start_index, bool sleep_ok); + void t4_tp_tm_pio_read(struct adapter *adap, u32 *buff, u32 nregs, +diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +index 9cbce1faab26f9..7ce112b95b62e5 100644 +--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c ++++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +@@ -3247,7 +3247,7 @@ static int cxgb4_mgmt_set_vf_mac(struct net_device *dev, int vf, u8 *mac) + + dev_info(pi->adapter->pdev_dev, + "Setting MAC %pM on VF %d\n", mac, vf); +- ret = t4_set_vf_mac_acl(adap, vf + 1, 1, mac); ++ ret = t4_set_vf_mac_acl(adap, vf + 1, pi->lport, 1, mac); + if (!ret) + ether_addr_copy(adap->vfinfo[vf].vf_mac_addr, mac); + return ret; +diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c +index 76de55306c4d01..175bf9b1305888 100644 +--- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c ++++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c +@@ -10215,11 +10215,12 @@ int t4_load_cfg(struct adapter *adap, const u8 *cfg_data, unsigned int size) + * t4_set_vf_mac_acl - Set MAC address for the specified VF + * @adapter: The adapter + * @vf: one of the VFs instantiated by the specified PF ++ * @start: The start port id associated with specified VF + * @naddr: the number of MAC addresses + * @addr: the MAC address(es) to be set to the specified VF + */ + int t4_set_vf_mac_acl(struct adapter *adapter, unsigned int vf, +- unsigned int naddr, u8 *addr) ++ u8 start, unsigned int naddr, u8 *addr) + { + struct fw_acl_mac_cmd cmd; + +@@ -10234,7 +10235,7 @@ int t4_set_vf_mac_acl(struct adapter *adapter, unsigned int vf, + cmd.en_to_len16 = cpu_to_be32((unsigned int)FW_LEN16(cmd)); + cmd.nmac = naddr; + +- switch (adapter->pf) { ++ switch (start) { + case 3: + memcpy(cmd.macaddr3, addr, sizeof(cmd.macaddr3)); + break; +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_domain.c b/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_domain.c +index fc6ae49b5ecce4..d462017c6a9573 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_domain.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_domain.c +@@ -195,7 +195,9 @@ dr_domain_add_vport_cap(struct mlx5dr_domain *dmn, u16 vport) + if (ret) { + mlx5dr_dbg(dmn, "Couldn't insert new vport into xarray (%d)\n", ret); + kvfree(vport_caps); +- return ERR_PTR(ret); ++ if (ret == -EBUSY) ++ return ERR_PTR(-EBUSY); ++ return NULL; + } + + return vport_caps; +diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c +index 7031f41287e094..1ed69e77b89584 100644 +--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c ++++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c +@@ -680,12 +680,11 @@ static int sparx5_start(struct sparx5 *sparx5) + err = -ENXIO; + if (sparx5->fdma_irq >= 0) { + if (GCB_CHIP_ID_REV_ID_GET(sparx5->chip_id) > 0) +- err = devm_request_threaded_irq(sparx5->dev, +- sparx5->fdma_irq, +- NULL, +- sparx5_fdma_handler, +- IRQF_ONESHOT, +- "sparx5-fdma", sparx5); ++ err = devm_request_irq(sparx5->dev, ++ sparx5->fdma_irq, ++ sparx5_fdma_handler, ++ 0, ++ "sparx5-fdma", sparx5); + if (!err) + err = sparx5_fdma_start(sparx5); + if (err) +diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_port.c b/drivers/net/ethernet/microchip/sparx5/sparx5_port.c +index 212bf6f4ed72d4..e1df6bc86949c1 100644 +--- a/drivers/net/ethernet/microchip/sparx5/sparx5_port.c ++++ b/drivers/net/ethernet/microchip/sparx5/sparx5_port.c +@@ -1113,7 +1113,7 @@ int sparx5_port_init(struct sparx5 *sparx5, + spx5_inst_rmw(DEV10G_MAC_MAXLEN_CFG_MAX_LEN_SET(ETH_MAXLEN), + DEV10G_MAC_MAXLEN_CFG_MAX_LEN, + devinst, +- DEV10G_MAC_ENA_CFG(0)); ++ DEV10G_MAC_MAXLEN_CFG(0)); + + /* Handle Signal Detect in 10G PCS */ + spx5_inst_wr(PCS10G_BR_PCS_SD_CFG_SD_POL_SET(sd_pol) | +diff --git a/drivers/net/ethernet/mscc/ocelot_ptp.c b/drivers/net/ethernet/mscc/ocelot_ptp.c +index cb32234a5bf1bc..34a2d8ea3b2d00 100644 +--- a/drivers/net/ethernet/mscc/ocelot_ptp.c ++++ b/drivers/net/ethernet/mscc/ocelot_ptp.c +@@ -14,6 +14,8 @@ + #include <soc/mscc/ocelot.h> + #include "ocelot.h" + ++#define OCELOT_PTP_TX_TSTAMP_TIMEOUT (5 * HZ) ++ + int ocelot_ptp_gettime64(struct ptp_clock_info *ptp, struct timespec64 *ts) + { + struct ocelot *ocelot = container_of(ptp, struct ocelot, ptp_info); +@@ -495,6 +497,28 @@ static int ocelot_traps_to_ptp_rx_filter(unsigned int proto) + return HWTSTAMP_FILTER_NONE; + } + ++static int ocelot_ptp_tx_type_to_cmd(int tx_type, int *ptp_cmd) ++{ ++ switch (tx_type) { ++ case HWTSTAMP_TX_ON: ++ *ptp_cmd = IFH_REW_OP_TWO_STEP_PTP; ++ break; ++ case HWTSTAMP_TX_ONESTEP_SYNC: ++ /* IFH_REW_OP_ONE_STEP_PTP updates the correctionField, ++ * what we need to update is the originTimestamp. ++ */ ++ *ptp_cmd = IFH_REW_OP_ORIGIN_PTP; ++ break; ++ case HWTSTAMP_TX_OFF: ++ *ptp_cmd = 0; ++ break; ++ default: ++ return -ERANGE; ++ } ++ ++ return 0; ++} ++ + int ocelot_hwstamp_get(struct ocelot *ocelot, int port, struct ifreq *ifr) + { + struct ocelot_port *ocelot_port = ocelot->ports[port]; +@@ -521,30 +545,19 @@ EXPORT_SYMBOL(ocelot_hwstamp_get); + int ocelot_hwstamp_set(struct ocelot *ocelot, int port, struct ifreq *ifr) + { + struct ocelot_port *ocelot_port = ocelot->ports[port]; ++ int ptp_cmd, old_ptp_cmd = ocelot_port->ptp_cmd; + bool l2 = false, l4 = false; + struct hwtstamp_config cfg; ++ bool old_l2, old_l4; + int err; + + if (copy_from_user(&cfg, ifr->ifr_data, sizeof(cfg))) + return -EFAULT; + + /* Tx type sanity check */ +- switch (cfg.tx_type) { +- case HWTSTAMP_TX_ON: +- ocelot_port->ptp_cmd = IFH_REW_OP_TWO_STEP_PTP; +- break; +- case HWTSTAMP_TX_ONESTEP_SYNC: +- /* IFH_REW_OP_ONE_STEP_PTP updates the correctional field, we +- * need to update the origin time. +- */ +- ocelot_port->ptp_cmd = IFH_REW_OP_ORIGIN_PTP; +- break; +- case HWTSTAMP_TX_OFF: +- ocelot_port->ptp_cmd = 0; +- break; +- default: +- return -ERANGE; +- } ++ err = ocelot_ptp_tx_type_to_cmd(cfg.tx_type, &ptp_cmd); ++ if (err) ++ return err; + + switch (cfg.rx_filter) { + case HWTSTAMP_FILTER_NONE: +@@ -569,13 +582,27 @@ int ocelot_hwstamp_set(struct ocelot *ocelot, int port, struct ifreq *ifr) + return -ERANGE; + } + ++ old_l2 = ocelot_port->trap_proto & OCELOT_PROTO_PTP_L2; ++ old_l4 = ocelot_port->trap_proto & OCELOT_PROTO_PTP_L4; ++ + err = ocelot_setup_ptp_traps(ocelot, port, l2, l4); + if (err) + return err; + ++ ocelot_port->ptp_cmd = ptp_cmd; ++ + cfg.rx_filter = ocelot_traps_to_ptp_rx_filter(ocelot_port->trap_proto); + +- return copy_to_user(ifr->ifr_data, &cfg, sizeof(cfg)) ? -EFAULT : 0; ++ if (copy_to_user(ifr->ifr_data, &cfg, sizeof(cfg))) { ++ err = -EFAULT; ++ goto out_restore_ptp_traps; ++ } ++ ++ return 0; ++out_restore_ptp_traps: ++ ocelot_setup_ptp_traps(ocelot, port, old_l2, old_l4); ++ ocelot_port->ptp_cmd = old_ptp_cmd; ++ return err; + } + EXPORT_SYMBOL(ocelot_hwstamp_set); + +@@ -607,34 +634,87 @@ int ocelot_get_ts_info(struct ocelot *ocelot, int port, + } + EXPORT_SYMBOL(ocelot_get_ts_info); + +-static int ocelot_port_add_txtstamp_skb(struct ocelot *ocelot, int port, +- struct sk_buff *clone) ++static struct sk_buff *ocelot_port_dequeue_ptp_tx_skb(struct ocelot *ocelot, ++ int port, u8 ts_id, ++ u32 seqid) + { + struct ocelot_port *ocelot_port = ocelot->ports[port]; +- unsigned long flags; ++ struct sk_buff *skb, *skb_tmp, *skb_match = NULL; ++ struct ptp_header *hdr; + +- spin_lock_irqsave(&ocelot->ts_id_lock, flags); ++ spin_lock(&ocelot->ts_id_lock); + +- if (ocelot_port->ptp_skbs_in_flight == OCELOT_MAX_PTP_ID || +- ocelot->ptp_skbs_in_flight == OCELOT_PTP_FIFO_SIZE) { +- spin_unlock_irqrestore(&ocelot->ts_id_lock, flags); +- return -EBUSY; ++ skb_queue_walk_safe(&ocelot_port->tx_skbs, skb, skb_tmp) { ++ if (OCELOT_SKB_CB(skb)->ts_id != ts_id) ++ continue; ++ ++ /* Check that the timestamp ID is for the expected PTP ++ * sequenceId. We don't have to test ptp_parse_header() against ++ * NULL, because we've pre-validated the packet's ptp_class. ++ */ ++ hdr = ptp_parse_header(skb, OCELOT_SKB_CB(skb)->ptp_class); ++ if (seqid != ntohs(hdr->sequence_id)) ++ continue; ++ ++ __skb_unlink(skb, &ocelot_port->tx_skbs); ++ ocelot->ptp_skbs_in_flight--; ++ skb_match = skb; ++ break; + } + +- skb_shinfo(clone)->tx_flags |= SKBTX_IN_PROGRESS; +- /* Store timestamp ID in OCELOT_SKB_CB(clone)->ts_id */ +- OCELOT_SKB_CB(clone)->ts_id = ocelot_port->ts_id; ++ spin_unlock(&ocelot->ts_id_lock); + +- ocelot_port->ts_id++; +- if (ocelot_port->ts_id == OCELOT_MAX_PTP_ID) +- ocelot_port->ts_id = 0; ++ return skb_match; ++} ++ ++static int ocelot_port_queue_ptp_tx_skb(struct ocelot *ocelot, int port, ++ struct sk_buff *clone) ++{ ++ struct ocelot_port *ocelot_port = ocelot->ports[port]; ++ DECLARE_BITMAP(ts_id_in_flight, OCELOT_MAX_PTP_ID); ++ struct sk_buff *skb, *skb_tmp; ++ unsigned long n; ++ ++ spin_lock(&ocelot->ts_id_lock); ++ ++ /* To get a better chance of acquiring a timestamp ID, first flush the ++ * stale packets still waiting in the TX timestamping queue. They are ++ * probably lost. ++ */ ++ skb_queue_walk_safe(&ocelot_port->tx_skbs, skb, skb_tmp) { ++ if (time_before(OCELOT_SKB_CB(skb)->ptp_tx_time + ++ OCELOT_PTP_TX_TSTAMP_TIMEOUT, jiffies)) { ++ dev_warn_ratelimited(ocelot->dev, ++ "port %d invalidating stale timestamp ID %u which seems lost\n", ++ port, OCELOT_SKB_CB(skb)->ts_id); ++ __skb_unlink(skb, &ocelot_port->tx_skbs); ++ kfree_skb(skb); ++ ocelot->ptp_skbs_in_flight--; ++ } else { ++ __set_bit(OCELOT_SKB_CB(skb)->ts_id, ts_id_in_flight); ++ } ++ } ++ ++ if (ocelot->ptp_skbs_in_flight == OCELOT_PTP_FIFO_SIZE) { ++ spin_unlock(&ocelot->ts_id_lock); ++ return -EBUSY; ++ } ++ ++ n = find_first_zero_bit(ts_id_in_flight, OCELOT_MAX_PTP_ID); ++ if (n == OCELOT_MAX_PTP_ID) { ++ spin_unlock(&ocelot->ts_id_lock); ++ return -EBUSY; ++ } + +- ocelot_port->ptp_skbs_in_flight++; ++ /* Found an available timestamp ID, use it */ ++ OCELOT_SKB_CB(clone)->ts_id = n; ++ OCELOT_SKB_CB(clone)->ptp_tx_time = jiffies; + ocelot->ptp_skbs_in_flight++; ++ __skb_queue_tail(&ocelot_port->tx_skbs, clone); + +- skb_queue_tail(&ocelot_port->tx_skbs, clone); ++ spin_unlock(&ocelot->ts_id_lock); + +- spin_unlock_irqrestore(&ocelot->ts_id_lock, flags); ++ dev_dbg_ratelimited(ocelot->dev, "port %d timestamp id %lu\n", port, n); + + return 0; + } +@@ -691,10 +771,14 @@ int ocelot_port_txtstamp_request(struct ocelot *ocelot, int port, + if (!(*clone)) + return -ENOMEM; + +- err = ocelot_port_add_txtstamp_skb(ocelot, port, *clone); +- if (err) ++ /* Store timestamp ID in OCELOT_SKB_CB(clone)->ts_id */ ++ err = ocelot_port_queue_ptp_tx_skb(ocelot, port, *clone); ++ if (err) { ++ kfree_skb(*clone); + return err; ++ } + ++ skb_shinfo(*clone)->tx_flags |= SKBTX_IN_PROGRESS; + OCELOT_SKB_CB(skb)->ptp_cmd = ptp_cmd; + OCELOT_SKB_CB(*clone)->ptp_class = ptp_class; + } +@@ -730,28 +814,15 @@ static void ocelot_get_hwtimestamp(struct ocelot *ocelot, + spin_unlock_irqrestore(&ocelot->ptp_clock_lock, flags); + } + +-static bool ocelot_validate_ptp_skb(struct sk_buff *clone, u16 seqid) +-{ +- struct ptp_header *hdr; +- +- hdr = ptp_parse_header(clone, OCELOT_SKB_CB(clone)->ptp_class); +- if (WARN_ON(!hdr)) +- return false; +- +- return seqid == ntohs(hdr->sequence_id); +-} +- + void ocelot_get_txtstamp(struct ocelot *ocelot) + { + int budget = OCELOT_PTP_QUEUE_SZ; + + while (budget--) { +- struct sk_buff *skb, *skb_tmp, *skb_match = NULL; + struct skb_shared_hwtstamps shhwtstamps; + u32 val, id, seqid, txport; +- struct ocelot_port *port; ++ struct sk_buff *skb_match; + struct timespec64 ts; +- unsigned long flags; + + val = ocelot_read(ocelot, SYS_PTP_STATUS); + +@@ -766,36 +837,14 @@ void ocelot_get_txtstamp(struct ocelot *ocelot) + txport = SYS_PTP_STATUS_PTP_MESS_TXPORT_X(val); + seqid = SYS_PTP_STATUS_PTP_MESS_SEQ_ID(val); + +- port = ocelot->ports[txport]; +- +- spin_lock(&ocelot->ts_id_lock); +- port->ptp_skbs_in_flight--; +- ocelot->ptp_skbs_in_flight--; +- spin_unlock(&ocelot->ts_id_lock); +- + /* Retrieve its associated skb */ +-try_again: +- spin_lock_irqsave(&port->tx_skbs.lock, flags); +- +- skb_queue_walk_safe(&port->tx_skbs, skb, skb_tmp) { +- if (OCELOT_SKB_CB(skb)->ts_id != id) +- continue; +- __skb_unlink(skb, &port->tx_skbs); +- skb_match = skb; +- break; +- } +- +- spin_unlock_irqrestore(&port->tx_skbs.lock, flags); +- +- if (WARN_ON(!skb_match)) +- continue; +- +- if (!ocelot_validate_ptp_skb(skb_match, seqid)) { +- dev_err_ratelimited(ocelot->dev, +- "port %d received stale TX timestamp for seqid %d, discarding\n", +- txport, seqid); +- dev_kfree_skb_any(skb); +- goto try_again; ++ skb_match = ocelot_port_dequeue_ptp_tx_skb(ocelot, txport, id, ++ seqid); ++ if (!skb_match) { ++ dev_warn_ratelimited(ocelot->dev, ++ "port %d received TX timestamp (seqid %d, ts id %u) for packet previously declared stale\n", ++ txport, seqid, id); ++ goto next_ts; + } + + /* Get the h/w timestamp */ +@@ -806,7 +855,7 @@ void ocelot_get_txtstamp(struct ocelot *ocelot) + shhwtstamps.hwtstamp = ktime_set(ts.tv_sec, ts.tv_nsec); + skb_complete_tx_timestamp(skb_match, &shhwtstamps); + +- /* Next ts */ ++next_ts: + ocelot_write(ocelot, SYS_PTP_NXT_PTP_NXT, SYS_PTP_NXT); + } + } +diff --git a/drivers/net/ethernet/qualcomm/qca_spi.c b/drivers/net/ethernet/qualcomm/qca_spi.c +index 926a087ae1c62f..b7af824116ea29 100644 +--- a/drivers/net/ethernet/qualcomm/qca_spi.c ++++ b/drivers/net/ethernet/qualcomm/qca_spi.c +@@ -67,7 +67,7 @@ MODULE_PARM_DESC(qcaspi_burst_len, "Number of data bytes per burst. Use 1-5000." + + #define QCASPI_PLUGGABLE_MIN 0 + #define QCASPI_PLUGGABLE_MAX 1 +-static int qcaspi_pluggable = QCASPI_PLUGGABLE_MIN; ++static int qcaspi_pluggable = QCASPI_PLUGGABLE_MAX; + module_param(qcaspi_pluggable, int, 0); + MODULE_PARM_DESC(qcaspi_pluggable, "Pluggable SPI connection (yes/no)."); + +@@ -829,7 +829,6 @@ qcaspi_netdev_init(struct net_device *dev) + + dev->mtu = QCAFRM_MAX_MTU; + dev->type = ARPHRD_ETHER; +- qca->clkspeed = qcaspi_clkspeed; + qca->burst_len = qcaspi_burst_len; + qca->spi_thread = NULL; + qca->buffer_size = (dev->mtu + VLAN_ETH_HLEN + QCAFRM_HEADER_LEN + +@@ -918,17 +917,15 @@ qca_spi_probe(struct spi_device *spi) + legacy_mode = of_property_read_bool(spi->dev.of_node, + "qca,legacy-mode"); + +- if (qcaspi_clkspeed == 0) { +- if (spi->max_speed_hz) +- qcaspi_clkspeed = spi->max_speed_hz; +- else +- qcaspi_clkspeed = QCASPI_CLK_SPEED; +- } ++ if (qcaspi_clkspeed) ++ spi->max_speed_hz = qcaspi_clkspeed; ++ else if (!spi->max_speed_hz) ++ spi->max_speed_hz = QCASPI_CLK_SPEED; + +- if ((qcaspi_clkspeed < QCASPI_CLK_SPEED_MIN) || +- (qcaspi_clkspeed > QCASPI_CLK_SPEED_MAX)) { +- dev_err(&spi->dev, "Invalid clkspeed: %d\n", +- qcaspi_clkspeed); ++ if (spi->max_speed_hz < QCASPI_CLK_SPEED_MIN || ++ spi->max_speed_hz > QCASPI_CLK_SPEED_MAX) { ++ dev_err(&spi->dev, "Invalid clkspeed: %u\n", ++ spi->max_speed_hz); + return -EINVAL; + } + +@@ -953,14 +950,13 @@ qca_spi_probe(struct spi_device *spi) + return -EINVAL; + } + +- dev_info(&spi->dev, "ver=%s, clkspeed=%d, burst_len=%d, pluggable=%d\n", ++ dev_info(&spi->dev, "ver=%s, clkspeed=%u, burst_len=%d, pluggable=%d\n", + QCASPI_DRV_VERSION, +- qcaspi_clkspeed, ++ spi->max_speed_hz, + qcaspi_burst_len, + qcaspi_pluggable); + + spi->mode = SPI_MODE_3; +- spi->max_speed_hz = qcaspi_clkspeed; + if (spi_setup(spi) < 0) { + dev_err(&spi->dev, "Unable to setup SPI device\n"); + return -EFAULT; +diff --git a/drivers/net/ethernet/qualcomm/qca_spi.h b/drivers/net/ethernet/qualcomm/qca_spi.h +index 58ad910068d4bc..b3b17bd46e12c2 100644 +--- a/drivers/net/ethernet/qualcomm/qca_spi.h ++++ b/drivers/net/ethernet/qualcomm/qca_spi.h +@@ -101,7 +101,6 @@ struct qcaspi { + #endif + + /* user configurable options */ +- u32 clkspeed; + u8 legacy_mode; + u16 burst_len; + }; +diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c +index 293eaf6b3ec9e0..872640a9e73a15 100644 +--- a/drivers/net/team/team.c ++++ b/drivers/net/team/team.c +@@ -984,7 +984,8 @@ static void team_port_disable(struct team *team, + + #define TEAM_VLAN_FEATURES (NETIF_F_HW_CSUM | NETIF_F_SG | \ + NETIF_F_FRAGLIST | NETIF_F_GSO_SOFTWARE | \ +- NETIF_F_HIGHDMA | NETIF_F_LRO) ++ NETIF_F_HIGHDMA | NETIF_F_LRO | \ ++ NETIF_F_GSO_ENCAP_ALL) + + #define TEAM_ENC_FEATURES (NETIF_F_HW_CSUM | NETIF_F_SG | \ + NETIF_F_RXCSUM | NETIF_F_GSO_SOFTWARE) +diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c +index 95b5ab4b964e25..8425226c09f0d9 100644 +--- a/drivers/net/xen-netfront.c ++++ b/drivers/net/xen-netfront.c +@@ -867,7 +867,7 @@ static netdev_tx_t xennet_start_xmit(struct sk_buff *skb, struct net_device *dev + static int xennet_close(struct net_device *dev) + { + struct netfront_info *np = netdev_priv(dev); +- unsigned int num_queues = dev->real_num_tx_queues; ++ unsigned int num_queues = np->queues ? dev->real_num_tx_queues : 0; + unsigned int i; + struct netfront_queue *queue; + netif_tx_stop_all_queues(np->netdev); +@@ -882,6 +882,9 @@ static void xennet_destroy_queues(struct netfront_info *info) + { + unsigned int i; + ++ if (!info->queues) ++ return; ++ + for (i = 0; i < info->netdev->real_num_tx_queues; i++) { + struct netfront_queue *queue = &info->queues[i]; + +diff --git a/drivers/ptp/ptp_kvm_arm.c b/drivers/ptp/ptp_kvm_arm.c +index b7d28c8dfb84e3..e68e6943167beb 100644 +--- a/drivers/ptp/ptp_kvm_arm.c ++++ b/drivers/ptp/ptp_kvm_arm.c +@@ -22,6 +22,10 @@ int kvm_arch_ptp_init(void) + return 0; + } + ++void kvm_arch_ptp_exit(void) ++{ ++} ++ + int kvm_arch_ptp_get_clock(struct timespec64 *ts) + { + return kvm_arch_ptp_get_crosststamp(NULL, ts, NULL); +diff --git a/drivers/ptp/ptp_kvm_common.c b/drivers/ptp/ptp_kvm_common.c +index fcae32f56f25a2..051114a592865d 100644 +--- a/drivers/ptp/ptp_kvm_common.c ++++ b/drivers/ptp/ptp_kvm_common.c +@@ -130,6 +130,7 @@ static struct kvm_ptp_clock kvm_ptp_clock; + static void __exit ptp_kvm_exit(void) + { + ptp_clock_unregister(kvm_ptp_clock.ptp_clock); ++ kvm_arch_ptp_exit(); + } + + static int __init ptp_kvm_init(void) +diff --git a/drivers/ptp/ptp_kvm_x86.c b/drivers/ptp/ptp_kvm_x86.c +index 4991054a213506..5e5b2ef785474f 100644 +--- a/drivers/ptp/ptp_kvm_x86.c ++++ b/drivers/ptp/ptp_kvm_x86.c +@@ -14,27 +14,64 @@ + #include <uapi/linux/kvm_para.h> + #include <linux/ptp_clock_kernel.h> + #include <linux/ptp_kvm.h> ++#include <linux/set_memory.h> + + static phys_addr_t clock_pair_gpa; +-static struct kvm_clock_pairing clock_pair; ++static struct kvm_clock_pairing clock_pair_glbl; ++static struct kvm_clock_pairing *clock_pair; + + int kvm_arch_ptp_init(void) + { ++ struct page *p; + long ret; + + if (!kvm_para_available()) +- return -ENODEV; ++ return -EOPNOTSUPP; ++ ++ if (cc_platform_has(CC_ATTR_GUEST_MEM_ENCRYPT)) { ++ p = alloc_page(GFP_KERNEL | __GFP_ZERO); ++ if (!p) ++ return -ENOMEM; ++ ++ clock_pair = page_address(p); ++ ret = set_memory_decrypted((unsigned long)clock_pair, 1); ++ if (ret) { ++ __free_page(p); ++ clock_pair = NULL; ++ goto nofree; ++ } ++ } else { ++ clock_pair = &clock_pair_glbl; ++ } + +- clock_pair_gpa = slow_virt_to_phys(&clock_pair); +- if (!pvclock_get_pvti_cpu0_va()) +- return -ENODEV; ++ clock_pair_gpa = slow_virt_to_phys(clock_pair); ++ if (!pvclock_get_pvti_cpu0_va()) { ++ ret = -EOPNOTSUPP; ++ goto err; ++ } + + ret = kvm_hypercall2(KVM_HC_CLOCK_PAIRING, clock_pair_gpa, + KVM_CLOCK_PAIRING_WALLCLOCK); +- if (ret == -KVM_ENOSYS) +- return -ENODEV; ++ if (ret == -KVM_ENOSYS) { ++ ret = -EOPNOTSUPP; ++ goto err; ++ } + + return ret; ++ ++err: ++ kvm_arch_ptp_exit(); ++nofree: ++ return ret; ++} ++ ++void kvm_arch_ptp_exit(void) ++{ ++ if (cc_platform_has(CC_ATTR_GUEST_MEM_ENCRYPT)) { ++ WARN_ON(set_memory_encrypted((unsigned long)clock_pair, 1)); ++ free_page((unsigned long)clock_pair); ++ clock_pair = NULL; ++ } + } + + int kvm_arch_ptp_get_clock(struct timespec64 *ts) +@@ -49,8 +86,8 @@ int kvm_arch_ptp_get_clock(struct timespec64 *ts) + return -EOPNOTSUPP; + } + +- ts->tv_sec = clock_pair.sec; +- ts->tv_nsec = clock_pair.nsec; ++ ts->tv_sec = clock_pair->sec; ++ ts->tv_nsec = clock_pair->nsec; + + return 0; + } +@@ -81,9 +118,9 @@ int kvm_arch_ptp_get_crosststamp(u64 *cycle, struct timespec64 *tspec, + pr_err_ratelimited("clock pairing hypercall ret %lu\n", ret); + return -EOPNOTSUPP; + } +- tspec->tv_sec = clock_pair.sec; +- tspec->tv_nsec = clock_pair.nsec; +- *cycle = __pvclock_read_cycles(src, clock_pair.tsc); ++ tspec->tv_sec = clock_pair->sec; ++ tspec->tv_nsec = clock_pair->nsec; ++ *cycle = __pvclock_read_cycles(src, clock_pair->tsc); + } while (pvclock_read_retry(src, version)); + + *cs = &kvm_clock; +diff --git a/drivers/spi/spi-aspeed-smc.c b/drivers/spi/spi-aspeed-smc.c +index b90571396a604c..5015c2f6fd9f2a 100644 +--- a/drivers/spi/spi-aspeed-smc.c ++++ b/drivers/spi/spi-aspeed-smc.c +@@ -239,7 +239,7 @@ static ssize_t aspeed_spi_read_user(struct aspeed_spi_chip *chip, + + ret = aspeed_spi_send_cmd_addr(chip, op->addr.nbytes, offset, op->cmd.opcode); + if (ret < 0) +- return ret; ++ goto stop_user; + + if (op->dummy.buswidth && op->dummy.nbytes) { + for (i = 0; i < op->dummy.nbytes / op->dummy.buswidth; i++) +@@ -249,8 +249,9 @@ static ssize_t aspeed_spi_read_user(struct aspeed_spi_chip *chip, + aspeed_spi_set_io_mode(chip, io_mode); + + aspeed_spi_read_from_ahb(buf, chip->ahb_base, len); ++stop_user: + aspeed_spi_stop_user(chip); +- return 0; ++ return ret; + } + + static ssize_t aspeed_spi_write_user(struct aspeed_spi_chip *chip, +@@ -261,10 +262,11 @@ static ssize_t aspeed_spi_write_user(struct aspeed_spi_chip *chip, + aspeed_spi_start_user(chip); + ret = aspeed_spi_send_cmd_addr(chip, op->addr.nbytes, op->addr.val, op->cmd.opcode); + if (ret < 0) +- return ret; ++ goto stop_user; + aspeed_spi_write_to_ahb(chip->ahb_base, op->data.buf.out, op->data.nbytes); ++stop_user: + aspeed_spi_stop_user(chip); +- return 0; ++ return ret; + } + + /* support for 1-1-1, 1-1-2 or 1-1-4 */ +diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c +index dd5b1c5691e11e..c1de38de280619 100644 +--- a/drivers/usb/dwc2/hcd.c ++++ b/drivers/usb/dwc2/hcd.c +@@ -3546,11 +3546,9 @@ static int dwc2_hcd_hub_control(struct dwc2_hsotg *hsotg, u16 typereq, + port_status |= USB_PORT_STAT_C_OVERCURRENT << 16; + } + +- if (!hsotg->flags.b.port_connect_status) { ++ if (dwc2_is_device_mode(hsotg)) { + /* +- * The port is disconnected, which means the core is +- * either in device mode or it soon will be. Just +- * return 0's for the remainder of the port status ++ * Just return 0's for the remainder of the port status + * since the port register can't be read if the core + * is in device mode. + */ +@@ -3620,13 +3618,11 @@ static int dwc2_hcd_hub_control(struct dwc2_hsotg *hsotg, u16 typereq, + if (wvalue != USB_PORT_FEAT_TEST && (!windex || windex > 1)) + goto error; + +- if (!hsotg->flags.b.port_connect_status) { ++ if (dwc2_is_device_mode(hsotg)) { + /* +- * The port is disconnected, which means the core is +- * either in device mode or it soon will be. Just +- * return without doing anything since the port +- * register can't be written if the core is in device +- * mode. ++ * Just return 0's for the remainder of the port status ++ * since the port register can't be read if the core ++ * is in device mode. + */ + break; + } +@@ -4349,7 +4345,7 @@ static int _dwc2_hcd_suspend(struct usb_hcd *hcd) + if (hsotg->bus_suspended) + goto skip_power_saving; + +- if (hsotg->flags.b.port_connect_status == 0) ++ if (!(dwc2_read_hprt0(hsotg) & HPRT0_CONNSTS)) + goto skip_power_saving; + + switch (hsotg->params.power_down) { +@@ -4431,6 +4427,7 @@ static int _dwc2_hcd_resume(struct usb_hcd *hcd) + * Power Down mode. + */ + if (hprt0 & HPRT0_CONNSTS) { ++ set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); + hsotg->lx_state = DWC2_L0; + goto unlock; + } +diff --git a/drivers/usb/dwc3/dwc3-xilinx.c b/drivers/usb/dwc3/dwc3-xilinx.c +index 0745e9f11b2ef4..a8bda2a81acd35 100644 +--- a/drivers/usb/dwc3/dwc3-xilinx.c ++++ b/drivers/usb/dwc3/dwc3-xilinx.c +@@ -122,8 +122,11 @@ static int dwc3_xlnx_init_zynqmp(struct dwc3_xlnx *priv_data) + * in use but the usb3-phy entry is missing from the device tree. + * Therefore, skip these operations in this case. + */ +- if (!priv_data->usb3_phy) ++ if (!priv_data->usb3_phy) { ++ /* Deselect the PIPE Clock Select bit in FPD PIPE Clock register */ ++ writel(PIPE_CLK_DESELECT, priv_data->regs + XLNX_USB_FPD_PIPE_CLK); + goto skip_usb3_phy; ++ } + + crst = devm_reset_control_get_exclusive(dev, "usb_crst"); + if (IS_ERR(crst)) { +diff --git a/drivers/usb/gadget/function/u_serial.c b/drivers/usb/gadget/function/u_serial.c +index 1f143c6ba86bdc..8802dd53fbea9f 100644 +--- a/drivers/usb/gadget/function/u_serial.c ++++ b/drivers/usb/gadget/function/u_serial.c +@@ -570,9 +570,12 @@ static int gs_start_io(struct gs_port *port) + * we didn't in gs_start_tx() */ + tty_wakeup(port->port.tty); + } else { +- gs_free_requests(ep, head, &port->read_allocated); +- gs_free_requests(port->port_usb->in, &port->write_pool, +- &port->write_allocated); ++ /* Free reqs only if we are still connected */ ++ if (port->port_usb) { ++ gs_free_requests(ep, head, &port->read_allocated); ++ gs_free_requests(port->port_usb->in, &port->write_pool, ++ &port->write_allocated); ++ } + status = -EIO; + } + +diff --git a/drivers/usb/host/ehci-sh.c b/drivers/usb/host/ehci-sh.c +index c25c51d26f2603..395913113686e1 100644 +--- a/drivers/usb/host/ehci-sh.c ++++ b/drivers/usb/host/ehci-sh.c +@@ -120,8 +120,12 @@ static int ehci_hcd_sh_probe(struct platform_device *pdev) + if (IS_ERR(priv->iclk)) + priv->iclk = NULL; + +- clk_enable(priv->fclk); +- clk_enable(priv->iclk); ++ ret = clk_enable(priv->fclk); ++ if (ret) ++ goto fail_request_resource; ++ ret = clk_enable(priv->iclk); ++ if (ret) ++ goto fail_iclk; + + ret = usb_add_hcd(hcd, irq, IRQF_SHARED); + if (ret != 0) { +@@ -137,6 +141,7 @@ static int ehci_hcd_sh_probe(struct platform_device *pdev) + + fail_add_hcd: + clk_disable(priv->iclk); ++fail_iclk: + clk_disable(priv->fclk); + + fail_request_resource: +diff --git a/drivers/usb/host/max3421-hcd.c b/drivers/usb/host/max3421-hcd.c +index 19111e83ac1312..ab12d76b01fbe5 100644 +--- a/drivers/usb/host/max3421-hcd.c ++++ b/drivers/usb/host/max3421-hcd.c +@@ -785,11 +785,17 @@ max3421_check_unlink(struct usb_hcd *hcd) + retval = 1; + dev_dbg(&spi->dev, "%s: URB %p unlinked=%d", + __func__, urb, urb->unlinked); +- usb_hcd_unlink_urb_from_ep(hcd, urb); +- spin_unlock_irqrestore(&max3421_hcd->lock, +- flags); +- usb_hcd_giveback_urb(hcd, urb, 0); +- spin_lock_irqsave(&max3421_hcd->lock, flags); ++ if (urb == max3421_hcd->curr_urb) { ++ max3421_hcd->urb_done = 1; ++ max3421_hcd->hien &= ~(BIT(MAX3421_HI_HXFRDN_BIT) | ++ BIT(MAX3421_HI_RCVDAV_BIT)); ++ } else { ++ usb_hcd_unlink_urb_from_ep(hcd, urb); ++ spin_unlock_irqrestore(&max3421_hcd->lock, ++ flags); ++ usb_hcd_giveback_urb(hcd, urb, 0); ++ spin_lock_irqsave(&max3421_hcd->lock, flags); ++ } + } + } + } +diff --git a/drivers/usb/typec/anx7411.c b/drivers/usb/typec/anx7411.c +index b8f3b75fd7eb91..dfe4affa17570a 100644 +--- a/drivers/usb/typec/anx7411.c ++++ b/drivers/usb/typec/anx7411.c +@@ -289,6 +289,8 @@ struct anx7411_data { + struct power_supply *psy; + struct power_supply_desc psy_desc; + struct device *dev; ++ struct fwnode_handle *switch_node; ++ struct fwnode_handle *mux_node; + }; + + static u8 snk_identity[] = { +@@ -1020,6 +1022,16 @@ static void anx7411_port_unregister_altmodes(struct typec_altmode **adev) + } + } + ++static void anx7411_port_unregister(struct typec_params *typecp) ++{ ++ fwnode_handle_put(typecp->caps.fwnode); ++ anx7411_port_unregister_altmodes(typecp->port_amode); ++ if (typecp->port) ++ typec_unregister_port(typecp->port); ++ if (typecp->role_sw) ++ usb_role_switch_put(typecp->role_sw); ++} ++ + static int anx7411_usb_mux_set(struct typec_mux_dev *mux, + struct typec_mux_state *state) + { +@@ -1088,6 +1100,7 @@ static void anx7411_unregister_mux(struct anx7411_data *ctx) + if (ctx->typec.typec_mux) { + typec_mux_unregister(ctx->typec.typec_mux); + ctx->typec.typec_mux = NULL; ++ fwnode_handle_put(ctx->mux_node); + } + } + +@@ -1096,6 +1109,7 @@ static void anx7411_unregister_switch(struct anx7411_data *ctx) + if (ctx->typec.typec_switch) { + typec_switch_unregister(ctx->typec.typec_switch); + ctx->typec.typec_switch = NULL; ++ fwnode_handle_put(ctx->switch_node); + } + } + +@@ -1103,28 +1117,29 @@ static int anx7411_typec_switch_probe(struct anx7411_data *ctx, + struct device *dev) + { + int ret; +- struct device_node *node; + +- node = of_get_child_by_name(dev->of_node, "orientation_switch"); +- if (!node) ++ ctx->switch_node = device_get_named_child_node(dev, "orientation_switch"); ++ if (!ctx->switch_node) + return 0; + +- ret = anx7411_register_switch(ctx, dev, &node->fwnode); ++ ret = anx7411_register_switch(ctx, dev, ctx->switch_node); + if (ret) { + dev_err(dev, "failed register switch"); ++ fwnode_handle_put(ctx->switch_node); + return ret; + } + +- node = of_get_child_by_name(dev->of_node, "mode_switch"); +- if (!node) { ++ ctx->mux_node = device_get_named_child_node(dev, "mode_switch"); ++ if (!ctx->mux_node) { + dev_err(dev, "no typec mux exist"); + ret = -ENODEV; + goto unregister_switch; + } + +- ret = anx7411_register_mux(ctx, dev, &node->fwnode); ++ ret = anx7411_register_mux(ctx, dev, ctx->mux_node); + if (ret) { + dev_err(dev, "failed register mode switch"); ++ fwnode_handle_put(ctx->mux_node); + ret = -ENODEV; + goto unregister_switch; + } +@@ -1153,34 +1168,34 @@ static int anx7411_typec_port_probe(struct anx7411_data *ctx, + ret = fwnode_property_read_string(fwnode, "power-role", &buf); + if (ret) { + dev_err(dev, "power-role not found: %d\n", ret); +- return ret; ++ goto put_fwnode; + } + + ret = typec_find_port_power_role(buf); + if (ret < 0) +- return ret; ++ goto put_fwnode; + cap->type = ret; + + ret = fwnode_property_read_string(fwnode, "data-role", &buf); + if (ret) { + dev_err(dev, "data-role not found: %d\n", ret); +- return ret; ++ goto put_fwnode; + } + + ret = typec_find_port_data_role(buf); + if (ret < 0) +- return ret; ++ goto put_fwnode; + cap->data = ret; + + ret = fwnode_property_read_string(fwnode, "try-power-role", &buf); + if (ret) { + dev_err(dev, "try-power-role not found: %d\n", ret); +- return ret; ++ goto put_fwnode; + } + + ret = typec_find_power_role(buf); + if (ret < 0) +- return ret; ++ goto put_fwnode; + cap->prefer_role = ret; + + /* Get source pdos */ +@@ -1192,7 +1207,7 @@ static int anx7411_typec_port_probe(struct anx7411_data *ctx, + typecp->src_pdo_nr); + if (ret < 0) { + dev_err(dev, "source cap validate failed: %d\n", ret); +- return -EINVAL; ++ goto put_fwnode; + } + + typecp->caps_flags |= HAS_SOURCE_CAP; +@@ -1206,7 +1221,7 @@ static int anx7411_typec_port_probe(struct anx7411_data *ctx, + typecp->sink_pdo_nr); + if (ret < 0) { + dev_err(dev, "sink cap validate failed: %d\n", ret); +- return -EINVAL; ++ goto put_fwnode; + } + + for (i = 0; i < typecp->sink_pdo_nr; i++) { +@@ -1250,13 +1265,21 @@ static int anx7411_typec_port_probe(struct anx7411_data *ctx, + ret = PTR_ERR(ctx->typec.port); + ctx->typec.port = NULL; + dev_err(dev, "Failed to register type c port %d\n", ret); +- return ret; ++ goto put_usb_role_switch; + } + + typec_port_register_altmodes(ctx->typec.port, NULL, ctx, + ctx->typec.port_amode, + MAX_ALTMODE); + return 0; ++ ++put_usb_role_switch: ++ if (ctx->typec.role_sw) ++ usb_role_switch_put(ctx->typec.role_sw); ++put_fwnode: ++ fwnode_handle_put(fwnode); ++ ++ return ret; + } + + static int anx7411_typec_check_connection(struct anx7411_data *ctx) +@@ -1528,8 +1551,7 @@ static int anx7411_i2c_probe(struct i2c_client *client, + destroy_workqueue(plat->workqueue); + + free_typec_port: +- typec_unregister_port(plat->typec.port); +- anx7411_port_unregister_altmodes(plat->typec.port_amode); ++ anx7411_port_unregister(&plat->typec); + + free_typec_switch: + anx7411_unregister_switch(plat); +@@ -1554,17 +1576,11 @@ static void anx7411_i2c_remove(struct i2c_client *client) + if (plat->spi_client) + i2c_unregister_device(plat->spi_client); + +- if (plat->typec.role_sw) +- usb_role_switch_put(plat->typec.role_sw); +- + anx7411_unregister_mux(plat); + + anx7411_unregister_switch(plat); + +- if (plat->typec.port) +- typec_unregister_port(plat->typec.port); +- +- anx7411_port_unregister_altmodes(plat->typec.port_amode); ++ anx7411_port_unregister(&plat->typec); + } + + static const struct i2c_device_id anx7411_id[] = { +diff --git a/fs/exfat/dir.c b/fs/exfat/dir.c +index 51b03b0dd5f752..d58c6901805101 100644 +--- a/fs/exfat/dir.c ++++ b/fs/exfat/dir.c +@@ -613,6 +613,10 @@ int exfat_free_dentry_set(struct exfat_entry_set_cache *es, int sync) + bforget(es->bh[i]); + else + brelse(es->bh[i]); ++ ++ if (IS_DYNAMIC_ES(es)) ++ kfree(es->bh); ++ + kfree(es); + return err; + } +@@ -845,6 +849,7 @@ struct exfat_entry_set_cache *exfat_get_dentry_set(struct super_block *sb, + /* byte offset in sector */ + off = EXFAT_BLK_OFFSET(byte_offset, sb); + es->start_off = off; ++ es->bh = es->__bh; + + /* sector offset in cluster */ + sec = EXFAT_B_TO_BLK(byte_offset, sb); +@@ -864,6 +869,16 @@ struct exfat_entry_set_cache *exfat_get_dentry_set(struct super_block *sb, + es->num_entries = num_entries; + + num_bh = EXFAT_B_TO_BLK_ROUND_UP(off + num_entries * DENTRY_SIZE, sb); ++ if (num_bh > ARRAY_SIZE(es->__bh)) { ++ es->bh = kmalloc_array(num_bh, sizeof(*es->bh), GFP_NOFS); ++ if (!es->bh) { ++ brelse(bh); ++ kfree(es); ++ return NULL; ++ } ++ es->bh[0] = bh; ++ } ++ + for (i = 1; i < num_bh; i++) { + /* get the next sector */ + if (exfat_is_last_sector_in_cluster(sbi, sec)) { +diff --git a/fs/exfat/exfat_fs.h b/fs/exfat/exfat_fs.h +index e0af6ace633cb5..c79c78bf265bae 100644 +--- a/fs/exfat/exfat_fs.h ++++ b/fs/exfat/exfat_fs.h +@@ -169,10 +169,13 @@ struct exfat_entry_set_cache { + bool modified; + unsigned int start_off; + int num_bh; +- struct buffer_head *bh[DIR_CACHE_SIZE]; ++ struct buffer_head *__bh[DIR_CACHE_SIZE]; ++ struct buffer_head **bh; + unsigned int num_entries; + }; + ++#define IS_DYNAMIC_ES(es) ((es)->__bh != (es)->bh) ++ + struct exfat_dir_entry { + struct exfat_chain dir; + int entry; +diff --git a/fs/smb/client/connect.c b/fs/smb/client/connect.c +index 87ce71b39b7711..db30c4b8a22114 100644 +--- a/fs/smb/client/connect.c ++++ b/fs/smb/client/connect.c +@@ -259,7 +259,13 @@ cifs_mark_tcp_ses_conns_for_reconnect(struct TCP_Server_Info *server, + + spin_lock(&cifs_tcp_ses_lock); + list_for_each_entry_safe(ses, nses, &pserver->smb_ses_list, smb_ses_list) { +- /* check if iface is still active */ ++ spin_lock(&ses->ses_lock); ++ if (ses->ses_status == SES_EXITING) { ++ spin_unlock(&ses->ses_lock); ++ continue; ++ } ++ spin_unlock(&ses->ses_lock); ++ + spin_lock(&ses->chan_lock); + if (!cifs_chan_is_iface_active(ses, server)) { + spin_unlock(&ses->chan_lock); +@@ -1977,31 +1983,6 @@ cifs_setup_ipc(struct cifs_ses *ses, struct smb3_fs_context *ctx) + return rc; + } + +-/** +- * cifs_free_ipc - helper to release the session IPC tcon +- * @ses: smb session to unmount the IPC from +- * +- * Needs to be called everytime a session is destroyed. +- * +- * On session close, the IPC is closed and the server must release all tcons of the session. +- * No need to send a tree disconnect here. +- * +- * Besides, it will make the server to not close durable and resilient files on session close, as +- * specified in MS-SMB2 3.3.5.6 Receiving an SMB2 LOGOFF Request. +- */ +-static int +-cifs_free_ipc(struct cifs_ses *ses) +-{ +- struct cifs_tcon *tcon = ses->tcon_ipc; +- +- if (tcon == NULL) +- return 0; +- +- tconInfoFree(tcon); +- ses->tcon_ipc = NULL; +- return 0; +-} +- + static struct cifs_ses * + cifs_find_smb_ses(struct TCP_Server_Info *server, struct smb3_fs_context *ctx) + { +@@ -2035,35 +2016,44 @@ void cifs_put_smb_ses(struct cifs_ses *ses) + { + unsigned int rc, xid; + unsigned int chan_count; ++ bool do_logoff; ++ struct cifs_tcon *tcon; + struct TCP_Server_Info *server = ses->server; + ++ spin_lock(&cifs_tcp_ses_lock); + spin_lock(&ses->ses_lock); +- if (ses->ses_status == SES_EXITING) { ++ cifs_dbg(FYI, "%s: id=0x%llx ses_count=%d ses_status=%u ipc=%s\n", ++ __func__, ses->Suid, ses->ses_count, ses->ses_status, ++ ses->tcon_ipc ? ses->tcon_ipc->tree_name : "none"); ++ if (ses->ses_status == SES_EXITING || --ses->ses_count > 0) { + spin_unlock(&ses->ses_lock); +- return; +- } +- spin_unlock(&ses->ses_lock); +- +- cifs_dbg(FYI, "%s: ses_count=%d\n", __func__, ses->ses_count); +- cifs_dbg(FYI, +- "%s: ses ipc: %s\n", __func__, ses->tcon_ipc ? ses->tcon_ipc->tree_name : "NONE"); +- +- spin_lock(&cifs_tcp_ses_lock); +- if (--ses->ses_count > 0) { + spin_unlock(&cifs_tcp_ses_lock); + return; + } +- spin_unlock(&cifs_tcp_ses_lock); +- + /* ses_count can never go negative */ + WARN_ON(ses->ses_count < 0); + +- if (ses->ses_status == SES_GOOD) +- ses->ses_status = SES_EXITING; ++ spin_lock(&ses->chan_lock); ++ cifs_chan_clear_need_reconnect(ses, server); ++ spin_unlock(&ses->chan_lock); + +- cifs_free_ipc(ses); ++ do_logoff = ses->ses_status == SES_GOOD && server->ops->logoff; ++ ses->ses_status = SES_EXITING; ++ tcon = ses->tcon_ipc; ++ ses->tcon_ipc = NULL; ++ spin_unlock(&ses->ses_lock); ++ spin_unlock(&cifs_tcp_ses_lock); + +- if (ses->ses_status == SES_EXITING && server->ops->logoff) { ++ /* ++ * On session close, the IPC is closed and the server must release all ++ * tcons of the session. No need to send a tree disconnect here. ++ * ++ * Besides, it will make the server to not close durable and resilient ++ * files on session close, as specified in MS-SMB2 3.3.5.6 Receiving an ++ * SMB2 LOGOFF Request. ++ */ ++ tconInfoFree(tcon); ++ if (do_logoff) { + xid = get_xid(); + rc = server->ops->logoff(xid, ses); + if (rc) +diff --git a/fs/smb/server/auth.c b/fs/smb/server/auth.c +index 229a6527870d0e..8e24a6665abdb5 100644 +--- a/fs/smb/server/auth.c ++++ b/fs/smb/server/auth.c +@@ -1010,6 +1010,8 @@ static int ksmbd_get_encryption_key(struct ksmbd_work *work, __u64 ses_id, + + ses_enc_key = enc ? sess->smb3encryptionkey : + sess->smb3decryptionkey; ++ if (enc) ++ ksmbd_user_session_get(sess); + memcpy(key, ses_enc_key, SMB3_ENC_DEC_KEY_SIZE); + + return 0; +diff --git a/fs/smb/server/mgmt/user_session.c b/fs/smb/server/mgmt/user_session.c +index 710ac7b976fa87..b1c2219ec0b42a 100644 +--- a/fs/smb/server/mgmt/user_session.c ++++ b/fs/smb/server/mgmt/user_session.c +@@ -262,8 +262,10 @@ struct ksmbd_session *ksmbd_session_lookup(struct ksmbd_conn *conn, + + down_read(&conn->session_lock); + sess = xa_load(&conn->sessions, id); +- if (sess) ++ if (sess) { + sess->last_active = jiffies; ++ ksmbd_user_session_get(sess); ++ } + up_read(&conn->session_lock); + return sess; + } +@@ -274,6 +276,8 @@ struct ksmbd_session *ksmbd_session_lookup_slowpath(unsigned long long id) + + down_read(&sessions_table_lock); + sess = __session_lookup(id); ++ if (sess) ++ ksmbd_user_session_get(sess); + up_read(&sessions_table_lock); + + return sess; +diff --git a/fs/smb/server/server.c b/fs/smb/server/server.c +index da5b9678ad05a0..27d8d6c6fdacd9 100644 +--- a/fs/smb/server/server.c ++++ b/fs/smb/server/server.c +@@ -241,14 +241,14 @@ static void __handle_ksmbd_work(struct ksmbd_work *work, + if (work->tcon) + ksmbd_tree_connect_put(work->tcon); + smb3_preauth_hash_rsp(work); +- if (work->sess) +- ksmbd_user_session_put(work->sess); + if (work->sess && work->sess->enc && work->encrypted && + conn->ops->encrypt_resp) { + rc = conn->ops->encrypt_resp(work); + if (rc < 0) + conn->ops->set_rsp_status(work, STATUS_DATA_ERROR); + } ++ if (work->sess) ++ ksmbd_user_session_put(work->sess); + + ksmbd_conn_write(work); + } +diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c +index cb775646962174..96d441ca511d46 100644 +--- a/fs/smb/server/smb2pdu.c ++++ b/fs/smb/server/smb2pdu.c +@@ -66,8 +66,10 @@ static inline bool check_session_id(struct ksmbd_conn *conn, u64 id) + return false; + + sess = ksmbd_session_lookup_all(conn, id); +- if (sess) ++ if (sess) { ++ ksmbd_user_session_put(sess); + return true; ++ } + pr_err("Invalid user session id: %llu\n", id); + return false; + } +@@ -604,10 +606,8 @@ int smb2_check_user_session(struct ksmbd_work *work) + + /* Check for validity of user session */ + work->sess = ksmbd_session_lookup_all(conn, sess_id); +- if (work->sess) { +- ksmbd_user_session_get(work->sess); ++ if (work->sess) + return 1; +- } + ksmbd_debug(SMB, "Invalid user session, Uid %llu\n", sess_id); + return -ENOENT; + } +@@ -1720,29 +1720,35 @@ int smb2_sess_setup(struct ksmbd_work *work) + + if (conn->dialect != sess->dialect) { + rc = -EINVAL; ++ ksmbd_user_session_put(sess); + goto out_err; + } + + if (!(req->hdr.Flags & SMB2_FLAGS_SIGNED)) { + rc = -EINVAL; ++ ksmbd_user_session_put(sess); + goto out_err; + } + + if (strncmp(conn->ClientGUID, sess->ClientGUID, + SMB2_CLIENT_GUID_SIZE)) { + rc = -ENOENT; ++ ksmbd_user_session_put(sess); + goto out_err; + } + + if (sess->state == SMB2_SESSION_IN_PROGRESS) { + rc = -EACCES; ++ ksmbd_user_session_put(sess); + goto out_err; + } + + if (sess->state == SMB2_SESSION_EXPIRED) { + rc = -EFAULT; ++ ksmbd_user_session_put(sess); + goto out_err; + } ++ ksmbd_user_session_put(sess); + + if (ksmbd_conn_need_reconnect(conn)) { + rc = -EFAULT; +@@ -1750,7 +1756,8 @@ int smb2_sess_setup(struct ksmbd_work *work) + goto out_err; + } + +- if (ksmbd_session_lookup(conn, sess_id)) { ++ sess = ksmbd_session_lookup(conn, sess_id); ++ if (!sess) { + rc = -EACCES; + goto out_err; + } +@@ -1761,7 +1768,6 @@ int smb2_sess_setup(struct ksmbd_work *work) + } + + conn->binding = true; +- ksmbd_user_session_get(sess); + } else if ((conn->dialect < SMB30_PROT_ID || + server_conf.flags & KSMBD_GLOBAL_FLAG_SMB3_MULTICHANNEL) && + (req->Flags & SMB2_SESSION_REQ_FLAG_BINDING)) { +@@ -1788,7 +1794,6 @@ int smb2_sess_setup(struct ksmbd_work *work) + } + + conn->binding = false; +- ksmbd_user_session_get(sess); + } + work->sess = sess; + +@@ -2207,9 +2212,9 @@ int smb2_tree_disconnect(struct ksmbd_work *work) + int smb2_session_logoff(struct ksmbd_work *work) + { + struct ksmbd_conn *conn = work->conn; ++ struct ksmbd_session *sess = work->sess; + struct smb2_logoff_req *req; + struct smb2_logoff_rsp *rsp; +- struct ksmbd_session *sess; + u64 sess_id; + int err; + +@@ -2231,11 +2236,6 @@ int smb2_session_logoff(struct ksmbd_work *work) + ksmbd_close_session_fds(work); + ksmbd_conn_wait_idle(conn, sess_id); + +- /* +- * Re-lookup session to validate if session is deleted +- * while waiting request complete +- */ +- sess = ksmbd_session_lookup_all(conn, sess_id); + if (ksmbd_tree_conn_session_logoff(sess)) { + ksmbd_debug(SMB, "Invalid tid %d\n", req->hdr.Id.SyncId.TreeId); + rsp->hdr.Status = STATUS_NETWORK_NAME_DELETED; +@@ -8682,6 +8682,7 @@ int smb3_decrypt_req(struct ksmbd_work *work) + le64_to_cpu(tr_hdr->SessionId)); + return -ECONNABORTED; + } ++ ksmbd_user_session_put(sess); + + iov[0].iov_base = buf; + iov[0].iov_len = sizeof(struct smb2_transform_hdr) + 4; +diff --git a/fs/xfs/libxfs/xfs_btree.c b/fs/xfs/libxfs/xfs_btree.c +index 6b084b3cac83eb..f5c3be85b13562 100644 +--- a/fs/xfs/libxfs/xfs_btree.c ++++ b/fs/xfs/libxfs/xfs_btree.c +@@ -3430,14 +3430,31 @@ xfs_btree_insrec( + xfs_btree_log_block(cur, bp, XFS_BB_NUMRECS); + + /* +- * If we just inserted into a new tree block, we have to +- * recalculate nkey here because nkey is out of date. ++ * Update btree keys to reflect the newly added record or keyptr. ++ * There are three cases here to be aware of. Normally, all we have to ++ * do is walk towards the root, updating keys as necessary. + * +- * Otherwise we're just updating an existing block (having shoved +- * some records into the new tree block), so use the regular key +- * update mechanism. ++ * If the caller had us target a full block for the insertion, we dealt ++ * with that by calling the _make_block_unfull function. If the ++ * "make unfull" function splits the block, it'll hand us back the key ++ * and pointer of the new block. We haven't yet added the new block to ++ * the next level up, so if we decide to add the new record to the new ++ * block (bp->b_bn != old_bn), we have to update the caller's pointer ++ * so that the caller adds the new block with the correct key. ++ * ++ * However, there is a third possibility-- if the selected block is the ++ * root block of an inode-rooted btree and cannot be expanded further, ++ * the "make unfull" function moves the root block contents to a new ++ * block and updates the root block to point to the new block. In this ++ * case, no block pointer is passed back because the block has already ++ * been added to the btree. In this case, we need to use the regular ++ * key update function, just like the first case. This is critical for ++ * overlapping btrees, because the high key must be updated to reflect ++ * the entire tree, not just the subtree accessible through the first ++ * child of the root (which is now two levels down from the root). + */ +- if (bp && xfs_buf_daddr(bp) != old_bn) { ++ if (!xfs_btree_ptr_is_null(cur, &nptr) && ++ bp && xfs_buf_daddr(bp) != old_bn) { + xfs_btree_get_keys(cur, block, lkey); + } else if (xfs_btree_needs_key_update(cur, optr)) { + error = xfs_btree_update_keys(cur, level); +diff --git a/fs/xfs/libxfs/xfs_symlink_remote.c b/fs/xfs/libxfs/xfs_symlink_remote.c +index bdc777b9ec4a6c..8828d854e34fa2 100644 +--- a/fs/xfs/libxfs/xfs_symlink_remote.c ++++ b/fs/xfs/libxfs/xfs_symlink_remote.c +@@ -89,8 +89,10 @@ xfs_symlink_verify( + struct xfs_mount *mp = bp->b_mount; + struct xfs_dsymlink_hdr *dsl = bp->b_addr; + ++ /* no verification of non-crc buffers */ + if (!xfs_has_crc(mp)) +- return __this_address; ++ return NULL; ++ + if (!xfs_verify_magic(bp, dsl->sl_magic)) + return __this_address; + if (!uuid_equal(&dsl->sl_uuid, &mp->m_sb.sb_meta_uuid)) +diff --git a/fs/xfs/scrub/trace.h b/fs/xfs/scrub/trace.h +index 93ece6df02e333..0afc978e998309 100644 +--- a/fs/xfs/scrub/trace.h ++++ b/fs/xfs/scrub/trace.h +@@ -464,7 +464,7 @@ TRACE_EVENT(xchk_ifork_btree_error, + TP_fast_assign( + xfs_fsblock_t fsbno = xchk_btree_cur_fsbno(cur, level); + __entry->dev = sc->mp->m_super->s_dev; +- __entry->ino = sc->ip->i_ino; ++ __entry->ino = cur->bc_ino.ip->i_ino; + __entry->whichfork = cur->bc_ino.whichfork; + __entry->type = sc->sm->sm_type; + __entry->btnum = cur->bc_btnum; +diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c +index 595a5bcf46b949..8de40cf63a5bfd 100644 +--- a/fs/xfs/xfs_file.c ++++ b/fs/xfs/xfs_file.c +@@ -1161,6 +1161,14 @@ xfs_file_remap_range( + xfs_iunlock2_io_mmap(src, dest); + if (ret) + trace_xfs_reflink_remap_range_error(dest, ret, _RET_IP_); ++ /* ++ * If the caller did not set CAN_SHORTEN, then it is not prepared to ++ * handle partial results -- either the whole remap succeeds, or we ++ * must say why it did not. In this case, any error should be returned ++ * to the caller. ++ */ ++ if (ret && remapped < len && !(remap_flags & REMAP_FILE_CAN_SHORTEN)) ++ return ret; + return remapped > 0 ? remapped : ret; + } + +diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c +index b45879868f90fc..24233e0b57fd9b 100644 +--- a/fs/xfs/xfs_trans.c ++++ b/fs/xfs/xfs_trans.c +@@ -955,13 +955,6 @@ __xfs_trans_commit( + + trace_xfs_trans_commit(tp, _RET_IP_); + +- error = xfs_trans_run_precommits(tp); +- if (error) { +- if (tp->t_flags & XFS_TRANS_PERM_LOG_RES) +- xfs_defer_cancel(tp); +- goto out_unreserve; +- } +- + /* + * Finish deferred items on final commit. Only permanent transactions + * should ever have deferred ops. +@@ -972,13 +965,12 @@ __xfs_trans_commit( + error = xfs_defer_finish_noroll(&tp); + if (error) + goto out_unreserve; +- +- /* Run precommits from final tx in defer chain. */ +- error = xfs_trans_run_precommits(tp); +- if (error) +- goto out_unreserve; + } + ++ error = xfs_trans_run_precommits(tp); ++ if (error) ++ goto out_unreserve; ++ + /* + * If there is nothing to be logged by the transaction, + * then unlock all of the items associated with the +diff --git a/include/linux/compiler.h b/include/linux/compiler.h +index 973a1bfd7ef530..fdfe8e6ff0b2e7 100644 +--- a/include/linux/compiler.h ++++ b/include/linux/compiler.h +@@ -205,28 +205,43 @@ void ftrace_likely_update(struct ftrace_likely_data *f, int val, + + #endif /* __KERNEL__ */ + ++/** ++ * offset_to_ptr - convert a relative memory offset to an absolute pointer ++ * @off: the address of the 32-bit offset value ++ */ ++static inline void *offset_to_ptr(const int *off) ++{ ++ return (void *)((unsigned long)off + *off); ++} ++ ++#endif /* __ASSEMBLY__ */ ++ ++#ifdef CONFIG_64BIT ++#define ARCH_SEL(a,b) a ++#else ++#define ARCH_SEL(a,b) b ++#endif ++ + /* + * Force the compiler to emit 'sym' as a symbol, so that we can reference + * it from inline assembler. Necessary in case 'sym' could be inlined + * otherwise, or eliminated entirely due to lack of references that are + * visible to the compiler. + */ +-#define ___ADDRESSABLE(sym, __attrs) \ +- static void * __used __attrs \ ++#define ___ADDRESSABLE(sym, __attrs) \ ++ static void * __used __attrs \ + __UNIQUE_ID(__PASTE(__addressable_,sym)) = (void *)&sym; ++ + #define __ADDRESSABLE(sym) \ + ___ADDRESSABLE(sym, __section(".discard.addressable")) + +-/** +- * offset_to_ptr - convert a relative memory offset to an absolute pointer +- * @off: the address of the 32-bit offset value +- */ +-static inline void *offset_to_ptr(const int *off) +-{ +- return (void *)((unsigned long)off + *off); +-} ++#define __ADDRESSABLE_ASM(sym) \ ++ .pushsection .discard.addressable,"aw"; \ ++ .align ARCH_SEL(8,4); \ ++ ARCH_SEL(.quad, .long) __stringify(sym); \ ++ .popsection; + +-#endif /* __ASSEMBLY__ */ ++#define __ADDRESSABLE_ASM_STR(sym) __stringify(__ADDRESSABLE_ASM(sym)) + + /* &a[0] degrades to a pointer: a different type from an array */ + #define __must_be_array(a) BUILD_BUG_ON_ZERO(__same_type((a), &(a)[0])) +diff --git a/include/linux/dsa/ocelot.h b/include/linux/dsa/ocelot.h +index 6fbfbde68a37c3..620a3260fc0802 100644 +--- a/include/linux/dsa/ocelot.h ++++ b/include/linux/dsa/ocelot.h +@@ -15,6 +15,7 @@ + struct ocelot_skb_cb { + struct sk_buff *clone; + unsigned int ptp_class; /* valid only for clones */ ++ unsigned long ptp_tx_time; /* valid only for clones */ + u32 tstamp_lo; + u8 ptp_cmd; + u8 ts_id; +diff --git a/include/linux/ptp_kvm.h b/include/linux/ptp_kvm.h +index c2e28deef33a8d..746fd67c34806b 100644 +--- a/include/linux/ptp_kvm.h ++++ b/include/linux/ptp_kvm.h +@@ -14,6 +14,7 @@ struct timespec64; + struct clocksource; + + int kvm_arch_ptp_init(void); ++void kvm_arch_ptp_exit(void); + int kvm_arch_ptp_get_clock(struct timespec64 *ts); + int kvm_arch_ptp_get_crosststamp(u64 *cycle, + struct timespec64 *tspec, struct clocksource **cs); +diff --git a/include/linux/static_call.h b/include/linux/static_call.h +index df53bed9d71f1d..d73384f506035d 100644 +--- a/include/linux/static_call.h ++++ b/include/linux/static_call.h +@@ -160,6 +160,8 @@ extern void arch_static_call_transform(void *site, void *tramp, void *func, bool + + #ifdef CONFIG_HAVE_STATIC_CALL_INLINE + ++extern bool static_call_initialized; ++ + extern int __init static_call_init(void); + + struct static_call_mod { +@@ -223,6 +225,8 @@ extern long __static_call_return0(void); + + #elif defined(CONFIG_HAVE_STATIC_CALL) + ++#define static_call_initialized 0 ++ + static inline int static_call_init(void) { return 0; } + + #define DEFINE_STATIC_CALL(name, _func) \ +@@ -279,6 +283,8 @@ extern long __static_call_return0(void); + + #else /* Generic implementation */ + ++#define static_call_initialized 0 ++ + static inline int static_call_init(void) { return 0; } + + static inline long __static_call_return0(void) +diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h +index 41fc7f12971a55..5689b4744764fd 100644 +--- a/include/net/bluetooth/bluetooth.h ++++ b/include/net/bluetooth/bluetooth.h +@@ -122,6 +122,7 @@ struct bt_voice { + + #define BT_VOICE_TRANSPARENT 0x0003 + #define BT_VOICE_CVSD_16BIT 0x0060 ++#define BT_VOICE_TRANSPARENT_16BIT 0x0063 + + #define BT_SNDMTU 12 + #define BT_RCVMTU 13 +diff --git a/include/net/lapb.h b/include/net/lapb.h +index 124ee122f2c8f8..6c07420644e45a 100644 +--- a/include/net/lapb.h ++++ b/include/net/lapb.h +@@ -4,7 +4,7 @@ + #include <linux/lapb.h> + #include <linux/refcount.h> + +-#define LAPB_HEADER_LEN 20 /* LAPB over Ethernet + a bit more */ ++#define LAPB_HEADER_LEN MAX_HEADER /* LAPB over Ethernet + a bit more */ + + #define LAPB_ACK_PENDING_CONDITION 0x01 + #define LAPB_REJECT_CONDITION 0x02 +diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h +index 8c3587d5c308f0..7ca4b7af57ca6e 100644 +--- a/include/net/net_namespace.h ++++ b/include/net/net_namespace.h +@@ -81,6 +81,7 @@ struct net { + * or to unregister pernet ops + * (pernet_ops_rwsem write locked). + */ ++ struct llist_node defer_free_list; + struct llist_node cleanup_list; /* namespaces on death row */ + + #ifdef CONFIG_KEYS +diff --git a/include/soc/mscc/ocelot.h b/include/soc/mscc/ocelot.h +index 9b5562f545486c..99cfaa9347c9e1 100644 +--- a/include/soc/mscc/ocelot.h ++++ b/include/soc/mscc/ocelot.h +@@ -941,7 +941,6 @@ struct ocelot_port { + + phy_interface_t phy_mode; + +- unsigned int ptp_skbs_in_flight; + struct sk_buff_head tx_skbs; + + unsigned int trap_proto; +@@ -949,7 +948,6 @@ struct ocelot_port { + u16 mrp_ring_id; + + u8 ptp_cmd; +- u8 ts_id; + + u8 index; + +diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c +index b68572c41e9640..bdd5105337dc1a 100644 +--- a/kernel/bpf/verifier.c ++++ b/kernel/bpf/verifier.c +@@ -10350,8 +10350,11 @@ static void find_equal_scalars(struct bpf_verifier_state *vstate, + struct bpf_reg_state *reg; + + bpf_for_each_reg_in_vstate(vstate, state, reg, ({ +- if (reg->type == SCALAR_VALUE && reg->id == known_reg->id) ++ if (reg->type == SCALAR_VALUE && reg->id == known_reg->id) { ++ s32 saved_subreg_def = reg->subreg_def; + copy_register_state(reg, known_reg); ++ reg->subreg_def = saved_subreg_def; ++ } + })); + } + +diff --git a/kernel/static_call_inline.c b/kernel/static_call_inline.c +index 6f566fe27ec1d7..f0bd892ef15776 100644 +--- a/kernel/static_call_inline.c ++++ b/kernel/static_call_inline.c +@@ -15,7 +15,7 @@ extern struct static_call_site __start_static_call_sites[], + extern struct static_call_tramp_key __start_static_call_tramp_key[], + __stop_static_call_tramp_key[]; + +-static bool static_call_initialized; ++bool static_call_initialized; + + /* mutex to protect key modules/sites */ + static DEFINE_MUTEX(static_call_mutex); +diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c +index d8212fea1e99d9..e7b7be074e5a32 100644 +--- a/kernel/trace/bpf_trace.c ++++ b/kernel/trace/bpf_trace.c +@@ -2180,6 +2180,9 @@ void perf_event_detach_bpf_prog(struct perf_event *event) + goto unlock; + + old_array = bpf_event_rcu_dereference(event->tp_event->prog_array); ++ if (!old_array) ++ goto put; ++ + ret = bpf_prog_array_copy(old_array, event->prog, NULL, 0, &new_array); + if (ret < 0) { + bpf_prog_array_delete_safe(old_array, event->prog); +@@ -2188,6 +2191,14 @@ void perf_event_detach_bpf_prog(struct perf_event *event) + bpf_prog_array_free_sleepable(old_array); + } + ++put: ++ /* ++ * It could be that the bpf_prog is not sleepable (and will be freed ++ * via normal RCU), but is called from a point that supports sleepable ++ * programs and uses tasks-trace-RCU. ++ */ ++ synchronize_rcu_tasks_trace(); ++ + bpf_prog_put(event->prog); + event->prog = NULL; + +diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c +index e3993d19687dbf..8657c9b1448ea0 100644 +--- a/kernel/trace/trace_kprobe.c ++++ b/kernel/trace/trace_kprobe.c +@@ -1816,7 +1816,7 @@ create_local_trace_kprobe(char *func, void *addr, unsigned long offs, + int ret; + char *event; + +- if (func) { ++ if (func && !strchr(func, ':')) { + unsigned int count; + + count = number_of_same_symbols(func); +diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c +index 4fc66cd95dc471..2b5453801bf0da 100644 +--- a/net/batman-adv/translation-table.c ++++ b/net/batman-adv/translation-table.c +@@ -990,16 +990,25 @@ static void batadv_tt_tvlv_container_update(struct batadv_priv *bat_priv) + int tt_diff_len, tt_change_len = 0; + int tt_diff_entries_num = 0; + int tt_diff_entries_count = 0; ++ bool drop_changes = false; ++ size_t tt_extra_len = 0; + u16 tvlv_len; + + tt_diff_entries_num = atomic_read(&bat_priv->tt.local_changes); + tt_diff_len = batadv_tt_len(tt_diff_entries_num); + + /* if we have too many changes for one packet don't send any +- * and wait for the tt table request which will be fragmented ++ * and wait for the tt table request so we can reply with the full ++ * (fragmented) table. ++ * ++ * The local change history should still be cleaned up so the next ++ * TT round can start again with a clean state. + */ +- if (tt_diff_len > bat_priv->soft_iface->mtu) ++ if (tt_diff_len > bat_priv->soft_iface->mtu) { + tt_diff_len = 0; ++ tt_diff_entries_num = 0; ++ drop_changes = true; ++ } + + tvlv_len = batadv_tt_prepare_tvlv_local_data(bat_priv, &tt_data, + &tt_change, &tt_diff_len); +@@ -1008,7 +1017,7 @@ static void batadv_tt_tvlv_container_update(struct batadv_priv *bat_priv) + + tt_data->flags = BATADV_TT_OGM_DIFF; + +- if (tt_diff_len == 0) ++ if (!drop_changes && tt_diff_len == 0) + goto container_register; + + spin_lock_bh(&bat_priv->tt.changes_list_lock); +@@ -1027,6 +1036,9 @@ static void batadv_tt_tvlv_container_update(struct batadv_priv *bat_priv) + } + spin_unlock_bh(&bat_priv->tt.changes_list_lock); + ++ tt_extra_len = batadv_tt_len(tt_diff_entries_num - ++ tt_diff_entries_count); ++ + /* Keep the buffer for possible tt_request */ + spin_lock_bh(&bat_priv->tt.last_changeset_lock); + kfree(bat_priv->tt.last_changeset); +@@ -1035,6 +1047,7 @@ static void batadv_tt_tvlv_container_update(struct batadv_priv *bat_priv) + tt_change_len = batadv_tt_len(tt_diff_entries_count); + /* check whether this new OGM has no changes due to size problems */ + if (tt_diff_entries_count > 0) { ++ tt_diff_len -= tt_extra_len; + /* if kmalloc() fails we will reply with the full table + * instead of providing the diff + */ +@@ -1047,6 +1060,8 @@ static void batadv_tt_tvlv_container_update(struct batadv_priv *bat_priv) + } + spin_unlock_bh(&bat_priv->tt.last_changeset_lock); + ++ /* Remove extra packet space for OGM */ ++ tvlv_len -= tt_extra_len; + container_register: + batadv_tvlv_container_register(bat_priv, BATADV_TVLV_TT, 1, tt_data, + tvlv_len); +@@ -2747,14 +2762,16 @@ static bool batadv_tt_global_valid(const void *entry_ptr, + * + * Fills the tvlv buff with the tt entries from the specified hash. If valid_cb + * is not provided then this becomes a no-op. ++ * ++ * Return: Remaining unused length in tvlv_buff. + */ +-static void batadv_tt_tvlv_generate(struct batadv_priv *bat_priv, +- struct batadv_hashtable *hash, +- void *tvlv_buff, u16 tt_len, +- bool (*valid_cb)(const void *, +- const void *, +- u8 *flags), +- void *cb_data) ++static u16 batadv_tt_tvlv_generate(struct batadv_priv *bat_priv, ++ struct batadv_hashtable *hash, ++ void *tvlv_buff, u16 tt_len, ++ bool (*valid_cb)(const void *, ++ const void *, ++ u8 *flags), ++ void *cb_data) + { + struct batadv_tt_common_entry *tt_common_entry; + struct batadv_tvlv_tt_change *tt_change; +@@ -2768,7 +2785,7 @@ static void batadv_tt_tvlv_generate(struct batadv_priv *bat_priv, + tt_change = tvlv_buff; + + if (!valid_cb) +- return; ++ return tt_len; + + rcu_read_lock(); + for (i = 0; i < hash->size; i++) { +@@ -2794,6 +2811,8 @@ static void batadv_tt_tvlv_generate(struct batadv_priv *bat_priv, + } + } + rcu_read_unlock(); ++ ++ return batadv_tt_len(tt_tot - tt_num_entries); + } + + /** +@@ -3069,10 +3088,11 @@ static bool batadv_send_other_tt_response(struct batadv_priv *bat_priv, + goto out; + + /* fill the rest of the tvlv with the real TT entries */ +- batadv_tt_tvlv_generate(bat_priv, bat_priv->tt.global_hash, +- tt_change, tt_len, +- batadv_tt_global_valid, +- req_dst_orig_node); ++ tvlv_len -= batadv_tt_tvlv_generate(bat_priv, ++ bat_priv->tt.global_hash, ++ tt_change, tt_len, ++ batadv_tt_global_valid, ++ req_dst_orig_node); + } + + /* Don't send the response, if larger than fragmented packet. */ +@@ -3196,9 +3216,11 @@ static bool batadv_send_my_tt_response(struct batadv_priv *bat_priv, + goto out; + + /* fill the rest of the tvlv with the real TT entries */ +- batadv_tt_tvlv_generate(bat_priv, bat_priv->tt.local_hash, +- tt_change, tt_len, +- batadv_tt_local_valid, NULL); ++ tvlv_len -= batadv_tt_tvlv_generate(bat_priv, ++ bat_priv->tt.local_hash, ++ tt_change, tt_len, ++ batadv_tt_local_valid, ++ NULL); + } + + tvlv_tt_data->flags = BATADV_TT_RESPONSE; +diff --git a/net/bluetooth/iso.c b/net/bluetooth/iso.c +index ff15d5192768ab..437cbeaa96193c 100644 +--- a/net/bluetooth/iso.c ++++ b/net/bluetooth/iso.c +@@ -964,7 +964,11 @@ static int iso_sock_accept(struct socket *sock, struct socket *newsock, + long timeo; + int err = 0; + +- lock_sock(sk); ++ /* Use explicit nested locking to avoid lockdep warnings generated ++ * because the parent socket and the child socket are locked on the ++ * same thread. ++ */ ++ lock_sock_nested(sk, SINGLE_DEPTH_NESTING); + + timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK); + +@@ -995,7 +999,7 @@ static int iso_sock_accept(struct socket *sock, struct socket *newsock, + release_sock(sk); + + timeo = wait_woken(&wait, TASK_INTERRUPTIBLE, timeo); +- lock_sock(sk); ++ lock_sock_nested(sk, SINGLE_DEPTH_NESTING); + } + remove_wait_queue(sk_sleep(sk), &wait); + +diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c +index ad5afde17213a2..fe8728041ad085 100644 +--- a/net/bluetooth/sco.c ++++ b/net/bluetooth/sco.c +@@ -268,10 +268,13 @@ static int sco_connect(struct sock *sk) + else + type = SCO_LINK; + +- if (sco_pi(sk)->setting == BT_VOICE_TRANSPARENT && +- (!lmp_transp_capable(hdev) || !lmp_esco_capable(hdev))) { +- err = -EOPNOTSUPP; +- goto unlock; ++ switch (sco_pi(sk)->setting & SCO_AIRMODE_MASK) { ++ case SCO_AIRMODE_TRANSP: ++ if (!lmp_transp_capable(hdev) || !lmp_esco_capable(hdev)) { ++ err = -EOPNOTSUPP; ++ goto unlock; ++ } ++ break; + } + + hcon = hci_connect_sco(hdev, type, &sco_pi(sk)->dst, +@@ -888,13 +891,6 @@ static int sco_sock_setsockopt(struct socket *sock, int level, int optname, + if (err) + break; + +- /* Explicitly check for these values */ +- if (voice.setting != BT_VOICE_TRANSPARENT && +- voice.setting != BT_VOICE_CVSD_16BIT) { +- err = -EINVAL; +- break; +- } +- + sco_pi(sk)->setting = voice.setting; + hdev = hci_get_route(&sco_pi(sk)->dst, &sco_pi(sk)->src, + BDADDR_BREDR); +@@ -902,9 +898,14 @@ static int sco_sock_setsockopt(struct socket *sock, int level, int optname, + err = -EBADFD; + break; + } +- if (enhanced_sync_conn_capable(hdev) && +- voice.setting == BT_VOICE_TRANSPARENT) +- sco_pi(sk)->codec.id = BT_CODEC_TRANSPARENT; ++ ++ switch (sco_pi(sk)->setting & SCO_AIRMODE_MASK) { ++ case SCO_AIRMODE_TRANSP: ++ if (enhanced_sync_conn_capable(hdev)) ++ sco_pi(sk)->codec.id = BT_CODEC_TRANSPARENT; ++ break; ++ } ++ + hci_dev_put(hdev); + break; + +diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c +index 1d95a5adce4ec4..6c6d2a785c0049 100644 +--- a/net/core/net_namespace.c ++++ b/net/core/net_namespace.c +@@ -435,11 +435,28 @@ static struct net *net_alloc(void) + goto out; + } + ++static LLIST_HEAD(defer_free_list); ++ ++static void net_complete_free(void) ++{ ++ struct llist_node *kill_list; ++ struct net *net, *next; ++ ++ /* Get the list of namespaces to free from last round. */ ++ kill_list = llist_del_all(&defer_free_list); ++ ++ llist_for_each_entry_safe(net, next, kill_list, defer_free_list) ++ kmem_cache_free(net_cachep, net); ++ ++} ++ + static void net_free(struct net *net) + { + if (refcount_dec_and_test(&net->passive)) { + kfree(rcu_access_pointer(net->gen)); +- kmem_cache_free(net_cachep, net); ++ ++ /* Wait for an extra rcu_barrier() before final free. */ ++ llist_add(&net->defer_free_list, &defer_free_list); + } + } + +@@ -614,6 +631,8 @@ static void cleanup_net(struct work_struct *work) + */ + rcu_barrier(); + ++ net_complete_free(); ++ + /* Finally it is safe to free my network namespace structure */ + list_for_each_entry_safe(net, tmp, &net_exit_list, exit_list) { + list_del_init(&net->exit_list); +diff --git a/net/core/sock_map.c b/net/core/sock_map.c +index 25b5abab60ed04..e674a686ff7100 100644 +--- a/net/core/sock_map.c ++++ b/net/core/sock_map.c +@@ -158,6 +158,7 @@ static void sock_map_del_link(struct sock *sk, + verdict_stop = true; + list_del(&link->list); + sk_psock_free_link(link); ++ break; + } + } + spin_unlock_bh(&psock->link_lock); +diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c +index 3f54b76bc28111..40568365cdb3b8 100644 +--- a/net/ipv4/tcp_output.c ++++ b/net/ipv4/tcp_output.c +@@ -827,8 +827,10 @@ static unsigned int tcp_syn_options(struct sock *sk, struct sk_buff *skb, + unsigned int size; + + if (mptcp_syn_options(sk, skb, &size, &opts->mptcp)) { +- opts->options |= OPTION_MPTCP; +- remaining -= size; ++ if (remaining >= size) { ++ opts->options |= OPTION_MPTCP; ++ remaining -= size; ++ } + } + } + +diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c +index c0dccaceb05e6e..be48d3f7ffcd61 100644 +--- a/net/mac80211/cfg.c ++++ b/net/mac80211/cfg.c +@@ -1683,7 +1683,6 @@ static int sta_link_apply_parameters(struct ieee80211_local *local, + struct sta_info *sta, bool new_link, + struct link_station_parameters *params) + { +- int ret = 0; + struct ieee80211_supported_band *sband; + struct ieee80211_sub_if_data *sdata = sta->sdata; + u32 link_id = params->link_id < 0 ? 0 : params->link_id; +@@ -1725,6 +1724,8 @@ static int sta_link_apply_parameters(struct ieee80211_local *local, + } + + if (params->txpwr_set) { ++ int ret; ++ + link_sta->pub->txpwr.type = params->txpwr.type; + if (params->txpwr.type == NL80211_TX_POWER_LIMITED) + link_sta->pub->txpwr.power = params->txpwr.power; +@@ -1766,6 +1767,8 @@ static int sta_link_apply_parameters(struct ieee80211_local *local, + params->eht_capa_len, + link_sta); + ++ ieee80211_sta_init_nss(link_sta); ++ + if (params->opmode_notif_used) { + /* returned value is only needed for rc update, but the + * rc isn't initialized here yet, so ignore it +@@ -1775,9 +1778,7 @@ static int sta_link_apply_parameters(struct ieee80211_local *local, + sband->band); + } + +- ieee80211_sta_init_nss(link_sta); +- +- return ret; ++ return 0; + } + + static int sta_apply_parameters(struct ieee80211_local *local, +diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c +index 0eba06613dcdef..f47ab622399f31 100644 +--- a/net/sched/sch_netem.c ++++ b/net/sched/sch_netem.c +@@ -77,6 +77,8 @@ struct netem_sched_data { + struct sk_buff *t_head; + struct sk_buff *t_tail; + ++ u32 t_len; ++ + /* optional qdisc for classful handling (NULL at netem init) */ + struct Qdisc *qdisc; + +@@ -373,6 +375,7 @@ static void tfifo_reset(struct Qdisc *sch) + rtnl_kfree_skbs(q->t_head, q->t_tail); + q->t_head = NULL; + q->t_tail = NULL; ++ q->t_len = 0; + } + + static void tfifo_enqueue(struct sk_buff *nskb, struct Qdisc *sch) +@@ -402,6 +405,7 @@ static void tfifo_enqueue(struct sk_buff *nskb, struct Qdisc *sch) + rb_link_node(&nskb->rbnode, parent, p); + rb_insert_color(&nskb->rbnode, &q->t_root); + } ++ q->t_len++; + sch->q.qlen++; + } + +@@ -508,7 +512,7 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch, + 1<<prandom_u32_max(8); + } + +- if (unlikely(sch->q.qlen >= sch->limit)) { ++ if (unlikely(q->t_len >= sch->limit)) { + /* re-link segs, so that qdisc_drop_all() frees them all */ + skb->next = segs; + qdisc_drop_all(skb, sch, to_free); +@@ -692,8 +696,8 @@ static struct sk_buff *netem_dequeue(struct Qdisc *sch) + tfifo_dequeue: + skb = __qdisc_dequeue_head(&sch->q); + if (skb) { +- qdisc_qstats_backlog_dec(sch, skb); + deliver: ++ qdisc_qstats_backlog_dec(sch, skb); + qdisc_bstats_update(sch, skb); + return skb; + } +@@ -709,8 +713,7 @@ static struct sk_buff *netem_dequeue(struct Qdisc *sch) + + if (time_to_send <= now && q->slot.slot_next <= now) { + netem_erase_head(q, skb); +- sch->q.qlen--; +- qdisc_qstats_backlog_dec(sch, skb); ++ q->t_len--; + skb->next = NULL; + skb->prev = NULL; + /* skb->dev shares skb->rbnode area, +@@ -737,16 +740,21 @@ static struct sk_buff *netem_dequeue(struct Qdisc *sch) + if (net_xmit_drop_count(err)) + qdisc_qstats_drop(sch); + qdisc_tree_reduce_backlog(sch, 1, pkt_len); ++ sch->qstats.backlog -= pkt_len; ++ sch->q.qlen--; + } + goto tfifo_dequeue; + } ++ sch->q.qlen--; + goto deliver; + } + + if (q->qdisc) { + skb = q->qdisc->ops->dequeue(q->qdisc); +- if (skb) ++ if (skb) { ++ sch->q.qlen--; + goto deliver; ++ } + } + + qdisc_watchdog_schedule_ns(&q->watchdog, +@@ -756,8 +764,10 @@ static struct sk_buff *netem_dequeue(struct Qdisc *sch) + + if (q->qdisc) { + skb = q->qdisc->ops->dequeue(q->qdisc); +- if (skb) ++ if (skb) { ++ sch->q.qlen--; + goto deliver; ++ } + } + return NULL; + } +diff --git a/net/tipc/udp_media.c b/net/tipc/udp_media.c +index 3f5a12b85b2d3e..f5bd75d931c1b5 100644 +--- a/net/tipc/udp_media.c ++++ b/net/tipc/udp_media.c +@@ -811,6 +811,7 @@ static void cleanup_bearer(struct work_struct *work) + { + struct udp_bearer *ub = container_of(work, struct udp_bearer, work); + struct udp_replicast *rcast, *tmp; ++ struct tipc_net *tn; + + list_for_each_entry_safe(rcast, tmp, &ub->rcast.list, list) { + dst_cache_destroy(&rcast->dst_cache); +@@ -818,10 +819,14 @@ static void cleanup_bearer(struct work_struct *work) + kfree_rcu(rcast, rcu); + } + ++ tn = tipc_net(sock_net(ub->ubsock->sk)); ++ + dst_cache_destroy(&ub->rcast.dst_cache); + udp_tunnel_sock_release(ub->ubsock); ++ ++ /* Note: could use a call_rcu() to avoid another synchronize_net() */ + synchronize_net(); +- atomic_dec(&tipc_net(sock_net(ub->ubsock->sk))->wq_count); ++ atomic_dec(&tn->wq_count); + kfree(ub); + } + +diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c +index 3e1c4e23484dce..0ba824c3fd1b70 100644 +--- a/net/wireless/nl80211.c ++++ b/net/wireless/nl80211.c +@@ -806,7 +806,7 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = { + [NL80211_ATTR_MLO_LINKS] = + NLA_POLICY_NESTED_ARRAY(nl80211_policy), + [NL80211_ATTR_MLO_LINK_ID] = +- NLA_POLICY_RANGE(NLA_U8, 0, IEEE80211_MLD_MAX_NUM_LINKS), ++ NLA_POLICY_RANGE(NLA_U8, 0, IEEE80211_MLD_MAX_NUM_LINKS - 1), + [NL80211_ATTR_MLD_ADDR] = NLA_POLICY_EXACT_LEN(ETH_ALEN), + [NL80211_ATTR_MLO_SUPPORT] = { .type = NLA_FLAG }, + [NL80211_ATTR_MAX_NUM_AKM_SUITES] = { .type = NLA_REJECT }, +diff --git a/sound/soc/amd/yc/acp6x-mach.c b/sound/soc/amd/yc/acp6x-mach.c +index af9601bea275ef..9c1bf0eb2debd1 100644 +--- a/sound/soc/amd/yc/acp6x-mach.c ++++ b/sound/soc/amd/yc/acp6x-mach.c +@@ -473,14 +473,19 @@ static int acp6x_probe(struct platform_device *pdev) + + handle = ACPI_HANDLE(pdev->dev.parent); + ret = acpi_evaluate_integer(handle, "_WOV", NULL, &dmic_status); +- if (!ACPI_FAILURE(ret)) ++ if (!ACPI_FAILURE(ret)) { + wov_en = dmic_status; ++ if (!wov_en) ++ return -ENODEV; ++ } else { ++ /* Incase of ACPI method read failure then jump to check_dmi_entry */ ++ goto check_dmi_entry; ++ } + +- if (is_dmic_enable && wov_en) ++ if (is_dmic_enable) + platform_set_drvdata(pdev, &acp6x_card); +- else +- return 0; + ++check_dmi_entry: + /* check for any DMI overrides */ + dmi_id = dmi_first_match(yc_acp_quirk_table); + if (dmi_id) +diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c +index ecb49ba8432c28..673591fbf917d1 100644 +--- a/sound/usb/quirks.c ++++ b/sound/usb/quirks.c +@@ -553,7 +553,7 @@ int snd_usb_create_quirk(struct snd_usb_audio *chip, + static int snd_usb_extigy_boot_quirk(struct usb_device *dev, struct usb_interface *intf) + { + struct usb_host_config *config = dev->actconfig; +- struct usb_device_descriptor new_device_descriptor; ++ struct usb_device_descriptor *new_device_descriptor __free(kfree) = NULL; + int err; + + if (le16_to_cpu(get_cfg_desc(config)->wTotalLength) == EXTIGY_FIRMWARE_SIZE_OLD || +@@ -564,15 +564,19 @@ static int snd_usb_extigy_boot_quirk(struct usb_device *dev, struct usb_interfac + 0x10, 0x43, 0x0001, 0x000a, NULL, 0); + if (err < 0) + dev_dbg(&dev->dev, "error sending boot message: %d\n", err); ++ ++ new_device_descriptor = kmalloc(sizeof(*new_device_descriptor), GFP_KERNEL); ++ if (!new_device_descriptor) ++ return -ENOMEM; + err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, +- &new_device_descriptor, sizeof(new_device_descriptor)); ++ new_device_descriptor, sizeof(*new_device_descriptor)); + if (err < 0) + dev_dbg(&dev->dev, "error usb_get_descriptor: %d\n", err); +- if (new_device_descriptor.bNumConfigurations > dev->descriptor.bNumConfigurations) ++ if (new_device_descriptor->bNumConfigurations > dev->descriptor.bNumConfigurations) + dev_dbg(&dev->dev, "error too large bNumConfigurations: %d\n", +- new_device_descriptor.bNumConfigurations); ++ new_device_descriptor->bNumConfigurations); + else +- memcpy(&dev->descriptor, &new_device_descriptor, sizeof(dev->descriptor)); ++ memcpy(&dev->descriptor, new_device_descriptor, sizeof(dev->descriptor)); + err = usb_reset_configuration(dev); + if (err < 0) + dev_dbg(&dev->dev, "error usb_reset_configuration: %d\n", err); +@@ -904,7 +908,7 @@ static void mbox2_setup_48_24_magic(struct usb_device *dev) + static int snd_usb_mbox2_boot_quirk(struct usb_device *dev) + { + struct usb_host_config *config = dev->actconfig; +- struct usb_device_descriptor new_device_descriptor; ++ struct usb_device_descriptor *new_device_descriptor __free(kfree) = NULL; + int err; + u8 bootresponse[0x12]; + int fwsize; +@@ -939,15 +943,19 @@ static int snd_usb_mbox2_boot_quirk(struct usb_device *dev) + + dev_dbg(&dev->dev, "device initialised!\n"); + ++ new_device_descriptor = kmalloc(sizeof(*new_device_descriptor), GFP_KERNEL); ++ if (!new_device_descriptor) ++ return -ENOMEM; ++ + err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, +- &new_device_descriptor, sizeof(new_device_descriptor)); ++ new_device_descriptor, sizeof(*new_device_descriptor)); + if (err < 0) + dev_dbg(&dev->dev, "error usb_get_descriptor: %d\n", err); +- if (new_device_descriptor.bNumConfigurations > dev->descriptor.bNumConfigurations) ++ if (new_device_descriptor->bNumConfigurations > dev->descriptor.bNumConfigurations) + dev_dbg(&dev->dev, "error too large bNumConfigurations: %d\n", +- new_device_descriptor.bNumConfigurations); ++ new_device_descriptor->bNumConfigurations); + else +- memcpy(&dev->descriptor, &new_device_descriptor, sizeof(dev->descriptor)); ++ memcpy(&dev->descriptor, new_device_descriptor, sizeof(dev->descriptor)); + + err = usb_reset_configuration(dev); + if (err < 0) +@@ -1261,7 +1269,7 @@ static void mbox3_setup_48_24_magic(struct usb_device *dev) + static int snd_usb_mbox3_boot_quirk(struct usb_device *dev) + { + struct usb_host_config *config = dev->actconfig; +- struct usb_device_descriptor new_device_descriptor; ++ struct usb_device_descriptor *new_device_descriptor __free(kfree) = NULL; + int err; + int descriptor_size; + +@@ -1274,15 +1282,19 @@ static int snd_usb_mbox3_boot_quirk(struct usb_device *dev) + + dev_dbg(&dev->dev, "device initialised!\n"); + ++ new_device_descriptor = kmalloc(sizeof(*new_device_descriptor), GFP_KERNEL); ++ if (!new_device_descriptor) ++ return -ENOMEM; ++ + err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, +- &new_device_descriptor, sizeof(new_device_descriptor)); ++ new_device_descriptor, sizeof(*new_device_descriptor)); + if (err < 0) + dev_dbg(&dev->dev, "error usb_get_descriptor: %d\n", err); +- if (new_device_descriptor.bNumConfigurations > dev->descriptor.bNumConfigurations) ++ if (new_device_descriptor->bNumConfigurations > dev->descriptor.bNumConfigurations) + dev_dbg(&dev->dev, "error too large bNumConfigurations: %d\n", +- new_device_descriptor.bNumConfigurations); ++ new_device_descriptor->bNumConfigurations); + else +- memcpy(&dev->descriptor, &new_device_descriptor, sizeof(dev->descriptor)); ++ memcpy(&dev->descriptor, new_device_descriptor, sizeof(dev->descriptor)); + + err = usb_reset_configuration(dev); + if (err < 0) +@@ -2065,6 +2077,8 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = { + QUIRK_FLAG_CTL_MSG_DELAY_1M | QUIRK_FLAG_MIC_RES_384), + DEVICE_FLG(0x046d, 0x09a4, /* Logitech QuickCam E 3500 */ + QUIRK_FLAG_CTL_MSG_DELAY_1M | QUIRK_FLAG_IGNORE_CTL_ERROR), ++ DEVICE_FLG(0x0499, 0x1506, /* Yamaha THR5 */ ++ QUIRK_FLAG_GENERIC_IMPLICIT_FB), + DEVICE_FLG(0x0499, 0x1509, /* Steinberg UR22 */ + QUIRK_FLAG_GENERIC_IMPLICIT_FB), + DEVICE_FLG(0x0499, 0x3108, /* Yamaha YIT-W12TX */ +diff --git a/tools/objtool/check.c b/tools/objtool/check.c +index cb363b507a329f..6ea78612635baf 100644 +--- a/tools/objtool/check.c ++++ b/tools/objtool/check.c +@@ -3521,10 +3521,13 @@ static int validate_branch(struct objtool_file *file, struct symbol *func, + break; + + case INSN_CONTEXT_SWITCH: +- if (func && (!next_insn || !next_insn->hint)) { +- WARN_FUNC("unsupported instruction in callable function", +- sec, insn->offset); +- return 1; ++ if (func) { ++ if (!next_insn || !next_insn->hint) { ++ WARN_FUNC("unsupported instruction in callable function", ++ sec, insn->offset); ++ return 1; ++ } ++ break; + } + return 0; + +diff --git a/tools/testing/selftests/drivers/net/mlxsw/sharedbuffer.sh b/tools/testing/selftests/drivers/net/mlxsw/sharedbuffer.sh +index 0c47faff9274b1..c068e6c2a580ea 100755 +--- a/tools/testing/selftests/drivers/net/mlxsw/sharedbuffer.sh ++++ b/tools/testing/selftests/drivers/net/mlxsw/sharedbuffer.sh +@@ -22,20 +22,34 @@ SB_ITC=0 + h1_create() + { + simple_if_init $h1 192.0.1.1/24 ++ tc qdisc add dev $h1 clsact ++ ++ # Add egress filter on $h1 that will guarantee that the packet sent, ++ # will be the only packet being passed to the device. ++ tc filter add dev $h1 egress pref 2 handle 102 matchall action drop + } + + h1_destroy() + { ++ tc filter del dev $h1 egress pref 2 handle 102 matchall action drop ++ tc qdisc del dev $h1 clsact + simple_if_fini $h1 192.0.1.1/24 + } + + h2_create() + { + simple_if_init $h2 192.0.1.2/24 ++ tc qdisc add dev $h2 clsact ++ ++ # Add egress filter on $h2 that will guarantee that the packet sent, ++ # will be the only packet being passed to the device. ++ tc filter add dev $h2 egress pref 1 handle 101 matchall action drop + } + + h2_destroy() + { ++ tc filter del dev $h2 egress pref 1 handle 101 matchall action drop ++ tc qdisc del dev $h2 clsact + simple_if_fini $h2 192.0.1.2/24 + } + +@@ -101,6 +115,11 @@ port_pool_test() + local exp_max_occ=$(devlink_cell_size_get) + local max_occ + ++ tc filter add dev $h1 egress protocol ip pref 1 handle 101 flower \ ++ src_mac $h1mac dst_mac $h2mac \ ++ src_ip 192.0.1.1 dst_ip 192.0.1.2 \ ++ action pass ++ + devlink sb occupancy clearmax $DEVLINK_DEV + + $MZ $h1 -c 1 -p 10 -a $h1mac -b $h2mac -A 192.0.1.1 -B 192.0.1.2 \ +@@ -108,11 +127,6 @@ port_pool_test() + + devlink sb occupancy snapshot $DEVLINK_DEV + +- RET=0 +- max_occ=$(sb_occ_pool_check $dl_port1 $SB_POOL_ING $exp_max_occ) +- check_err $? "Expected iPool($SB_POOL_ING) max occupancy to be $exp_max_occ, but got $max_occ" +- log_test "physical port's($h1) ingress pool" +- + RET=0 + max_occ=$(sb_occ_pool_check $dl_port2 $SB_POOL_ING $exp_max_occ) + check_err $? "Expected iPool($SB_POOL_ING) max occupancy to be $exp_max_occ, but got $max_occ" +@@ -122,6 +136,11 @@ port_pool_test() + max_occ=$(sb_occ_pool_check $cpu_dl_port $SB_POOL_EGR_CPU $exp_max_occ) + check_err $? "Expected ePool($SB_POOL_EGR_CPU) max occupancy to be $exp_max_occ, but got $max_occ" + log_test "CPU port's egress pool" ++ ++ tc filter del dev $h1 egress protocol ip pref 1 handle 101 flower \ ++ src_mac $h1mac dst_mac $h2mac \ ++ src_ip 192.0.1.1 dst_ip 192.0.1.2 \ ++ action pass + } + + port_tc_ip_test() +@@ -129,6 +148,11 @@ port_tc_ip_test() + local exp_max_occ=$(devlink_cell_size_get) + local max_occ + ++ tc filter add dev $h1 egress protocol ip pref 1 handle 101 flower \ ++ src_mac $h1mac dst_mac $h2mac \ ++ src_ip 192.0.1.1 dst_ip 192.0.1.2 \ ++ action pass ++ + devlink sb occupancy clearmax $DEVLINK_DEV + + $MZ $h1 -c 1 -p 10 -a $h1mac -b $h2mac -A 192.0.1.1 -B 192.0.1.2 \ +@@ -136,11 +160,6 @@ port_tc_ip_test() + + devlink sb occupancy snapshot $DEVLINK_DEV + +- RET=0 +- max_occ=$(sb_occ_itc_check $dl_port2 $SB_ITC $exp_max_occ) +- check_err $? "Expected ingress TC($SB_ITC) max occupancy to be $exp_max_occ, but got $max_occ" +- log_test "physical port's($h1) ingress TC - IP packet" +- + RET=0 + max_occ=$(sb_occ_itc_check $dl_port2 $SB_ITC $exp_max_occ) + check_err $? "Expected ingress TC($SB_ITC) max occupancy to be $exp_max_occ, but got $max_occ" +@@ -150,6 +169,11 @@ port_tc_ip_test() + max_occ=$(sb_occ_etc_check $cpu_dl_port $SB_ITC_CPU_IP $exp_max_occ) + check_err $? "Expected egress TC($SB_ITC_CPU_IP) max occupancy to be $exp_max_occ, but got $max_occ" + log_test "CPU port's egress TC - IP packet" ++ ++ tc filter del dev $h1 egress protocol ip pref 1 handle 101 flower \ ++ src_mac $h1mac dst_mac $h2mac \ ++ src_ip 192.0.1.1 dst_ip 192.0.1.2 \ ++ action pass + } + + port_tc_arp_test() +@@ -157,17 +181,15 @@ port_tc_arp_test() + local exp_max_occ=$(devlink_cell_size_get) + local max_occ + ++ tc filter add dev $h1 egress protocol arp pref 1 handle 101 flower \ ++ src_mac $h1mac action pass ++ + devlink sb occupancy clearmax $DEVLINK_DEV + + $MZ $h1 -c 1 -p 10 -a $h1mac -A 192.0.1.1 -t arp -q + + devlink sb occupancy snapshot $DEVLINK_DEV + +- RET=0 +- max_occ=$(sb_occ_itc_check $dl_port2 $SB_ITC $exp_max_occ) +- check_err $? "Expected ingress TC($SB_ITC) max occupancy to be $exp_max_occ, but got $max_occ" +- log_test "physical port's($h1) ingress TC - ARP packet" +- + RET=0 + max_occ=$(sb_occ_itc_check $dl_port2 $SB_ITC $exp_max_occ) + check_err $? "Expected ingress TC($SB_ITC) max occupancy to be $exp_max_occ, but got $max_occ" +@@ -177,6 +199,9 @@ port_tc_arp_test() + max_occ=$(sb_occ_etc_check $cpu_dl_port $SB_ITC_CPU_ARP $exp_max_occ) + check_err $? "Expected egress TC($SB_ITC_IP2ME) max occupancy to be $exp_max_occ, but got $max_occ" + log_test "CPU port's egress TC - ARP packet" ++ ++ tc filter del dev $h1 egress protocol arp pref 1 handle 101 flower \ ++ src_mac $h1mac action pass + } + + setup_prepare()
