diff options
author | 2024-08-14 10:09:52 -0400 | |
---|---|---|
committer | 2024-08-14 10:09:52 -0400 | |
commit | f1c0c7d7aefc065463125d0c66cad91e9e21d6cb (patch) | |
tree | a553dec28254459aa1cbd8a20520606a662d62cd | |
parent | Linux patch 6.6.45 (diff) | |
download | linux-patches-f1c0c7d7aefc065463125d0c66cad91e9e21d6cb.tar.gz linux-patches-f1c0c7d7aefc065463125d0c66cad91e9e21d6cb.tar.bz2 linux-patches-f1c0c7d7aefc065463125d0c66cad91e9e21d6cb.zip |
Linux patch 6.6.46
Signed-off-by: Mike Pagano <mpagano@gentoo.org>
-rw-r--r-- | 0000_README | 4 | ||||
-rw-r--r-- | 1045_linux-6.6.46.patch | 6300 |
2 files changed, 6304 insertions, 0 deletions
diff --git a/0000_README b/0000_README index 674bb8f3..b57442d8 100644 --- a/0000_README +++ b/0000_README @@ -223,6 +223,10 @@ Patch: 1044_linux-6.6.45.patch From: https://www.kernel.org Desc: Linux 6.6.45 +Patch: 1045_linux-6.6.46.patch +From: https://www.kernel.org +Desc: Linux 6.6.46 + Patch: 1510_fs-enable-link-security-restrictions-by-default.patch From: http://sources.debian.net/src/linux/3.16.7-ckt4-3/debian/patches/debian/fs-enable-link-security-restrictions-by-default.patch Desc: Enable link security restrictions by default. diff --git a/1045_linux-6.6.46.patch b/1045_linux-6.6.46.patch new file mode 100644 index 00000000..359d52ec --- /dev/null +++ b/1045_linux-6.6.46.patch @@ -0,0 +1,6300 @@ +diff --git a/Documentation/admin-guide/cifs/usage.rst b/Documentation/admin-guide/cifs/usage.rst +index 20aba92dfc5f5..3de599cf0779a 100644 +--- a/Documentation/admin-guide/cifs/usage.rst ++++ b/Documentation/admin-guide/cifs/usage.rst +@@ -741,7 +741,7 @@ SecurityFlags Flags which control security negotiation and + may use NTLMSSP 0x00080 + must use NTLMSSP 0x80080 + seal (packet encryption) 0x00040 +- must seal (not implemented yet) 0x40040 ++ must seal 0x40040 + + cifsFYI If set to non-zero value, additional debug information + will be logged to the system error log. This field +diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt +index 8d2f9ed3f1076..a7fe113897361 100644 +--- a/Documentation/admin-guide/kernel-parameters.txt ++++ b/Documentation/admin-guide/kernel-parameters.txt +@@ -664,12 +664,6 @@ + loops can be debugged more effectively on production + systems. + +- clocksource.max_cswd_read_retries= [KNL] +- Number of clocksource_watchdog() retries due to +- external delays before the clock will be marked +- unstable. Defaults to two retries, that is, +- three attempts to read the clock under test. +- + clocksource.verify_n_cpus= [KNL] + Limit the number of CPUs checked for clocksources + marked with CLOCK_SOURCE_VERIFY_PERCPU that +@@ -4655,11 +4649,9 @@ + + profile= [KNL] Enable kernel profiling via /proc/profile + Format: [<profiletype>,]<number> +- Param: <profiletype>: "schedule", "sleep", or "kvm" ++ Param: <profiletype>: "schedule" or "kvm" + [defaults to kernel profiling] + Param: "schedule" - profile schedule points. +- Param: "sleep" - profile D-state sleeping (millisecs). +- Requires CONFIG_SCHEDSTATS + Param: "kvm" - profile VM exits. + Param: <number> - step/bucket size as a power of 2 for + statistical time based profiling. +diff --git a/Documentation/arch/arm64/silicon-errata.rst b/Documentation/arch/arm64/silicon-errata.rst +index 29fd5213eeb2b..357d6cb98161f 100644 +--- a/Documentation/arch/arm64/silicon-errata.rst ++++ b/Documentation/arch/arm64/silicon-errata.rst +@@ -119,32 +119,68 @@ stable kernels. + +----------------+-----------------+-----------------+-----------------------------+ + | ARM | Cortex-A76 | #1463225 | ARM64_ERRATUM_1463225 | + +----------------+-----------------+-----------------+-----------------------------+ ++| ARM | Cortex-A76 | #3324349 | ARM64_ERRATUM_3194386 | +++----------------+-----------------+-----------------+-----------------------------+ + | ARM | Cortex-A77 | #1508412 | ARM64_ERRATUM_1508412 | + +----------------+-----------------+-----------------+-----------------------------+ ++| ARM | Cortex-A77 | #3324348 | ARM64_ERRATUM_3194386 | +++----------------+-----------------+-----------------+-----------------------------+ ++| ARM | Cortex-A78 | #3324344 | ARM64_ERRATUM_3194386 | +++----------------+-----------------+-----------------+-----------------------------+ ++| ARM | Cortex-A78C | #3324346,3324347| ARM64_ERRATUM_3194386 | +++----------------+-----------------+-----------------+-----------------------------+ + | ARM | Cortex-A710 | #2119858 | ARM64_ERRATUM_2119858 | + +----------------+-----------------+-----------------+-----------------------------+ + | ARM | Cortex-A710 | #2054223 | ARM64_ERRATUM_2054223 | + +----------------+-----------------+-----------------+-----------------------------+ + | ARM | Cortex-A710 | #2224489 | ARM64_ERRATUM_2224489 | + +----------------+-----------------+-----------------+-----------------------------+ ++| ARM | Cortex-A710 | #3324338 | ARM64_ERRATUM_3194386 | +++----------------+-----------------+-----------------+-----------------------------+ + | ARM | Cortex-A715 | #2645198 | ARM64_ERRATUM_2645198 | + +----------------+-----------------+-----------------+-----------------------------+ ++| ARM | Cortex-A720 | #3456091 | ARM64_ERRATUM_3194386 | +++----------------+-----------------+-----------------+-----------------------------+ ++| ARM | Cortex-A725 | #3456106 | ARM64_ERRATUM_3194386 | +++----------------+-----------------+-----------------+-----------------------------+ ++| ARM | Cortex-X1 | #3324344 | ARM64_ERRATUM_3194386 | +++----------------+-----------------+-----------------+-----------------------------+ ++| ARM | Cortex-X1C | #3324346 | ARM64_ERRATUM_3194386 | +++----------------+-----------------+-----------------+-----------------------------+ + | ARM | Cortex-X2 | #2119858 | ARM64_ERRATUM_2119858 | + +----------------+-----------------+-----------------+-----------------------------+ + | ARM | Cortex-X2 | #2224489 | ARM64_ERRATUM_2224489 | + +----------------+-----------------+-----------------+-----------------------------+ ++| ARM | Cortex-X2 | #3324338 | ARM64_ERRATUM_3194386 | +++----------------+-----------------+-----------------+-----------------------------+ ++| ARM | Cortex-X3 | #3324335 | ARM64_ERRATUM_3194386 | +++----------------+-----------------+-----------------+-----------------------------+ ++| ARM | Cortex-X4 | #3194386 | ARM64_ERRATUM_3194386 | +++----------------+-----------------+-----------------+-----------------------------+ ++| ARM | Cortex-X925 | #3324334 | ARM64_ERRATUM_3194386 | +++----------------+-----------------+-----------------+-----------------------------+ + | ARM | Neoverse-N1 | #1188873,1418040| ARM64_ERRATUM_1418040 | + +----------------+-----------------+-----------------+-----------------------------+ + | ARM | Neoverse-N1 | #1349291 | N/A | + +----------------+-----------------+-----------------+-----------------------------+ + | ARM | Neoverse-N1 | #1542419 | ARM64_ERRATUM_1542419 | + +----------------+-----------------+-----------------+-----------------------------+ ++| ARM | Neoverse-N1 | #3324349 | ARM64_ERRATUM_3194386 | +++----------------+-----------------+-----------------+-----------------------------+ + | ARM | Neoverse-N2 | #2139208 | ARM64_ERRATUM_2139208 | + +----------------+-----------------+-----------------+-----------------------------+ + | ARM | Neoverse-N2 | #2067961 | ARM64_ERRATUM_2067961 | + +----------------+-----------------+-----------------+-----------------------------+ + | ARM | Neoverse-N2 | #2253138 | ARM64_ERRATUM_2253138 | + +----------------+-----------------+-----------------+-----------------------------+ ++| ARM | Neoverse-N2 | #3324339 | ARM64_ERRATUM_3194386 | +++----------------+-----------------+-----------------+-----------------------------+ ++| ARM | Neoverse-V1 | #3324341 | ARM64_ERRATUM_3194386 | +++----------------+-----------------+-----------------+-----------------------------+ ++| ARM | Neoverse-V2 | #3324336 | ARM64_ERRATUM_3194386 | +++----------------+-----------------+-----------------+-----------------------------+ ++| ARM | Neoverse-V3 | #3312417 | ARM64_ERRATUM_3194386 | +++----------------+-----------------+-----------------+-----------------------------+ + | ARM | MMU-500 | #841119,826419 | N/A | + +----------------+-----------------+-----------------+-----------------------------+ + | ARM | MMU-600 | #1076982,1209401| N/A | +diff --git a/Documentation/hwmon/corsair-psu.rst b/Documentation/hwmon/corsair-psu.rst +index 16db34d464dd6..7ed794087f848 100644 +--- a/Documentation/hwmon/corsair-psu.rst ++++ b/Documentation/hwmon/corsair-psu.rst +@@ -15,11 +15,11 @@ Supported devices: + + Corsair HX850i + +- Corsair HX1000i (Series 2022 and 2023) ++ Corsair HX1000i (Legacy and Series 2023) + +- Corsair HX1200i ++ Corsair HX1200i (Legacy and Series 2023) + +- Corsair HX1500i (Series 2022 and 2023) ++ Corsair HX1500i (Legacy and Series 2023) + + Corsair RM550i + +diff --git a/Makefile b/Makefile +index 0bd4bee2128b4..77de99984c2f1 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,7 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0 + VERSION = 6 + PATCHLEVEL = 6 +-SUBLEVEL = 45 ++SUBLEVEL = 46 + EXTRAVERSION = + NAME = Hurr durr I'ma ninja sloth + +diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig +index f9777ce2ccb2d..9e0c1ac3d13ee 100644 +--- a/arch/arm64/Kconfig ++++ b/arch/arm64/Kconfig +@@ -1068,6 +1068,44 @@ config ARM64_ERRATUM_3117295 + + If unsure, say Y. + ++config ARM64_ERRATUM_3194386 ++ bool "Cortex-*/Neoverse-*: workaround for MSR SSBS not self-synchronizing" ++ default y ++ help ++ This option adds the workaround for the following errata: ++ ++ * ARM Cortex-A76 erratum 3324349 ++ * ARM Cortex-A77 erratum 3324348 ++ * ARM Cortex-A78 erratum 3324344 ++ * ARM Cortex-A78C erratum 3324346 ++ * ARM Cortex-A78C erratum 3324347 ++ * ARM Cortex-A710 erratam 3324338 ++ * ARM Cortex-A720 erratum 3456091 ++ * ARM Cortex-A725 erratum 3456106 ++ * ARM Cortex-X1 erratum 3324344 ++ * ARM Cortex-X1C erratum 3324346 ++ * ARM Cortex-X2 erratum 3324338 ++ * ARM Cortex-X3 erratum 3324335 ++ * ARM Cortex-X4 erratum 3194386 ++ * ARM Cortex-X925 erratum 3324334 ++ * ARM Neoverse-N1 erratum 3324349 ++ * ARM Neoverse N2 erratum 3324339 ++ * ARM Neoverse-V1 erratum 3324341 ++ * ARM Neoverse V2 erratum 3324336 ++ * ARM Neoverse-V3 erratum 3312417 ++ ++ On affected cores "MSR SSBS, #0" instructions may not affect ++ subsequent speculative instructions, which may permit unexepected ++ speculative store bypassing. ++ ++ Work around this problem by placing a Speculation Barrier (SB) or ++ Instruction Synchronization Barrier (ISB) after kernel changes to ++ SSBS. The presence of the SSBS special-purpose register is hidden ++ from hwcaps and EL0 reads of ID_AA64PFR1_EL1, such that userspace ++ will use the PR_SPEC_STORE_BYPASS prctl to change SSBS. ++ ++ If unsure, say Y. ++ + config CAVIUM_ERRATUM_22375 + bool "Cavium erratum 22375, 24313" + default y +diff --git a/arch/arm64/include/asm/barrier.h b/arch/arm64/include/asm/barrier.h +index cf2987464c186..1ca947d5c9396 100644 +--- a/arch/arm64/include/asm/barrier.h ++++ b/arch/arm64/include/asm/barrier.h +@@ -40,6 +40,10 @@ + */ + #define dgh() asm volatile("hint #6" : : : "memory") + ++#define spec_bar() asm volatile(ALTERNATIVE("dsb nsh\nisb\n", \ ++ SB_BARRIER_INSN"nop\n", \ ++ ARM64_HAS_SB)) ++ + #ifdef CONFIG_ARM64_PSEUDO_NMI + #define pmr_sync() \ + do { \ +diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h +index 52f076afeb960..5fd7caea44193 100644 +--- a/arch/arm64/include/asm/cputype.h ++++ b/arch/arm64/include/asm/cputype.h +@@ -86,6 +86,14 @@ + #define ARM_CPU_PART_CORTEX_X2 0xD48 + #define ARM_CPU_PART_NEOVERSE_N2 0xD49 + #define ARM_CPU_PART_CORTEX_A78C 0xD4B ++#define ARM_CPU_PART_CORTEX_X1C 0xD4C ++#define ARM_CPU_PART_CORTEX_X3 0xD4E ++#define ARM_CPU_PART_NEOVERSE_V2 0xD4F ++#define ARM_CPU_PART_CORTEX_A720 0xD81 ++#define ARM_CPU_PART_CORTEX_X4 0xD82 ++#define ARM_CPU_PART_NEOVERSE_V3 0xD84 ++#define ARM_CPU_PART_CORTEX_X925 0xD85 ++#define ARM_CPU_PART_CORTEX_A725 0xD87 + + #define APM_CPU_PART_XGENE 0x000 + #define APM_CPU_VAR_POTENZA 0x00 +@@ -159,6 +167,14 @@ + #define MIDR_CORTEX_X2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X2) + #define MIDR_NEOVERSE_N2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N2) + #define MIDR_CORTEX_A78C MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A78C) ++#define MIDR_CORTEX_X1C MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X1C) ++#define MIDR_CORTEX_X3 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X3) ++#define MIDR_NEOVERSE_V2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_V2) ++#define MIDR_CORTEX_A720 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A720) ++#define MIDR_CORTEX_X4 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X4) ++#define MIDR_NEOVERSE_V3 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_V3) ++#define MIDR_CORTEX_X925 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X925) ++#define MIDR_CORTEX_A725 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A725) + #define MIDR_THUNDERX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX) + #define MIDR_THUNDERX_81XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_81XX) + #define MIDR_THUNDERX_83XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_83XX) +diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c +index 7bba831f62c33..57b1d6a68256b 100644 +--- a/arch/arm64/kernel/cpu_errata.c ++++ b/arch/arm64/kernel/cpu_errata.c +@@ -448,6 +448,30 @@ static const struct midr_range erratum_spec_unpriv_load_list[] = { + }; + #endif + ++#ifdef CONFIG_ARM64_ERRATUM_3194386 ++static const struct midr_range erratum_spec_ssbs_list[] = { ++ MIDR_ALL_VERSIONS(MIDR_CORTEX_A76), ++ MIDR_ALL_VERSIONS(MIDR_CORTEX_A77), ++ MIDR_ALL_VERSIONS(MIDR_CORTEX_A78), ++ MIDR_ALL_VERSIONS(MIDR_CORTEX_A78C), ++ MIDR_ALL_VERSIONS(MIDR_CORTEX_A710), ++ MIDR_ALL_VERSIONS(MIDR_CORTEX_A720), ++ MIDR_ALL_VERSIONS(MIDR_CORTEX_A725), ++ MIDR_ALL_VERSIONS(MIDR_CORTEX_X1), ++ MIDR_ALL_VERSIONS(MIDR_CORTEX_X1C), ++ MIDR_ALL_VERSIONS(MIDR_CORTEX_X2), ++ MIDR_ALL_VERSIONS(MIDR_CORTEX_X3), ++ MIDR_ALL_VERSIONS(MIDR_CORTEX_X4), ++ MIDR_ALL_VERSIONS(MIDR_CORTEX_X925), ++ MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N1), ++ MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N2), ++ MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V1), ++ MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V2), ++ MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V3), ++ {} ++}; ++#endif ++ + const struct arm64_cpu_capabilities arm64_errata[] = { + #ifdef CONFIG_ARM64_WORKAROUND_CLEAN_CACHE + { +@@ -746,6 +770,13 @@ const struct arm64_cpu_capabilities arm64_errata[] = { + .cpu_enable = cpu_clear_bf16_from_user_emulation, + }, + #endif ++#ifdef CONFIG_ARM64_ERRATUM_3194386 ++ { ++ .desc = "SSBS not fully self-synchronizing", ++ .capability = ARM64_WORKAROUND_SPECULATIVE_SSBS, ++ ERRATA_MIDR_RANGE_LIST(erratum_spec_ssbs_list), ++ }, ++#endif + #ifdef CONFIG_ARM64_WORKAROUND_SPECULATIVE_UNPRIV_LOAD + { + .desc = "ARM errata 2966298, 3117295", +diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c +index 444a73c2e6385..7e96604559004 100644 +--- a/arch/arm64/kernel/cpufeature.c ++++ b/arch/arm64/kernel/cpufeature.c +@@ -2190,6 +2190,17 @@ static void cpu_enable_mte(struct arm64_cpu_capabilities const *cap) + } + #endif /* CONFIG_ARM64_MTE */ + ++static void user_feature_fixup(void) ++{ ++ if (cpus_have_cap(ARM64_WORKAROUND_SPECULATIVE_SSBS)) { ++ struct arm64_ftr_reg *regp; ++ ++ regp = get_arm64_ftr_reg(SYS_ID_AA64PFR1_EL1); ++ if (regp) ++ regp->user_mask &= ~ID_AA64PFR1_EL1_SSBS_MASK; ++ } ++} ++ + static void elf_hwcap_fixup(void) + { + #ifdef CONFIG_ARM64_ERRATUM_1742098 +@@ -3345,6 +3356,7 @@ void __init setup_cpu_features(void) + u32 cwg; + + setup_system_capabilities(); ++ user_feature_fixup(); + setup_elf_hwcaps(arm64_elf_hwcaps); + + if (system_supports_32bit_el0()) { +diff --git a/arch/arm64/kernel/proton-pack.c b/arch/arm64/kernel/proton-pack.c +index 05f40c4e18fda..57503dc4b22fa 100644 +--- a/arch/arm64/kernel/proton-pack.c ++++ b/arch/arm64/kernel/proton-pack.c +@@ -558,6 +558,18 @@ static enum mitigation_state spectre_v4_enable_hw_mitigation(void) + + /* SCTLR_EL1.DSSBS was initialised to 0 during boot */ + set_pstate_ssbs(0); ++ ++ /* ++ * SSBS is self-synchronizing and is intended to affect subsequent ++ * speculative instructions, but some CPUs can speculate with a stale ++ * value of SSBS. ++ * ++ * Mitigate this with an unconditional speculation barrier, as CPUs ++ * could mis-speculate branches and bypass a conditional barrier. ++ */ ++ if (IS_ENABLED(CONFIG_ARM64_ERRATUM_3194386)) ++ spec_bar(); ++ + return SPECTRE_MITIGATED; + } + +diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps +index 5511bee15603a..c251ef3caae56 100644 +--- a/arch/arm64/tools/cpucaps ++++ b/arch/arm64/tools/cpucaps +@@ -99,4 +99,5 @@ WORKAROUND_NVIDIA_CARMEL_CNP + WORKAROUND_QCOM_FALKOR_E1003 + WORKAROUND_REPEAT_TLBI + WORKAROUND_SPECULATIVE_AT ++WORKAROUND_SPECULATIVE_SSBS + WORKAROUND_SPECULATIVE_UNPRIV_LOAD +diff --git a/arch/loongarch/kernel/efi.c b/arch/loongarch/kernel/efi.c +index 9fc10cea21e10..de4f3def4af0b 100644 +--- a/arch/loongarch/kernel/efi.c ++++ b/arch/loongarch/kernel/efi.c +@@ -66,6 +66,12 @@ void __init efi_runtime_init(void) + set_bit(EFI_RUNTIME_SERVICES, &efi.flags); + } + ++bool efi_poweroff_required(void) ++{ ++ return efi_enabled(EFI_RUNTIME_SERVICES) && ++ (acpi_gbl_reduced_hardware || acpi_no_s5); ++} ++ + unsigned long __initdata screen_info_table = EFI_INVALID_TABLE_ADDR; + + static void __init init_screen_info(void) +diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig +index 2834a64064970..a077e6bf9475f 100644 +--- a/arch/parisc/Kconfig ++++ b/arch/parisc/Kconfig +@@ -18,6 +18,7 @@ config PARISC + select ARCH_SUPPORTS_HUGETLBFS if PA20 + select ARCH_SUPPORTS_MEMORY_FAILURE + select ARCH_STACKWALK ++ select ARCH_HAS_CACHE_LINE_SIZE + select ARCH_HAS_DEBUG_VM_PGTABLE + select HAVE_RELIABLE_STACKTRACE + select DMA_OPS +diff --git a/arch/parisc/include/asm/cache.h b/arch/parisc/include/asm/cache.h +index 2a60d7a72f1fa..a3f0f100f2194 100644 +--- a/arch/parisc/include/asm/cache.h ++++ b/arch/parisc/include/asm/cache.h +@@ -20,7 +20,16 @@ + + #define SMP_CACHE_BYTES L1_CACHE_BYTES + +-#define ARCH_DMA_MINALIGN L1_CACHE_BYTES ++#ifdef CONFIG_PA20 ++#define ARCH_DMA_MINALIGN 128 ++#else ++#define ARCH_DMA_MINALIGN 32 ++#endif ++#define ARCH_KMALLOC_MINALIGN 16 /* ldcw requires 16-byte alignment */ ++ ++#define arch_slab_minalign() ((unsigned)dcache_stride) ++#define cache_line_size() dcache_stride ++#define dma_get_cache_alignment cache_line_size + + #define __read_mostly __section(".data..read_mostly") + +diff --git a/arch/parisc/net/bpf_jit_core.c b/arch/parisc/net/bpf_jit_core.c +index d6ee2fd455503..7b9cb3cda27ee 100644 +--- a/arch/parisc/net/bpf_jit_core.c ++++ b/arch/parisc/net/bpf_jit_core.c +@@ -114,7 +114,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog) + jit_data->header = + bpf_jit_binary_alloc(prog_size + extable_size, + &jit_data->image, +- sizeof(u32), ++ sizeof(long), + bpf_fill_ill_insns); + if (!jit_data->header) { + prog = orig_prog; +diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h +index 621bac6b74011..24b7bd255e983 100644 +--- a/arch/x86/include/asm/msr-index.h ++++ b/arch/x86/include/asm/msr-index.h +@@ -237,6 +237,7 @@ + #define MSR_INTEGRITY_CAPS_ARRAY_BIST BIT(MSR_INTEGRITY_CAPS_ARRAY_BIST_BIT) + #define MSR_INTEGRITY_CAPS_PERIODIC_BIST_BIT 4 + #define MSR_INTEGRITY_CAPS_PERIODIC_BIST BIT(MSR_INTEGRITY_CAPS_PERIODIC_BIST_BIT) ++#define MSR_INTEGRITY_CAPS_SAF_GEN_MASK GENMASK_ULL(10, 9) + + #define MSR_LBR_NHM_FROM 0x00000680 + #define MSR_LBR_NHM_TO 0x000006c0 +diff --git a/arch/x86/include/asm/qspinlock.h b/arch/x86/include/asm/qspinlock.h +index cde8357bb226d..e897046c5d2c6 100644 +--- a/arch/x86/include/asm/qspinlock.h ++++ b/arch/x86/include/asm/qspinlock.h +@@ -66,13 +66,15 @@ static inline bool vcpu_is_preempted(long cpu) + + #ifdef CONFIG_PARAVIRT + /* +- * virt_spin_lock_key - enables (by default) the virt_spin_lock() hijack. ++ * virt_spin_lock_key - disables by default the virt_spin_lock() hijack. + * +- * Native (and PV wanting native due to vCPU pinning) should disable this key. +- * It is done in this backwards fashion to only have a single direction change, +- * which removes ordering between native_pv_spin_init() and HV setup. ++ * Native (and PV wanting native due to vCPU pinning) should keep this key ++ * disabled. Native does not touch the key. ++ * ++ * When in a guest then native_pv_lock_init() enables the key first and ++ * KVM/XEN might conditionally disable it later in the boot process again. + */ +-DECLARE_STATIC_KEY_TRUE(virt_spin_lock_key); ++DECLARE_STATIC_KEY_FALSE(virt_spin_lock_key); + + /* + * Shortcut for the queued_spin_lock_slowpath() function that allows +diff --git a/arch/x86/kernel/cpu/mtrr/mtrr.c b/arch/x86/kernel/cpu/mtrr/mtrr.c +index 767bf1c71aadd..2a2fc14955cd3 100644 +--- a/arch/x86/kernel/cpu/mtrr/mtrr.c ++++ b/arch/x86/kernel/cpu/mtrr/mtrr.c +@@ -609,7 +609,7 @@ void mtrr_save_state(void) + { + int first_cpu; + +- if (!mtrr_enabled()) ++ if (!mtrr_enabled() || !mtrr_state.have_fixed) + return; + + first_cpu = cpumask_first(cpu_online_mask); +diff --git a/arch/x86/kernel/paravirt.c b/arch/x86/kernel/paravirt.c +index 97f1436c1a203..8d51c86caa415 100644 +--- a/arch/x86/kernel/paravirt.c ++++ b/arch/x86/kernel/paravirt.c +@@ -71,13 +71,12 @@ DEFINE_PARAVIRT_ASM(pv_native_irq_enable, "sti", .noinstr.text); + DEFINE_PARAVIRT_ASM(pv_native_read_cr2, "mov %cr2, %rax", .noinstr.text); + #endif + +-DEFINE_STATIC_KEY_TRUE(virt_spin_lock_key); ++DEFINE_STATIC_KEY_FALSE(virt_spin_lock_key); + + void __init native_pv_lock_init(void) + { +- if (IS_ENABLED(CONFIG_PARAVIRT_SPINLOCKS) && +- !boot_cpu_has(X86_FEATURE_HYPERVISOR)) +- static_branch_disable(&virt_spin_lock_key); ++ if (boot_cpu_has(X86_FEATURE_HYPERVISOR)) ++ static_branch_enable(&virt_spin_lock_key); + } + + static void native_tlb_remove_table(struct mmu_gather *tlb, void *table) +diff --git a/arch/x86/mm/pti.c b/arch/x86/mm/pti.c +index 51b6b78e6b175..41d8c8f475a7c 100644 +--- a/arch/x86/mm/pti.c ++++ b/arch/x86/mm/pti.c +@@ -374,14 +374,14 @@ pti_clone_pgtable(unsigned long start, unsigned long end, + */ + *target_pmd = *pmd; + +- addr += PMD_SIZE; ++ addr = round_up(addr + 1, PMD_SIZE); + + } else if (level == PTI_CLONE_PTE) { + + /* Walk the page-table down to the pte level */ + pte = pte_offset_kernel(pmd, addr); + if (pte_none(*pte)) { +- addr += PAGE_SIZE; ++ addr = round_up(addr + 1, PAGE_SIZE); + continue; + } + +@@ -401,7 +401,7 @@ pti_clone_pgtable(unsigned long start, unsigned long end, + /* Clone the PTE */ + *target_pte = *pte; + +- addr += PAGE_SIZE; ++ addr = round_up(addr + 1, PAGE_SIZE); + + } else { + BUG(); +@@ -496,7 +496,7 @@ static void pti_clone_entry_text(void) + { + pti_clone_pgtable((unsigned long) __entry_text_start, + (unsigned long) __entry_text_end, +- PTI_CLONE_PMD); ++ PTI_LEVEL_KERNEL_IMAGE); + } + + /* +diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c +index 969bf81e8d546..7f7ad94f22b91 100644 +--- a/drivers/acpi/battery.c ++++ b/drivers/acpi/battery.c +@@ -678,12 +678,18 @@ static ssize_t acpi_battery_alarm_store(struct device *dev, + return count; + } + +-static const struct device_attribute alarm_attr = { ++static struct device_attribute alarm_attr = { + .attr = {.name = "alarm", .mode = 0644}, + .show = acpi_battery_alarm_show, + .store = acpi_battery_alarm_store, + }; + ++static struct attribute *acpi_battery_attrs[] = { ++ &alarm_attr.attr, ++ NULL ++}; ++ATTRIBUTE_GROUPS(acpi_battery); ++ + /* + * The Battery Hooking API + * +@@ -823,7 +829,10 @@ static void __exit battery_hook_exit(void) + + static int sysfs_add_battery(struct acpi_battery *battery) + { +- struct power_supply_config psy_cfg = { .drv_data = battery, }; ++ struct power_supply_config psy_cfg = { ++ .drv_data = battery, ++ .attr_grp = acpi_battery_groups, ++ }; + bool full_cap_broken = false; + + if (!ACPI_BATTERY_CAPACITY_VALID(battery->full_charge_capacity) && +@@ -868,7 +877,7 @@ static int sysfs_add_battery(struct acpi_battery *battery) + return result; + } + battery_hook_add_battery(battery); +- return device_create_file(&battery->bat->dev, &alarm_attr); ++ return 0; + } + + static void sysfs_remove_battery(struct acpi_battery *battery) +@@ -879,7 +888,6 @@ static void sysfs_remove_battery(struct acpi_battery *battery) + return; + } + battery_hook_remove_battery(battery); +- device_remove_file(&battery->bat->dev, &alarm_attr); + power_supply_unregister(battery->bat); + battery->bat = NULL; + mutex_unlock(&battery->sysfs_lock); +diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c +index 94e3c000df2e1..fdeb46ed21d69 100644 +--- a/drivers/acpi/sbs.c ++++ b/drivers/acpi/sbs.c +@@ -77,7 +77,6 @@ struct acpi_battery { + u16 spec; + u8 id; + u8 present:1; +- u8 have_sysfs_alarm:1; + }; + + #define to_acpi_battery(x) power_supply_get_drvdata(x) +@@ -462,12 +461,18 @@ static ssize_t acpi_battery_alarm_store(struct device *dev, + return count; + } + +-static const struct device_attribute alarm_attr = { ++static struct device_attribute alarm_attr = { + .attr = {.name = "alarm", .mode = 0644}, + .show = acpi_battery_alarm_show, + .store = acpi_battery_alarm_store, + }; + ++static struct attribute *acpi_battery_attrs[] = { ++ &alarm_attr.attr, ++ NULL ++}; ++ATTRIBUTE_GROUPS(acpi_battery); ++ + /* -------------------------------------------------------------------------- + Driver Interface + -------------------------------------------------------------------------- */ +@@ -518,7 +523,10 @@ static int acpi_battery_read(struct acpi_battery *battery) + static int acpi_battery_add(struct acpi_sbs *sbs, int id) + { + struct acpi_battery *battery = &sbs->battery[id]; +- struct power_supply_config psy_cfg = { .drv_data = battery, }; ++ struct power_supply_config psy_cfg = { ++ .drv_data = battery, ++ .attr_grp = acpi_battery_groups, ++ }; + int result; + + battery->id = id; +@@ -548,10 +556,6 @@ static int acpi_battery_add(struct acpi_sbs *sbs, int id) + goto end; + } + +- result = device_create_file(&battery->bat->dev, &alarm_attr); +- if (result) +- goto end; +- battery->have_sysfs_alarm = 1; + end: + pr_info("%s [%s]: Battery Slot [%s] (battery %s)\n", + ACPI_SBS_DEVICE_NAME, acpi_device_bid(sbs->device), +@@ -563,11 +567,8 @@ static void acpi_battery_remove(struct acpi_sbs *sbs, int id) + { + struct acpi_battery *battery = &sbs->battery[id]; + +- if (battery->bat) { +- if (battery->have_sysfs_alarm) +- device_remove_file(&battery->bat->dev, &alarm_attr); ++ if (battery->bat) + power_supply_unregister(battery->bat); +- } + } + + static int acpi_charger_add(struct acpi_sbs *sbs) +diff --git a/drivers/base/core.c b/drivers/base/core.c +index aeb4644817d57..cb323700e952f 100644 +--- a/drivers/base/core.c ++++ b/drivers/base/core.c +@@ -25,6 +25,7 @@ + #include <linux/mutex.h> + #include <linux/pm_runtime.h> + #include <linux/netdevice.h> ++#include <linux/rcupdate.h> + #include <linux/sched/signal.h> + #include <linux/sched/mm.h> + #include <linux/string_helpers.h> +@@ -2565,6 +2566,7 @@ static const char *dev_uevent_name(const struct kobject *kobj) + static int dev_uevent(const struct kobject *kobj, struct kobj_uevent_env *env) + { + const struct device *dev = kobj_to_dev(kobj); ++ struct device_driver *driver; + int retval = 0; + + /* add device node properties if present */ +@@ -2593,8 +2595,12 @@ static int dev_uevent(const struct kobject *kobj, struct kobj_uevent_env *env) + if (dev->type && dev->type->name) + add_uevent_var(env, "DEVTYPE=%s", dev->type->name); + +- if (dev->driver) +- add_uevent_var(env, "DRIVER=%s", dev->driver->name); ++ /* Synchronize with module_remove_driver() */ ++ rcu_read_lock(); ++ driver = READ_ONCE(dev->driver); ++ if (driver) ++ add_uevent_var(env, "DRIVER=%s", driver->name); ++ rcu_read_unlock(); + + /* Add common DT information about the device */ + of_device_uevent(dev, env); +@@ -2664,11 +2670,8 @@ static ssize_t uevent_show(struct device *dev, struct device_attribute *attr, + if (!env) + return -ENOMEM; + +- /* Synchronize with really_probe() */ +- device_lock(dev); + /* let the kset specific function add its keys */ + retval = kset->uevent_ops->uevent(&dev->kobj, env); +- device_unlock(dev); + if (retval) + goto out; + +diff --git a/drivers/base/module.c b/drivers/base/module.c +index a1b55da07127d..b0b79b9c189d4 100644 +--- a/drivers/base/module.c ++++ b/drivers/base/module.c +@@ -7,6 +7,7 @@ + #include <linux/errno.h> + #include <linux/slab.h> + #include <linux/string.h> ++#include <linux/rcupdate.h> + #include "base.h" + + static char *make_driver_name(struct device_driver *drv) +@@ -97,6 +98,9 @@ void module_remove_driver(struct device_driver *drv) + if (!drv) + return; + ++ /* Synchronize with dev_uevent() */ ++ synchronize_rcu(); ++ + sysfs_remove_link(&drv->p->kobj, "module"); + + if (drv->owner) +diff --git a/drivers/bluetooth/btnxpuart.c b/drivers/bluetooth/btnxpuart.c +index 83e8e27a5ecec..b5d40e0e05f31 100644 +--- a/drivers/bluetooth/btnxpuart.c ++++ b/drivers/bluetooth/btnxpuart.c +@@ -340,7 +340,7 @@ static void ps_cancel_timer(struct btnxpuart_dev *nxpdev) + struct ps_data *psdata = &nxpdev->psdata; + + flush_work(&psdata->work); +- del_timer_sync(&psdata->ps_timer); ++ timer_shutdown_sync(&psdata->ps_timer); + } + + static void ps_control(struct hci_dev *hdev, u8 ps_state) +diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c +index 26919556ef5f0..b72b36e0abed8 100644 +--- a/drivers/clocksource/sh_cmt.c ++++ b/drivers/clocksource/sh_cmt.c +@@ -528,6 +528,7 @@ static void sh_cmt_set_next(struct sh_cmt_channel *ch, unsigned long delta) + static irqreturn_t sh_cmt_interrupt(int irq, void *dev_id) + { + struct sh_cmt_channel *ch = dev_id; ++ unsigned long flags; + + /* clear flags */ + sh_cmt_write_cmcsr(ch, sh_cmt_read_cmcsr(ch) & +@@ -558,6 +559,8 @@ static irqreturn_t sh_cmt_interrupt(int irq, void *dev_id) + + ch->flags &= ~FLAG_SKIPEVENT; + ++ raw_spin_lock_irqsave(&ch->lock, flags); ++ + if (ch->flags & FLAG_REPROGRAM) { + ch->flags &= ~FLAG_REPROGRAM; + sh_cmt_clock_event_program_verify(ch, 1); +@@ -570,6 +573,8 @@ static irqreturn_t sh_cmt_interrupt(int irq, void *dev_id) + + ch->flags &= ~FLAG_IRQCONTEXT; + ++ raw_spin_unlock_irqrestore(&ch->lock, flags); ++ + return IRQ_HANDLED; + } + +@@ -780,12 +785,18 @@ static int sh_cmt_clock_event_next(unsigned long delta, + struct clock_event_device *ced) + { + struct sh_cmt_channel *ch = ced_to_sh_cmt(ced); ++ unsigned long flags; + + BUG_ON(!clockevent_state_oneshot(ced)); ++ ++ raw_spin_lock_irqsave(&ch->lock, flags); ++ + if (likely(ch->flags & FLAG_IRQCONTEXT)) + ch->next_match_value = delta - 1; + else +- sh_cmt_set_next(ch, delta - 1); ++ __sh_cmt_set_next(ch, delta - 1); ++ ++ raw_spin_unlock_irqrestore(&ch->lock, flags); + + return 0; + } +diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c +index 1c512ed3fa6d9..5c0016c77d2ab 100644 +--- a/drivers/gpio/gpiolib.c ++++ b/drivers/gpio/gpiolib.c +@@ -15,6 +15,7 @@ + #include <linux/kernel.h> + #include <linux/list.h> + #include <linux/module.h> ++#include <linux/nospec.h> + #include <linux/of.h> + #include <linux/pinctrl/consumer.h> + #include <linux/seq_file.h> +@@ -164,7 +165,7 @@ struct gpio_desc *gpiochip_get_desc(struct gpio_chip *gc, + if (hwnum >= gdev->ngpio) + return ERR_PTR(-EINVAL); + +- return &gdev->descs[hwnum]; ++ return &gdev->descs[array_index_nospec(hwnum, gdev->ngpio)]; + } + EXPORT_SYMBOL_GPL(gpiochip_get_desc); + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +index ea1bce13db941..eb663eb811563 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +@@ -3561,6 +3561,7 @@ int amdgpu_device_init(struct amdgpu_device *adev, + mutex_init(&adev->grbm_idx_mutex); + mutex_init(&adev->mn_lock); + mutex_init(&adev->virt.vf_errors.lock); ++ mutex_init(&adev->virt.rlcg_reg_lock); + hash_init(adev->mn_hash); + mutex_init(&adev->psp.mutex); + mutex_init(&adev->notifier_lock); +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c +index de9d7f3dc2336..99dd86337e841 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c +@@ -258,9 +258,8 @@ amdgpu_job_prepare_job(struct drm_sched_job *sched_job, + struct dma_fence *fence = NULL; + int r; + +- /* Ignore soft recovered fences here */ + r = drm_sched_entity_error(s_entity); +- if (r && r != -ENODATA) ++ if (r) + goto error; + + if (!fence && job->gang_submit) +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp_ta.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp_ta.c +index ca5c86e5f7cd6..8e8afbd237bcd 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp_ta.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp_ta.c +@@ -334,7 +334,7 @@ static ssize_t ta_if_invoke_debugfs_write(struct file *fp, const char *buf, size + + set_ta_context_funcs(psp, ta_type, &context); + +- if (!context->initialized) { ++ if (!context || !context->initialized) { + dev_err(adev->dev, "TA is not initialized\n"); + ret = -EINVAL; + goto err_free_shared_buf; +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c +index 67b75ff0f7c37..7cba98f8bbdca 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c +@@ -1780,12 +1780,15 @@ static void amdgpu_ras_interrupt_process_handler(struct work_struct *work) + int amdgpu_ras_interrupt_dispatch(struct amdgpu_device *adev, + struct ras_dispatch_if *info) + { +- struct ras_manager *obj = amdgpu_ras_find_obj(adev, &info->head); +- struct ras_ih_data *data = &obj->ih_data; ++ struct ras_manager *obj; ++ struct ras_ih_data *data; + ++ obj = amdgpu_ras_find_obj(adev, &info->head); + if (!obj) + return -EINVAL; + ++ data = &obj->ih_data; ++ + if (data->inuse == 0) + return 0; + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c +index 96857ae7fb5bc..ff4f52e07cc0d 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c +@@ -1003,6 +1003,9 @@ static u32 amdgpu_virt_rlcg_reg_rw(struct amdgpu_device *adev, u32 offset, u32 v + scratch_reg1 = (void __iomem *)adev->rmmio + 4 * reg_access_ctrl->scratch_reg1; + scratch_reg2 = (void __iomem *)adev->rmmio + 4 * reg_access_ctrl->scratch_reg2; + scratch_reg3 = (void __iomem *)adev->rmmio + 4 * reg_access_ctrl->scratch_reg3; ++ ++ mutex_lock(&adev->virt.rlcg_reg_lock); ++ + if (reg_access_ctrl->spare_int) + spare_int = (void __iomem *)adev->rmmio + 4 * reg_access_ctrl->spare_int; + +@@ -1058,6 +1061,9 @@ static u32 amdgpu_virt_rlcg_reg_rw(struct amdgpu_device *adev, u32 offset, u32 v + } + + ret = readl(scratch_reg0); ++ ++ mutex_unlock(&adev->virt.rlcg_reg_lock); ++ + return ret; + } + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h +index fabb83e9d9aec..23b6efa9d25df 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h +@@ -263,6 +263,8 @@ struct amdgpu_virt { + + /* the ucode id to signal the autoload */ + uint32_t autoload_ucode_id; ++ ++ struct mutex rlcg_reg_lock; + }; + + struct amdgpu_video_codec_info; +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_sdma.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_sdma.c +index 349416e176a12..1cf1498204678 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_sdma.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_sdma.c +@@ -102,6 +102,11 @@ static int amdgpu_vm_sdma_prepare(struct amdgpu_vm_update_params *p, + if (!r) + r = amdgpu_sync_push_to_job(&sync, p->job); + amdgpu_sync_free(&sync); ++ ++ if (r) { ++ p->num_dw_left = 0; ++ amdgpu_job_free(p->job); ++ } + return r; + } + +diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +index 60db3800666ec..94059aef762be 100644 +--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c ++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +@@ -2628,7 +2628,8 @@ static int dm_suspend(void *handle) + + dm->cached_dc_state = dc_copy_state(dm->dc->current_state); + +- dm_gpureset_toggle_interrupts(adev, dm->cached_dc_state, false); ++ if (dm->cached_dc_state) ++ dm_gpureset_toggle_interrupts(adev, dm->cached_dc_state, false); + + amdgpu_dm_commit_zero_streams(dm->dc); + +@@ -6483,7 +6484,8 @@ static void create_eml_sink(struct amdgpu_dm_connector *aconnector) + aconnector->dc_sink = aconnector->dc_link->local_sink ? + aconnector->dc_link->local_sink : + aconnector->dc_em_sink; +- dc_sink_retain(aconnector->dc_sink); ++ if (aconnector->dc_sink) ++ dc_sink_retain(aconnector->dc_sink); + } + } + +@@ -7296,7 +7298,8 @@ static int amdgpu_dm_connector_get_modes(struct drm_connector *connector) + drm_add_modes_noedid(connector, 1920, 1080); + } else { + amdgpu_dm_connector_ddc_get_modes(connector, edid); +- amdgpu_dm_connector_add_common_modes(encoder, connector); ++ if (encoder) ++ amdgpu_dm_connector_add_common_modes(encoder, connector); + amdgpu_dm_connector_add_freesync_modes(connector, edid); + } + amdgpu_dm_fbc_init(connector); +diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c +index 2104511f3b863..3880ddf1c820f 100644 +--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c ++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c +@@ -1266,6 +1266,9 @@ static bool is_dsc_need_re_compute( + } + } + ++ if (new_stream_on_link_num == 0) ++ return false; ++ + /* check current_state if there stream on link but it is not in + * new request state + */ +diff --git a/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_hpo_fixed_vs_pe_retimer_dp.c b/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_hpo_fixed_vs_pe_retimer_dp.c +index b621b97711b61..a7f5b0f6272ce 100644 +--- a/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_hpo_fixed_vs_pe_retimer_dp.c ++++ b/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_hpo_fixed_vs_pe_retimer_dp.c +@@ -162,7 +162,12 @@ static void set_hpo_fixed_vs_pe_retimer_dp_link_test_pattern(struct dc_link *lin + link_res->hpo_dp_link_enc->funcs->set_link_test_pattern( + link_res->hpo_dp_link_enc, tp_params); + } ++ + link->dc->link_srv->dp_trace_source_sequence(link, DPCD_SOURCE_SEQ_AFTER_SET_SOURCE_PATTERN); ++ ++ // Give retimer extra time to lock before updating DP_TRAINING_PATTERN_SET to TPS1 ++ if (tp_params->dp_phy_pattern == DP_TEST_PATTERN_128b_132b_TPS1_TRAINING_MODE) ++ msleep(30); + } + + static void set_hpo_fixed_vs_pe_retimer_dp_lane_settings(struct dc_link *link, +diff --git a/drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c b/drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c +index 9e4f8a4104a34..7bf46e4974f88 100644 +--- a/drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c ++++ b/drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c +@@ -927,7 +927,7 @@ static int pp_dpm_switch_power_profile(void *handle, + enum PP_SMC_POWER_PROFILE type, bool en) + { + struct pp_hwmgr *hwmgr = handle; +- long workload; ++ long workload[1]; + uint32_t index; + + if (!hwmgr || !hwmgr->pm_en) +@@ -945,12 +945,12 @@ static int pp_dpm_switch_power_profile(void *handle, + hwmgr->workload_mask &= ~(1 << hwmgr->workload_prority[type]); + index = fls(hwmgr->workload_mask); + index = index > 0 && index <= Workload_Policy_Max ? index - 1 : 0; +- workload = hwmgr->workload_setting[index]; ++ workload[0] = hwmgr->workload_setting[index]; + } else { + hwmgr->workload_mask |= (1 << hwmgr->workload_prority[type]); + index = fls(hwmgr->workload_mask); + index = index <= Workload_Policy_Max ? index - 1 : 0; +- workload = hwmgr->workload_setting[index]; ++ workload[0] = hwmgr->workload_setting[index]; + } + + if (type == PP_SMC_POWER_PROFILE_COMPUTE && +@@ -960,7 +960,7 @@ static int pp_dpm_switch_power_profile(void *handle, + } + + if (hwmgr->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL) +- hwmgr->hwmgr_func->set_power_profile_mode(hwmgr, &workload, 0); ++ hwmgr->hwmgr_func->set_power_profile_mode(hwmgr, workload, 0); + + return 0; + } +diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/pp_psm.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/pp_psm.c +index 1d829402cd2e2..f4bd8e9357e22 100644 +--- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/pp_psm.c ++++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/pp_psm.c +@@ -269,7 +269,7 @@ int psm_adjust_power_state_dynamic(struct pp_hwmgr *hwmgr, bool skip_display_set + struct pp_power_state *new_ps) + { + uint32_t index; +- long workload; ++ long workload[1]; + + if (hwmgr->not_vf) { + if (!skip_display_settings) +@@ -294,10 +294,10 @@ int psm_adjust_power_state_dynamic(struct pp_hwmgr *hwmgr, bool skip_display_set + if (hwmgr->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL) { + index = fls(hwmgr->workload_mask); + index = index > 0 && index <= Workload_Policy_Max ? index - 1 : 0; +- workload = hwmgr->workload_setting[index]; ++ workload[0] = hwmgr->workload_setting[index]; + +- if (hwmgr->power_profile_mode != workload && hwmgr->hwmgr_func->set_power_profile_mode) +- hwmgr->hwmgr_func->set_power_profile_mode(hwmgr, &workload, 0); ++ if (hwmgr->power_profile_mode != workload[0] && hwmgr->hwmgr_func->set_power_profile_mode) ++ hwmgr->hwmgr_func->set_power_profile_mode(hwmgr, workload, 0); + } + + return 0; +diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c +index aa91730e4eaff..163864bd51c34 100644 +--- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c ++++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c +@@ -2957,6 +2957,7 @@ static int smu7_update_edc_leakage_table(struct pp_hwmgr *hwmgr) + + static int smu7_hwmgr_backend_init(struct pp_hwmgr *hwmgr) + { ++ struct amdgpu_device *adev = hwmgr->adev; + struct smu7_hwmgr *data; + int result = 0; + +@@ -2993,40 +2994,37 @@ static int smu7_hwmgr_backend_init(struct pp_hwmgr *hwmgr) + /* Initalize Dynamic State Adjustment Rule Settings */ + result = phm_initializa_dynamic_state_adjustment_rule_settings(hwmgr); + +- if (0 == result) { +- struct amdgpu_device *adev = hwmgr->adev; ++ if (result) ++ goto fail; + +- data->is_tlu_enabled = false; ++ data->is_tlu_enabled = false; + +- hwmgr->platform_descriptor.hardwareActivityPerformanceLevels = ++ hwmgr->platform_descriptor.hardwareActivityPerformanceLevels = + SMU7_MAX_HARDWARE_POWERLEVELS; +- hwmgr->platform_descriptor.hardwarePerformanceLevels = 2; +- hwmgr->platform_descriptor.minimumClocksReductionPercentage = 50; ++ hwmgr->platform_descriptor.hardwarePerformanceLevels = 2; ++ hwmgr->platform_descriptor.minimumClocksReductionPercentage = 50; + +- data->pcie_gen_cap = adev->pm.pcie_gen_mask; +- if (data->pcie_gen_cap & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3) +- data->pcie_spc_cap = 20; +- else +- data->pcie_spc_cap = 16; +- data->pcie_lane_cap = adev->pm.pcie_mlw_mask; +- +- hwmgr->platform_descriptor.vbiosInterruptId = 0x20000400; /* IRQ_SOURCE1_SW_INT */ +-/* The true clock step depends on the frequency, typically 4.5 or 9 MHz. Here we use 5. */ +- hwmgr->platform_descriptor.clockStep.engineClock = 500; +- hwmgr->platform_descriptor.clockStep.memoryClock = 500; +- smu7_thermal_parameter_init(hwmgr); +- } else { +- /* Ignore return value in here, we are cleaning up a mess. */ +- smu7_hwmgr_backend_fini(hwmgr); +- } ++ data->pcie_gen_cap = adev->pm.pcie_gen_mask; ++ if (data->pcie_gen_cap & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3) ++ data->pcie_spc_cap = 20; ++ else ++ data->pcie_spc_cap = 16; ++ data->pcie_lane_cap = adev->pm.pcie_mlw_mask; ++ ++ hwmgr->platform_descriptor.vbiosInterruptId = 0x20000400; /* IRQ_SOURCE1_SW_INT */ ++ /* The true clock step depends on the frequency, typically 4.5 or 9 MHz. Here we use 5. */ ++ hwmgr->platform_descriptor.clockStep.engineClock = 500; ++ hwmgr->platform_descriptor.clockStep.memoryClock = 500; ++ smu7_thermal_parameter_init(hwmgr); + + result = smu7_update_edc_leakage_table(hwmgr); +- if (result) { +- smu7_hwmgr_backend_fini(hwmgr); +- return result; +- } ++ if (result) ++ goto fail; + + return 0; ++fail: ++ smu7_hwmgr_backend_fini(hwmgr); ++ return result; + } + + static int smu7_force_dpm_highest(struct pp_hwmgr *hwmgr) +@@ -3316,8 +3314,7 @@ static int smu7_apply_state_adjust_rules(struct pp_hwmgr *hwmgr, + const struct pp_power_state *current_ps) + { + struct amdgpu_device *adev = hwmgr->adev; +- struct smu7_power_state *smu7_ps = +- cast_phw_smu7_power_state(&request_ps->hardware); ++ struct smu7_power_state *smu7_ps; + uint32_t sclk; + uint32_t mclk; + struct PP_Clocks minimum_clocks = {0}; +@@ -3334,6 +3331,10 @@ static int smu7_apply_state_adjust_rules(struct pp_hwmgr *hwmgr, + uint32_t latency; + bool latency_allowed = false; + ++ smu7_ps = cast_phw_smu7_power_state(&request_ps->hardware); ++ if (!smu7_ps) ++ return -EINVAL; ++ + data->battery_state = (PP_StateUILabel_Battery == + request_ps->classification.ui_label); + data->mclk_ignore_signal = false; +diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu8_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu8_hwmgr.c +index b015a601b385a..eb744401e0567 100644 +--- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu8_hwmgr.c ++++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu8_hwmgr.c +@@ -1065,16 +1065,18 @@ static int smu8_apply_state_adjust_rules(struct pp_hwmgr *hwmgr, + struct pp_power_state *prequest_ps, + const struct pp_power_state *pcurrent_ps) + { +- struct smu8_power_state *smu8_ps = +- cast_smu8_power_state(&prequest_ps->hardware); +- +- const struct smu8_power_state *smu8_current_ps = +- cast_const_smu8_power_state(&pcurrent_ps->hardware); +- ++ struct smu8_power_state *smu8_ps; ++ const struct smu8_power_state *smu8_current_ps; + struct smu8_hwmgr *data = hwmgr->backend; + struct PP_Clocks clocks = {0, 0, 0, 0}; + bool force_high; + ++ smu8_ps = cast_smu8_power_state(&prequest_ps->hardware); ++ smu8_current_ps = cast_const_smu8_power_state(&pcurrent_ps->hardware); ++ ++ if (!smu8_ps || !smu8_current_ps) ++ return -EINVAL; ++ + smu8_ps->need_dfs_bypass = true; + + data->battery_state = (PP_StateUILabel_Battery == prequest_ps->classification.ui_label); +diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c +index 6d6bc6a380b36..d43a530aba0e3 100644 +--- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c ++++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c +@@ -3259,8 +3259,7 @@ static int vega10_apply_state_adjust_rules(struct pp_hwmgr *hwmgr, + const struct pp_power_state *current_ps) + { + struct amdgpu_device *adev = hwmgr->adev; +- struct vega10_power_state *vega10_ps = +- cast_phw_vega10_power_state(&request_ps->hardware); ++ struct vega10_power_state *vega10_ps; + uint32_t sclk; + uint32_t mclk; + struct PP_Clocks minimum_clocks = {0}; +@@ -3278,6 +3277,10 @@ static int vega10_apply_state_adjust_rules(struct pp_hwmgr *hwmgr, + uint32_t stable_pstate_sclk = 0, stable_pstate_mclk = 0; + uint32_t latency; + ++ vega10_ps = cast_phw_vega10_power_state(&request_ps->hardware); ++ if (!vega10_ps) ++ return -EINVAL; ++ + data->battery_state = (PP_StateUILabel_Battery == + request_ps->classification.ui_label); + +@@ -3415,13 +3418,17 @@ static int vega10_find_dpm_states_clocks_in_dpm_table(struct pp_hwmgr *hwmgr, co + const struct vega10_power_state *vega10_ps = + cast_const_phw_vega10_power_state(states->pnew_state); + struct vega10_single_dpm_table *sclk_table = &(data->dpm_table.gfx_table); +- uint32_t sclk = vega10_ps->performance_levels +- [vega10_ps->performance_level_count - 1].gfx_clock; + struct vega10_single_dpm_table *mclk_table = &(data->dpm_table.mem_table); +- uint32_t mclk = vega10_ps->performance_levels +- [vega10_ps->performance_level_count - 1].mem_clock; ++ uint32_t sclk, mclk; + uint32_t i; + ++ if (vega10_ps == NULL) ++ return -EINVAL; ++ sclk = vega10_ps->performance_levels ++ [vega10_ps->performance_level_count - 1].gfx_clock; ++ mclk = vega10_ps->performance_levels ++ [vega10_ps->performance_level_count - 1].mem_clock; ++ + for (i = 0; i < sclk_table->count; i++) { + if (sclk == sclk_table->dpm_levels[i].value) + break; +@@ -3728,6 +3735,9 @@ static int vega10_generate_dpm_level_enable_mask( + cast_const_phw_vega10_power_state(states->pnew_state); + int i; + ++ if (vega10_ps == NULL) ++ return -EINVAL; ++ + PP_ASSERT_WITH_CODE(!vega10_trim_dpm_states(hwmgr, vega10_ps), + "Attempt to Trim DPM States Failed!", + return -1); +@@ -4995,6 +5005,8 @@ static int vega10_check_states_equal(struct pp_hwmgr *hwmgr, + + vega10_psa = cast_const_phw_vega10_power_state(pstate1); + vega10_psb = cast_const_phw_vega10_power_state(pstate2); ++ if (vega10_psa == NULL || vega10_psb == NULL) ++ return -EINVAL; + + /* If the two states don't even have the same number of performance levels + * they cannot be the same state. +@@ -5128,6 +5140,8 @@ static int vega10_set_sclk_od(struct pp_hwmgr *hwmgr, uint32_t value) + return -EINVAL; + + vega10_ps = cast_phw_vega10_power_state(&ps->hardware); ++ if (vega10_ps == NULL) ++ return -EINVAL; + + vega10_ps->performance_levels + [vega10_ps->performance_level_count - 1].gfx_clock = +@@ -5179,6 +5193,8 @@ static int vega10_set_mclk_od(struct pp_hwmgr *hwmgr, uint32_t value) + return -EINVAL; + + vega10_ps = cast_phw_vega10_power_state(&ps->hardware); ++ if (vega10_ps == NULL) ++ return -EINVAL; + + vega10_ps->performance_levels + [vega10_ps->performance_level_count - 1].mem_clock = +@@ -5420,6 +5436,9 @@ static void vega10_odn_update_power_state(struct pp_hwmgr *hwmgr) + return; + + vega10_ps = cast_phw_vega10_power_state(&ps->hardware); ++ if (vega10_ps == NULL) ++ return; ++ + max_level = vega10_ps->performance_level_count - 1; + + if (vega10_ps->performance_levels[max_level].gfx_clock != +@@ -5442,6 +5461,9 @@ static void vega10_odn_update_power_state(struct pp_hwmgr *hwmgr) + + ps = (struct pp_power_state *)((unsigned long)(hwmgr->ps) + hwmgr->ps_size * (hwmgr->num_ps - 1)); + vega10_ps = cast_phw_vega10_power_state(&ps->hardware); ++ if (vega10_ps == NULL) ++ return; ++ + max_level = vega10_ps->performance_level_count - 1; + + if (vega10_ps->performance_levels[max_level].gfx_clock != +@@ -5632,6 +5654,8 @@ static int vega10_get_performance_level(struct pp_hwmgr *hwmgr, const struct pp_ + return -EINVAL; + + vega10_ps = cast_const_phw_vega10_power_state(state); ++ if (vega10_ps == NULL) ++ return -EINVAL; + + i = index > vega10_ps->performance_level_count - 1 ? + vega10_ps->performance_level_count - 1 : index; +diff --git a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c +index 56e4c312cb7a9..1402e468aa90f 100644 +--- a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c ++++ b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c +@@ -1846,7 +1846,7 @@ static int smu_adjust_power_state_dynamic(struct smu_context *smu, + { + int ret = 0; + int index = 0; +- long workload; ++ long workload[1]; + struct smu_dpm_context *smu_dpm_ctx = &(smu->smu_dpm); + + if (!skip_display_settings) { +@@ -1886,10 +1886,10 @@ static int smu_adjust_power_state_dynamic(struct smu_context *smu, + smu_dpm_ctx->dpm_level != AMD_DPM_FORCED_LEVEL_PERF_DETERMINISM) { + index = fls(smu->workload_mask); + index = index > 0 && index <= WORKLOAD_POLICY_MAX ? index - 1 : 0; +- workload = smu->workload_setting[index]; ++ workload[0] = smu->workload_setting[index]; + +- if (smu->power_profile_mode != workload) +- smu_bump_power_profile_mode(smu, &workload, 0); ++ if (smu->power_profile_mode != workload[0]) ++ smu_bump_power_profile_mode(smu, workload, 0); + } + + return ret; +@@ -1939,7 +1939,7 @@ static int smu_switch_power_profile(void *handle, + { + struct smu_context *smu = handle; + struct smu_dpm_context *smu_dpm_ctx = &(smu->smu_dpm); +- long workload; ++ long workload[1]; + uint32_t index; + + if (!smu->pm_enabled || !smu->adev->pm.dpm_enabled) +@@ -1952,17 +1952,17 @@ static int smu_switch_power_profile(void *handle, + smu->workload_mask &= ~(1 << smu->workload_prority[type]); + index = fls(smu->workload_mask); + index = index > 0 && index <= WORKLOAD_POLICY_MAX ? index - 1 : 0; +- workload = smu->workload_setting[index]; ++ workload[0] = smu->workload_setting[index]; + } else { + smu->workload_mask |= (1 << smu->workload_prority[type]); + index = fls(smu->workload_mask); + index = index <= WORKLOAD_POLICY_MAX ? index - 1 : 0; +- workload = smu->workload_setting[index]; ++ workload[0] = smu->workload_setting[index]; + } + + if (smu_dpm_ctx->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL && + smu_dpm_ctx->dpm_level != AMD_DPM_FORCED_LEVEL_PERF_DETERMINISM) +- smu_bump_power_profile_mode(smu, &workload, 0); ++ smu_bump_power_profile_mode(smu, workload, 0); + + return 0; + } +diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c +index 6a4f20fccf841..7b0bc9704eacb 100644 +--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c ++++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c +@@ -1027,7 +1027,6 @@ ssize_t analogix_dp_transfer(struct analogix_dp_device *dp, + u32 status_reg; + u8 *buffer = msg->buffer; + unsigned int i; +- int num_transferred = 0; + int ret; + + /* Buffer size of AUX CH is 16 bytes */ +@@ -1079,7 +1078,6 @@ ssize_t analogix_dp_transfer(struct analogix_dp_device *dp, + reg = buffer[i]; + writel(reg, dp->reg_base + ANALOGIX_DP_BUF_DATA_0 + + 4 * i); +- num_transferred++; + } + } + +@@ -1127,7 +1125,6 @@ ssize_t analogix_dp_transfer(struct analogix_dp_device *dp, + reg = readl(dp->reg_base + ANALOGIX_DP_BUF_DATA_0 + + 4 * i); + buffer[i] = (unsigned char)reg; +- num_transferred++; + } + } + +@@ -1144,7 +1141,7 @@ ssize_t analogix_dp_transfer(struct analogix_dp_device *dp, + (msg->request & ~DP_AUX_I2C_MOT) == DP_AUX_NATIVE_READ) + msg->reply = DP_AUX_NATIVE_REPLY_ACK; + +- return num_transferred > 0 ? num_transferred : -EBUSY; ++ return msg->size; + + aux_error: + /* if aux err happen, reset aux */ +diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c b/drivers/gpu/drm/display/drm_dp_mst_topology.c +index 9023c0216a8a4..6ead31701e79e 100644 +--- a/drivers/gpu/drm/display/drm_dp_mst_topology.c ++++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c +@@ -4024,6 +4024,7 @@ static int drm_dp_mst_handle_up_req(struct drm_dp_mst_topology_mgr *mgr) + if (up_req->msg.req_type == DP_CONNECTION_STATUS_NOTIFY) { + const struct drm_dp_connection_status_notify *conn_stat = + &up_req->msg.u.conn_stat; ++ bool handle_csn; + + drm_dbg_kms(mgr->dev, "Got CSN: pn: %d ldps:%d ddps: %d mcs: %d ip: %d pdt: %d\n", + conn_stat->port_number, +@@ -4032,6 +4033,16 @@ static int drm_dp_mst_handle_up_req(struct drm_dp_mst_topology_mgr *mgr) + conn_stat->message_capability_status, + conn_stat->input_port, + conn_stat->peer_device_type); ++ ++ mutex_lock(&mgr->probe_lock); ++ handle_csn = mgr->mst_primary->link_address_sent; ++ mutex_unlock(&mgr->probe_lock); ++ ++ if (!handle_csn) { ++ drm_dbg_kms(mgr->dev, "Got CSN before finish topology probing. Skip it."); ++ kfree(up_req); ++ goto out; ++ } + } else if (up_req->msg.req_type == DP_RESOURCE_STATUS_NOTIFY) { + const struct drm_dp_resource_status_notify *res_stat = + &up_req->msg.u.resource_stat; +diff --git a/drivers/gpu/drm/drm_client_modeset.c b/drivers/gpu/drm/drm_client_modeset.c +index 0683a129b3628..51df7244de718 100644 +--- a/drivers/gpu/drm/drm_client_modeset.c ++++ b/drivers/gpu/drm/drm_client_modeset.c +@@ -869,6 +869,11 @@ int drm_client_modeset_probe(struct drm_client_dev *client, unsigned int width, + + kfree(modeset->mode); + modeset->mode = drm_mode_duplicate(dev, mode); ++ if (!modeset->mode) { ++ ret = -ENOMEM; ++ break; ++ } ++ + drm_connector_get(connector); + modeset->connectors[modeset->num_connectors++] = connector; + modeset->x = offset->x; +diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.c b/drivers/gpu/drm/i915/gem/i915_gem_mman.c +index 310654542b42c..a59c17ec7fa36 100644 +--- a/drivers/gpu/drm/i915/gem/i915_gem_mman.c ++++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.c +@@ -290,6 +290,41 @@ static vm_fault_t vm_fault_cpu(struct vm_fault *vmf) + return i915_error_to_vmf_fault(err); + } + ++static void set_address_limits(struct vm_area_struct *area, ++ struct i915_vma *vma, ++ unsigned long obj_offset, ++ unsigned long *start_vaddr, ++ unsigned long *end_vaddr) ++{ ++ unsigned long vm_start, vm_end, vma_size; /* user's memory parameters */ ++ long start, end; /* memory boundaries */ ++ ++ /* ++ * Let's move into the ">> PAGE_SHIFT" ++ * domain to be sure not to lose bits ++ */ ++ vm_start = area->vm_start >> PAGE_SHIFT; ++ vm_end = area->vm_end >> PAGE_SHIFT; ++ vma_size = vma->size >> PAGE_SHIFT; ++ ++ /* ++ * Calculate the memory boundaries by considering the offset ++ * provided by the user during memory mapping and the offset ++ * provided for the partial mapping. ++ */ ++ start = vm_start; ++ start -= obj_offset; ++ start += vma->gtt_view.partial.offset; ++ end = start + vma_size; ++ ++ start = max_t(long, start, vm_start); ++ end = min_t(long, end, vm_end); ++ ++ /* Let's move back into the "<< PAGE_SHIFT" domain */ ++ *start_vaddr = (unsigned long)start << PAGE_SHIFT; ++ *end_vaddr = (unsigned long)end << PAGE_SHIFT; ++} ++ + static vm_fault_t vm_fault_gtt(struct vm_fault *vmf) + { + #define MIN_CHUNK_PAGES (SZ_1M >> PAGE_SHIFT) +@@ -302,14 +337,18 @@ static vm_fault_t vm_fault_gtt(struct vm_fault *vmf) + struct i915_ggtt *ggtt = to_gt(i915)->ggtt; + bool write = area->vm_flags & VM_WRITE; + struct i915_gem_ww_ctx ww; ++ unsigned long obj_offset; ++ unsigned long start, end; /* memory boundaries */ + intel_wakeref_t wakeref; + struct i915_vma *vma; + pgoff_t page_offset; ++ unsigned long pfn; + int srcu; + int ret; + +- /* We don't use vmf->pgoff since that has the fake offset */ ++ obj_offset = area->vm_pgoff - drm_vma_node_start(&mmo->vma_node); + page_offset = (vmf->address - area->vm_start) >> PAGE_SHIFT; ++ page_offset += obj_offset; + + trace_i915_gem_object_fault(obj, page_offset, true, write); + +@@ -402,12 +441,14 @@ static vm_fault_t vm_fault_gtt(struct vm_fault *vmf) + if (ret) + goto err_unpin; + ++ set_address_limits(area, vma, obj_offset, &start, &end); ++ ++ pfn = (ggtt->gmadr.start + i915_ggtt_offset(vma)) >> PAGE_SHIFT; ++ pfn += (start - area->vm_start) >> PAGE_SHIFT; ++ pfn += obj_offset - vma->gtt_view.partial.offset; ++ + /* Finally, remap it using the new GTT offset */ +- ret = remap_io_mapping(area, +- area->vm_start + (vma->gtt_view.partial.offset << PAGE_SHIFT), +- (ggtt->gmadr.start + i915_ggtt_offset(vma)) >> PAGE_SHIFT, +- min_t(u64, vma->size, area->vm_end - area->vm_start), +- &ggtt->iomap); ++ ret = remap_io_mapping(area, start, pfn, end - start, &ggtt->iomap); + if (ret) + goto err_fence; + +@@ -1088,6 +1129,8 @@ int i915_gem_fb_mmap(struct drm_i915_gem_object *obj, struct vm_area_struct *vma + mmo = mmap_offset_attach(obj, mmap_type, NULL); + if (IS_ERR(mmo)) + return PTR_ERR(mmo); ++ ++ vma->vm_pgoff += drm_vma_node_start(&mmo->vma_node); + } + + /* +diff --git a/drivers/gpu/drm/lima/lima_drv.c b/drivers/gpu/drm/lima/lima_drv.c +index 10fd9154cc465..8c9b656eeb59d 100644 +--- a/drivers/gpu/drm/lima/lima_drv.c ++++ b/drivers/gpu/drm/lima/lima_drv.c +@@ -486,3 +486,4 @@ module_platform_driver(lima_platform_driver); + MODULE_AUTHOR("Lima Project Developers"); + MODULE_DESCRIPTION("Lima DRM Driver"); + MODULE_LICENSE("GPL v2"); ++MODULE_SOFTDEP("pre: governor_simpleondemand"); +diff --git a/drivers/gpu/drm/mgag200/mgag200_i2c.c b/drivers/gpu/drm/mgag200/mgag200_i2c.c +index 0c48bdf3e7f80..f5c5d06d0d4bb 100644 +--- a/drivers/gpu/drm/mgag200/mgag200_i2c.c ++++ b/drivers/gpu/drm/mgag200/mgag200_i2c.c +@@ -31,6 +31,8 @@ + #include <linux/i2c.h> + #include <linux/pci.h> + ++#include <drm/drm_managed.h> ++ + #include "mgag200_drv.h" + + static int mga_i2c_read_gpio(struct mga_device *mdev) +@@ -86,7 +88,7 @@ static int mga_gpio_getscl(void *data) + return (mga_i2c_read_gpio(mdev) & i2c->clock) ? 1 : 0; + } + +-static void mgag200_i2c_release(void *res) ++static void mgag200_i2c_release(struct drm_device *dev, void *res) + { + struct mga_i2c_chan *i2c = res; + +@@ -115,7 +117,7 @@ int mgag200_i2c_init(struct mga_device *mdev, struct mga_i2c_chan *i2c) + i2c->adapter.algo_data = &i2c->bit; + + i2c->bit.udelay = 10; +- i2c->bit.timeout = 2; ++ i2c->bit.timeout = usecs_to_jiffies(2200); + i2c->bit.data = i2c; + i2c->bit.setsda = mga_gpio_setsda; + i2c->bit.setscl = mga_gpio_setscl; +@@ -126,5 +128,5 @@ int mgag200_i2c_init(struct mga_device *mdev, struct mga_i2c_chan *i2c) + if (ret) + return ret; + +- return devm_add_action_or_reset(dev->dev, mgag200_i2c_release, i2c); ++ return drmm_add_action_or_reset(dev, mgag200_i2c_release, i2c); + } +diff --git a/drivers/gpu/drm/nouveau/nouveau_uvmm.c b/drivers/gpu/drm/nouveau/nouveau_uvmm.c +index 2bbcdc649e862..3d41e590d4712 100644 +--- a/drivers/gpu/drm/nouveau/nouveau_uvmm.c ++++ b/drivers/gpu/drm/nouveau/nouveau_uvmm.c +@@ -1320,6 +1320,7 @@ nouveau_uvmm_bind_job_submit(struct nouveau_job *job) + + drm_gpuva_for_each_op(va_op, op->ops) { + struct drm_gem_object *obj = op_gem_obj(va_op); ++ struct nouveau_bo *nvbo; + + if (unlikely(!obj)) + continue; +@@ -1330,8 +1331,9 @@ nouveau_uvmm_bind_job_submit(struct nouveau_job *job) + if (unlikely(va_op->op == DRM_GPUVA_OP_UNMAP)) + continue; + +- ret = nouveau_bo_validate(nouveau_gem_object(obj), +- true, false); ++ nvbo = nouveau_gem_object(obj); ++ nouveau_bo_placement_set(nvbo, nvbo->valid_domains, 0); ++ ret = nouveau_bo_validate(nvbo, true, false); + if (ret) { + op = list_last_op(&bind_job->ops); + goto unwind; +diff --git a/drivers/gpu/drm/radeon/pptable.h b/drivers/gpu/drm/radeon/pptable.h +index 844f0490bf31f..ce8832916704f 100644 +--- a/drivers/gpu/drm/radeon/pptable.h ++++ b/drivers/gpu/drm/radeon/pptable.h +@@ -439,7 +439,7 @@ typedef struct _StateArray{ + //how many states we have + UCHAR ucNumEntries; + +- ATOM_PPLIB_STATE_V2 states[] __counted_by(ucNumEntries); ++ ATOM_PPLIB_STATE_V2 states[] /* __counted_by(ucNumEntries) */; + }StateArray; + + +diff --git a/drivers/hwmon/corsair-psu.c b/drivers/hwmon/corsair-psu.c +index 2c7c92272fe39..f8f22b8a67cdf 100644 +--- a/drivers/hwmon/corsair-psu.c ++++ b/drivers/hwmon/corsair-psu.c +@@ -875,15 +875,16 @@ static const struct hid_device_id corsairpsu_idtable[] = { + { HID_USB_DEVICE(0x1b1c, 0x1c04) }, /* Corsair HX650i */ + { HID_USB_DEVICE(0x1b1c, 0x1c05) }, /* Corsair HX750i */ + { HID_USB_DEVICE(0x1b1c, 0x1c06) }, /* Corsair HX850i */ +- { HID_USB_DEVICE(0x1b1c, 0x1c07) }, /* Corsair HX1000i Series 2022 */ +- { HID_USB_DEVICE(0x1b1c, 0x1c08) }, /* Corsair HX1200i */ ++ { HID_USB_DEVICE(0x1b1c, 0x1c07) }, /* Corsair HX1000i Legacy */ ++ { HID_USB_DEVICE(0x1b1c, 0x1c08) }, /* Corsair HX1200i Legacy */ + { HID_USB_DEVICE(0x1b1c, 0x1c09) }, /* Corsair RM550i */ + { HID_USB_DEVICE(0x1b1c, 0x1c0a) }, /* Corsair RM650i */ + { HID_USB_DEVICE(0x1b1c, 0x1c0b) }, /* Corsair RM750i */ + { HID_USB_DEVICE(0x1b1c, 0x1c0c) }, /* Corsair RM850i */ + { HID_USB_DEVICE(0x1b1c, 0x1c0d) }, /* Corsair RM1000i */ + { HID_USB_DEVICE(0x1b1c, 0x1c1e) }, /* Corsair HX1000i Series 2023 */ +- { HID_USB_DEVICE(0x1b1c, 0x1c1f) }, /* Corsair HX1500i Series 2022 and 2023 */ ++ { HID_USB_DEVICE(0x1b1c, 0x1c1f) }, /* Corsair HX1500i Legacy and Series 2023 */ ++ { HID_USB_DEVICE(0x1b1c, 0x1c23) }, /* Corsair HX1200i Series 2023 */ + { }, + }; + MODULE_DEVICE_TABLE(hid, corsairpsu_idtable); +diff --git a/drivers/i2c/busses/i2c-qcom-geni.c b/drivers/i2c/busses/i2c-qcom-geni.c +index 5cc32a465f12e..b17411e97be68 100644 +--- a/drivers/i2c/busses/i2c-qcom-geni.c ++++ b/drivers/i2c/busses/i2c-qcom-geni.c +@@ -991,8 +991,11 @@ static int __maybe_unused geni_i2c_runtime_resume(struct device *dev) + return ret; + + ret = geni_se_resources_on(&gi2c->se); +- if (ret) ++ if (ret) { ++ clk_disable_unprepare(gi2c->core_clk); ++ geni_icc_disable(&gi2c->se); + return ret; ++ } + + enable_irq(gi2c->irq); + gi2c->suspended = 0; +diff --git a/drivers/i2c/i2c-smbus.c b/drivers/i2c/i2c-smbus.c +index 138c3f5e0093a..6520e09743912 100644 +--- a/drivers/i2c/i2c-smbus.c ++++ b/drivers/i2c/i2c-smbus.c +@@ -34,6 +34,7 @@ static int smbus_do_alert(struct device *dev, void *addrp) + struct i2c_client *client = i2c_verify_client(dev); + struct alert_data *data = addrp; + struct i2c_driver *driver; ++ int ret; + + if (!client || client->addr != data->addr) + return 0; +@@ -47,16 +48,47 @@ static int smbus_do_alert(struct device *dev, void *addrp) + device_lock(dev); + if (client->dev.driver) { + driver = to_i2c_driver(client->dev.driver); +- if (driver->alert) ++ if (driver->alert) { ++ /* Stop iterating after we find the device */ + driver->alert(client, data->type, data->data); +- else ++ ret = -EBUSY; ++ } else { + dev_warn(&client->dev, "no driver alert()!\n"); +- } else ++ ret = -EOPNOTSUPP; ++ } ++ } else { + dev_dbg(&client->dev, "alert with no driver\n"); ++ ret = -ENODEV; ++ } ++ device_unlock(dev); ++ ++ return ret; ++} ++ ++/* Same as above, but call back all drivers with alert handler */ ++ ++static int smbus_do_alert_force(struct device *dev, void *addrp) ++{ ++ struct i2c_client *client = i2c_verify_client(dev); ++ struct alert_data *data = addrp; ++ struct i2c_driver *driver; ++ ++ if (!client || (client->flags & I2C_CLIENT_TEN)) ++ return 0; ++ ++ /* ++ * Drivers should either disable alerts, or provide at least ++ * a minimal handler. Lock so the driver won't change. ++ */ ++ device_lock(dev); ++ if (client->dev.driver) { ++ driver = to_i2c_driver(client->dev.driver); ++ if (driver->alert) ++ driver->alert(client, data->type, data->data); ++ } + device_unlock(dev); + +- /* Stop iterating after we find the device */ +- return -EBUSY; ++ return 0; + } + + /* +@@ -67,6 +99,7 @@ static irqreturn_t smbus_alert(int irq, void *d) + { + struct i2c_smbus_alert *alert = d; + struct i2c_client *ara; ++ unsigned short prev_addr = I2C_CLIENT_END; /* Not a valid address */ + + ara = alert->ara; + +@@ -94,8 +127,25 @@ static irqreturn_t smbus_alert(int irq, void *d) + data.addr, data.data); + + /* Notify driver for the device which issued the alert */ +- device_for_each_child(&ara->adapter->dev, &data, +- smbus_do_alert); ++ status = device_for_each_child(&ara->adapter->dev, &data, ++ smbus_do_alert); ++ /* ++ * If we read the same address more than once, and the alert ++ * was not handled by a driver, it won't do any good to repeat ++ * the loop because it will never terminate. Try again, this ++ * time calling the alert handlers of all devices connected to ++ * the bus, and abort the loop afterwards. If this helps, we ++ * are all set. If it doesn't, there is nothing else we can do, ++ * so we might as well abort the loop. ++ * Note: This assumes that a driver with alert handler handles ++ * the alert properly and clears it if necessary. ++ */ ++ if (data.addr == prev_addr && status != -EBUSY) { ++ device_for_each_child(&ara->adapter->dev, &data, ++ smbus_do_alert_force); ++ break; ++ } ++ prev_addr = data.addr; + } + + return IRQ_HANDLED; +diff --git a/drivers/irqchip/irq-loongarch-cpu.c b/drivers/irqchip/irq-loongarch-cpu.c +index 9d8f2c4060431..b35903a06902f 100644 +--- a/drivers/irqchip/irq-loongarch-cpu.c ++++ b/drivers/irqchip/irq-loongarch-cpu.c +@@ -18,11 +18,13 @@ struct fwnode_handle *cpuintc_handle; + + static u32 lpic_gsi_to_irq(u32 gsi) + { ++ int irq = 0; ++ + /* Only pch irqdomain transferring is required for LoongArch. */ + if (gsi >= GSI_MIN_PCH_IRQ && gsi <= GSI_MAX_PCH_IRQ) +- return acpi_register_gsi(NULL, gsi, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_HIGH); ++ irq = acpi_register_gsi(NULL, gsi, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_HIGH); + +- return 0; ++ return (irq > 0) ? irq : 0; + } + + static struct fwnode_handle *lpic_get_gsi_domain_id(u32 gsi) +diff --git a/drivers/irqchip/irq-mbigen.c b/drivers/irqchip/irq-mbigen.c +index 58881d3139792..244a8d489cac6 100644 +--- a/drivers/irqchip/irq-mbigen.c ++++ b/drivers/irqchip/irq-mbigen.c +@@ -64,6 +64,20 @@ struct mbigen_device { + void __iomem *base; + }; + ++static inline unsigned int get_mbigen_node_offset(unsigned int nid) ++{ ++ unsigned int offset = nid * MBIGEN_NODE_OFFSET; ++ ++ /* ++ * To avoid touched clear register in unexpected way, we need to directly ++ * skip clear register when access to more than 10 mbigen nodes. ++ */ ++ if (nid >= (REG_MBIGEN_CLEAR_OFFSET / MBIGEN_NODE_OFFSET)) ++ offset += MBIGEN_NODE_OFFSET; ++ ++ return offset; ++} ++ + static inline unsigned int get_mbigen_vec_reg(irq_hw_number_t hwirq) + { + unsigned int nid, pin; +@@ -72,8 +86,7 @@ static inline unsigned int get_mbigen_vec_reg(irq_hw_number_t hwirq) + nid = hwirq / IRQS_PER_MBIGEN_NODE + 1; + pin = hwirq % IRQS_PER_MBIGEN_NODE; + +- return pin * 4 + nid * MBIGEN_NODE_OFFSET +- + REG_MBIGEN_VEC_OFFSET; ++ return pin * 4 + get_mbigen_node_offset(nid) + REG_MBIGEN_VEC_OFFSET; + } + + static inline void get_mbigen_type_reg(irq_hw_number_t hwirq, +@@ -88,8 +101,7 @@ static inline void get_mbigen_type_reg(irq_hw_number_t hwirq, + *mask = 1 << (irq_ofst % 32); + ofst = irq_ofst / 32 * 4; + +- *addr = ofst + nid * MBIGEN_NODE_OFFSET +- + REG_MBIGEN_TYPE_OFFSET; ++ *addr = ofst + get_mbigen_node_offset(nid) + REG_MBIGEN_TYPE_OFFSET; + } + + static inline void get_mbigen_clear_reg(irq_hw_number_t hwirq, +diff --git a/drivers/irqchip/irq-meson-gpio.c b/drivers/irqchip/irq-meson-gpio.c +index f88df39f41291..471e04eaf3230 100644 +--- a/drivers/irqchip/irq-meson-gpio.c ++++ b/drivers/irqchip/irq-meson-gpio.c +@@ -173,7 +173,7 @@ struct meson_gpio_irq_controller { + void __iomem *base; + u32 channel_irqs[MAX_NUM_CHANNEL]; + DECLARE_BITMAP(channel_map, MAX_NUM_CHANNEL); +- spinlock_t lock; ++ raw_spinlock_t lock; + }; + + static void meson_gpio_irq_update_bits(struct meson_gpio_irq_controller *ctl, +@@ -182,14 +182,14 @@ static void meson_gpio_irq_update_bits(struct meson_gpio_irq_controller *ctl, + unsigned long flags; + u32 tmp; + +- spin_lock_irqsave(&ctl->lock, flags); ++ raw_spin_lock_irqsave(&ctl->lock, flags); + + tmp = readl_relaxed(ctl->base + reg); + tmp &= ~mask; + tmp |= val; + writel_relaxed(tmp, ctl->base + reg); + +- spin_unlock_irqrestore(&ctl->lock, flags); ++ raw_spin_unlock_irqrestore(&ctl->lock, flags); + } + + static void meson_gpio_irq_init_dummy(struct meson_gpio_irq_controller *ctl) +@@ -239,12 +239,12 @@ meson_gpio_irq_request_channel(struct meson_gpio_irq_controller *ctl, + unsigned long flags; + unsigned int idx; + +- spin_lock_irqsave(&ctl->lock, flags); ++ raw_spin_lock_irqsave(&ctl->lock, flags); + + /* Find a free channel */ + idx = find_first_zero_bit(ctl->channel_map, ctl->params->nr_channels); + if (idx >= ctl->params->nr_channels) { +- spin_unlock_irqrestore(&ctl->lock, flags); ++ raw_spin_unlock_irqrestore(&ctl->lock, flags); + pr_err("No channel available\n"); + return -ENOSPC; + } +@@ -252,7 +252,7 @@ meson_gpio_irq_request_channel(struct meson_gpio_irq_controller *ctl, + /* Mark the channel as used */ + set_bit(idx, ctl->channel_map); + +- spin_unlock_irqrestore(&ctl->lock, flags); ++ raw_spin_unlock_irqrestore(&ctl->lock, flags); + + /* + * Setup the mux of the channel to route the signal of the pad +@@ -562,7 +562,7 @@ static int meson_gpio_irq_of_init(struct device_node *node, struct device_node * + if (!ctl) + return -ENOMEM; + +- spin_lock_init(&ctl->lock); ++ raw_spin_lock_init(&ctl->lock); + + ctl->base = of_iomap(node, 0); + if (!ctl->base) { +diff --git a/drivers/irqchip/irq-xilinx-intc.c b/drivers/irqchip/irq-xilinx-intc.c +index 238d3d3449496..7e08714d507f4 100644 +--- a/drivers/irqchip/irq-xilinx-intc.c ++++ b/drivers/irqchip/irq-xilinx-intc.c +@@ -189,7 +189,7 @@ static int __init xilinx_intc_of_init(struct device_node *intc, + irqc->intr_mask = 0; + } + +- if (irqc->intr_mask >> irqc->nr_irq) ++ if ((u64)irqc->intr_mask >> irqc->nr_irq) + pr_warn("irq-xilinx: mismatch in kind-of-intr param\n"); + + pr_info("irq-xilinx: %pOF: num_irq=%d, edge=0x%x\n", +diff --git a/drivers/md/md.c b/drivers/md/md.c +index b5dea664f946d..35b003b83ef1b 100644 +--- a/drivers/md/md.c ++++ b/drivers/md/md.c +@@ -456,7 +456,6 @@ void mddev_suspend(struct mddev *mddev) + clear_bit_unlock(MD_ALLOW_SB_UPDATE, &mddev->flags); + wait_event(mddev->sb_wait, !test_bit(MD_UPDATING_SB, &mddev->flags)); + +- del_timer_sync(&mddev->safemode_timer); + /* restrict memory reclaim I/O during raid array is suspend */ + mddev->noio_flag = memalloc_noio_save(); + } +diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c +index 1507540a9cb4e..2c7f11e576673 100644 +--- a/drivers/md/raid5.c ++++ b/drivers/md/raid5.c +@@ -6326,7 +6326,9 @@ static sector_t reshape_request(struct mddev *mddev, sector_t sector_nr, int *sk + safepos = conf->reshape_safe; + sector_div(safepos, data_disks); + if (mddev->reshape_backwards) { +- BUG_ON(writepos < reshape_sectors); ++ if (WARN_ON(writepos < reshape_sectors)) ++ return MaxSector; ++ + writepos -= reshape_sectors; + readpos += reshape_sectors; + safepos += reshape_sectors; +@@ -6344,14 +6346,18 @@ static sector_t reshape_request(struct mddev *mddev, sector_t sector_nr, int *sk + * to set 'stripe_addr' which is where we will write to. + */ + if (mddev->reshape_backwards) { +- BUG_ON(conf->reshape_progress == 0); ++ if (WARN_ON(conf->reshape_progress == 0)) ++ return MaxSector; ++ + stripe_addr = writepos; +- BUG_ON((mddev->dev_sectors & +- ~((sector_t)reshape_sectors - 1)) +- - reshape_sectors - stripe_addr +- != sector_nr); ++ if (WARN_ON((mddev->dev_sectors & ++ ~((sector_t)reshape_sectors - 1)) - ++ reshape_sectors - stripe_addr != sector_nr)) ++ return MaxSector; + } else { +- BUG_ON(writepos != sector_nr + reshape_sectors); ++ if (WARN_ON(writepos != sector_nr + reshape_sectors)) ++ return MaxSector; ++ + stripe_addr = sector_nr; + } + +diff --git a/drivers/media/platform/amphion/vdec.c b/drivers/media/platform/amphion/vdec.c +index 133d77d1ea0c3..4f438eaa7d385 100644 +--- a/drivers/media/platform/amphion/vdec.c ++++ b/drivers/media/platform/amphion/vdec.c +@@ -195,7 +195,6 @@ static int vdec_op_s_ctrl(struct v4l2_ctrl *ctrl) + struct vdec_t *vdec = inst->priv; + int ret = 0; + +- vpu_inst_lock(inst); + switch (ctrl->id) { + case V4L2_CID_MPEG_VIDEO_DEC_DISPLAY_DELAY_ENABLE: + vdec->params.display_delay_enable = ctrl->val; +@@ -207,7 +206,6 @@ static int vdec_op_s_ctrl(struct v4l2_ctrl *ctrl) + ret = -EINVAL; + break; + } +- vpu_inst_unlock(inst); + + return ret; + } +diff --git a/drivers/media/platform/amphion/venc.c b/drivers/media/platform/amphion/venc.c +index 4eb57d793a9c0..16ed4d21519cd 100644 +--- a/drivers/media/platform/amphion/venc.c ++++ b/drivers/media/platform/amphion/venc.c +@@ -518,7 +518,6 @@ static int venc_op_s_ctrl(struct v4l2_ctrl *ctrl) + struct venc_t *venc = inst->priv; + int ret = 0; + +- vpu_inst_lock(inst); + switch (ctrl->id) { + case V4L2_CID_MPEG_VIDEO_H264_PROFILE: + venc->params.profile = ctrl->val; +@@ -579,7 +578,6 @@ static int venc_op_s_ctrl(struct v4l2_ctrl *ctrl) + ret = -EINVAL; + break; + } +- vpu_inst_unlock(inst); + + return ret; + } +diff --git a/drivers/media/tuners/xc2028.c b/drivers/media/tuners/xc2028.c +index 5a967edceca93..352b8a3679b72 100644 +--- a/drivers/media/tuners/xc2028.c ++++ b/drivers/media/tuners/xc2028.c +@@ -1361,9 +1361,16 @@ static void load_firmware_cb(const struct firmware *fw, + void *context) + { + struct dvb_frontend *fe = context; +- struct xc2028_data *priv = fe->tuner_priv; ++ struct xc2028_data *priv; + int rc; + ++ if (!fe) { ++ pr_warn("xc2028: No frontend in %s\n", __func__); ++ return; ++ } ++ ++ priv = fe->tuner_priv; ++ + tuner_dbg("request_firmware_nowait(): %s\n", fw ? "OK" : "error"); + if (!fw) { + tuner_err("Could not load firmware %s.\n", priv->fname); +diff --git a/drivers/media/usb/uvc/uvc_video.c b/drivers/media/usb/uvc/uvc_video.c +index 5eef560bc8cd8..91c350b254126 100644 +--- a/drivers/media/usb/uvc/uvc_video.c ++++ b/drivers/media/usb/uvc/uvc_video.c +@@ -214,13 +214,13 @@ static void uvc_fixup_video_ctrl(struct uvc_streaming *stream, + * Compute a bandwidth estimation by multiplying the frame + * size by the number of video frames per second, divide the + * result by the number of USB frames (or micro-frames for +- * high-speed devices) per second and add the UVC header size +- * (assumed to be 12 bytes long). ++ * high- and super-speed devices) per second and add the UVC ++ * header size (assumed to be 12 bytes long). + */ + bandwidth = frame->wWidth * frame->wHeight / 8 * format->bpp; + bandwidth *= 10000000 / interval + 1; + bandwidth /= 1000; +- if (stream->dev->udev->speed == USB_SPEED_HIGH) ++ if (stream->dev->udev->speed >= USB_SPEED_HIGH) + bandwidth /= 8; + bandwidth += 12; + +@@ -478,6 +478,7 @@ uvc_video_clock_decode(struct uvc_streaming *stream, struct uvc_buffer *buf, + ktime_t time; + u16 host_sof; + u16 dev_sof; ++ u32 dev_stc; + + switch (data[1] & (UVC_STREAM_PTS | UVC_STREAM_SCR)) { + case UVC_STREAM_PTS | UVC_STREAM_SCR: +@@ -526,6 +527,34 @@ uvc_video_clock_decode(struct uvc_streaming *stream, struct uvc_buffer *buf, + if (dev_sof == stream->clock.last_sof) + return; + ++ dev_stc = get_unaligned_le32(&data[header_size - 6]); ++ ++ /* ++ * STC (Source Time Clock) is the clock used by the camera. The UVC 1.5 ++ * standard states that it "must be captured when the first video data ++ * of a video frame is put on the USB bus". This is generally understood ++ * as requiring devices to clear the payload header's SCR bit before ++ * the first packet containing video data. ++ * ++ * Most vendors follow that interpretation, but some (namely SunplusIT ++ * on some devices) always set the `UVC_STREAM_SCR` bit, fill the SCR ++ * field with 0's,and expect that the driver only processes the SCR if ++ * there is data in the packet. ++ * ++ * Ignore all the hardware timestamp information if we haven't received ++ * any data for this frame yet, the packet contains no data, and both ++ * STC and SOF are zero. This heuristics should be safe on compliant ++ * devices. This should be safe with compliant devices, as in the very ++ * unlikely case where a UVC 1.1 device would send timing information ++ * only before the first packet containing data, and both STC and SOF ++ * happen to be zero for a particular frame, we would only miss one ++ * clock sample from many and the clock recovery algorithm wouldn't ++ * suffer from this condition. ++ */ ++ if (buf && buf->bytesused == 0 && len == header_size && ++ dev_stc == 0 && dev_sof == 0) ++ return; ++ + stream->clock.last_sof = dev_sof; + + host_sof = usb_get_current_frame_number(stream->dev->udev); +@@ -575,7 +604,7 @@ uvc_video_clock_decode(struct uvc_streaming *stream, struct uvc_buffer *buf, + spin_lock_irqsave(&stream->clock.lock, flags); + + sample = &stream->clock.samples[stream->clock.head]; +- sample->dev_stc = get_unaligned_le32(&data[header_size - 6]); ++ sample->dev_stc = dev_stc; + sample->dev_sof = dev_sof; + sample->host_sof = host_sof; + sample->host_time = time; +diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd-ring.c b/drivers/net/can/spi/mcp251xfd/mcp251xfd-ring.c +index bfe4caa0c99d4..4cb79a4f24612 100644 +--- a/drivers/net/can/spi/mcp251xfd/mcp251xfd-ring.c ++++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd-ring.c +@@ -485,6 +485,8 @@ int mcp251xfd_ring_alloc(struct mcp251xfd_priv *priv) + clear_bit(MCP251XFD_FLAGS_FD_MODE, priv->flags); + } + ++ tx_ring->obj_num_shift_to_u8 = BITS_PER_TYPE(tx_ring->obj_num) - ++ ilog2(tx_ring->obj_num); + tx_ring->obj_size = tx_obj_size; + + rem = priv->rx_obj_num; +diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd-tef.c b/drivers/net/can/spi/mcp251xfd/mcp251xfd-tef.c +index e5bd57b65aafe..5b0c7890d4b44 100644 +--- a/drivers/net/can/spi/mcp251xfd/mcp251xfd-tef.c ++++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd-tef.c +@@ -2,7 +2,7 @@ + // + // mcp251xfd - Microchip MCP251xFD Family CAN controller driver + // +-// Copyright (c) 2019, 2020, 2021 Pengutronix, ++// Copyright (c) 2019, 2020, 2021, 2023 Pengutronix, + // Marc Kleine-Budde <kernel@pengutronix.de> + // + // Based on: +@@ -16,6 +16,11 @@ + + #include "mcp251xfd.h" + ++static inline bool mcp251xfd_tx_fifo_sta_full(u32 fifo_sta) ++{ ++ return !(fifo_sta & MCP251XFD_REG_FIFOSTA_TFNRFNIF); ++} ++ + static inline int + mcp251xfd_tef_tail_get_from_chip(const struct mcp251xfd_priv *priv, + u8 *tef_tail) +@@ -55,56 +60,39 @@ static int mcp251xfd_check_tef_tail(const struct mcp251xfd_priv *priv) + return 0; + } + +-static int +-mcp251xfd_handle_tefif_recover(const struct mcp251xfd_priv *priv, const u32 seq) +-{ +- const struct mcp251xfd_tx_ring *tx_ring = priv->tx; +- u32 tef_sta; +- int err; +- +- err = regmap_read(priv->map_reg, MCP251XFD_REG_TEFSTA, &tef_sta); +- if (err) +- return err; +- +- if (tef_sta & MCP251XFD_REG_TEFSTA_TEFOVIF) { +- netdev_err(priv->ndev, +- "Transmit Event FIFO buffer overflow.\n"); +- return -ENOBUFS; +- } +- +- netdev_info(priv->ndev, +- "Transmit Event FIFO buffer %s. (seq=0x%08x, tef_tail=0x%08x, tef_head=0x%08x, tx_head=0x%08x).\n", +- tef_sta & MCP251XFD_REG_TEFSTA_TEFFIF ? +- "full" : tef_sta & MCP251XFD_REG_TEFSTA_TEFNEIF ? +- "not empty" : "empty", +- seq, priv->tef->tail, priv->tef->head, tx_ring->head); +- +- /* The Sequence Number in the TEF doesn't match our tef_tail. */ +- return -EAGAIN; +-} +- + static int + mcp251xfd_handle_tefif_one(struct mcp251xfd_priv *priv, + const struct mcp251xfd_hw_tef_obj *hw_tef_obj, + unsigned int *frame_len_ptr) + { + struct net_device_stats *stats = &priv->ndev->stats; ++ u32 seq, tef_tail_masked, tef_tail; + struct sk_buff *skb; +- u32 seq, seq_masked, tef_tail_masked, tef_tail; + +- seq = FIELD_GET(MCP251XFD_OBJ_FLAGS_SEQ_MCP2518FD_MASK, ++ /* Use the MCP2517FD mask on the MCP2518FD, too. We only ++ * compare 7 bits, this is enough to detect old TEF objects. ++ */ ++ seq = FIELD_GET(MCP251XFD_OBJ_FLAGS_SEQ_MCP2517FD_MASK, + hw_tef_obj->flags); +- +- /* Use the MCP2517FD mask on the MCP2518FD, too. We only +- * compare 7 bits, this should be enough to detect +- * net-yet-completed, i.e. old TEF objects. +- */ +- seq_masked = seq & +- field_mask(MCP251XFD_OBJ_FLAGS_SEQ_MCP2517FD_MASK); + tef_tail_masked = priv->tef->tail & + field_mask(MCP251XFD_OBJ_FLAGS_SEQ_MCP2517FD_MASK); +- if (seq_masked != tef_tail_masked) +- return mcp251xfd_handle_tefif_recover(priv, seq); ++ ++ /* According to mcp2518fd erratum DS80000789E 6. the FIFOCI ++ * bits of a FIFOSTA register, here the TX FIFO tail index ++ * might be corrupted and we might process past the TEF FIFO's ++ * head into old CAN frames. ++ * ++ * Compare the sequence number of the currently processed CAN ++ * frame with the expected sequence number. Abort with ++ * -EBADMSG if an old CAN frame is detected. ++ */ ++ if (seq != tef_tail_masked) { ++ netdev_dbg(priv->ndev, "%s: chip=0x%02x ring=0x%02x\n", __func__, ++ seq, tef_tail_masked); ++ stats->tx_fifo_errors++; ++ ++ return -EBADMSG; ++ } + + tef_tail = mcp251xfd_get_tef_tail(priv); + skb = priv->can.echo_skb[tef_tail]; +@@ -120,28 +108,44 @@ mcp251xfd_handle_tefif_one(struct mcp251xfd_priv *priv, + return 0; + } + +-static int mcp251xfd_tef_ring_update(struct mcp251xfd_priv *priv) ++static int ++mcp251xfd_get_tef_len(struct mcp251xfd_priv *priv, u8 *len_p) + { + const struct mcp251xfd_tx_ring *tx_ring = priv->tx; +- unsigned int new_head; +- u8 chip_tx_tail; ++ const u8 shift = tx_ring->obj_num_shift_to_u8; ++ u8 chip_tx_tail, tail, len; ++ u32 fifo_sta; + int err; + +- err = mcp251xfd_tx_tail_get_from_chip(priv, &chip_tx_tail); ++ err = regmap_read(priv->map_reg, MCP251XFD_REG_FIFOSTA(priv->tx->fifo_nr), ++ &fifo_sta); + if (err) + return err; + +- /* chip_tx_tail, is the next TX-Object send by the HW. +- * The new TEF head must be >= the old head, ... ++ if (mcp251xfd_tx_fifo_sta_full(fifo_sta)) { ++ *len_p = tx_ring->obj_num; ++ return 0; ++ } ++ ++ chip_tx_tail = FIELD_GET(MCP251XFD_REG_FIFOSTA_FIFOCI_MASK, fifo_sta); ++ ++ err = mcp251xfd_check_tef_tail(priv); ++ if (err) ++ return err; ++ tail = mcp251xfd_get_tef_tail(priv); ++ ++ /* First shift to full u8. The subtraction works on signed ++ * values, that keeps the difference steady around the u8 ++ * overflow. The right shift acts on len, which is an u8. + */ +- new_head = round_down(priv->tef->head, tx_ring->obj_num) + chip_tx_tail; +- if (new_head <= priv->tef->head) +- new_head += tx_ring->obj_num; ++ BUILD_BUG_ON(sizeof(tx_ring->obj_num) != sizeof(chip_tx_tail)); ++ BUILD_BUG_ON(sizeof(tx_ring->obj_num) != sizeof(tail)); ++ BUILD_BUG_ON(sizeof(tx_ring->obj_num) != sizeof(len)); + +- /* ... but it cannot exceed the TX head. */ +- priv->tef->head = min(new_head, tx_ring->head); ++ len = (chip_tx_tail << shift) - (tail << shift); ++ *len_p = len >> shift; + +- return mcp251xfd_check_tef_tail(priv); ++ return 0; + } + + static inline int +@@ -182,13 +186,12 @@ int mcp251xfd_handle_tefif(struct mcp251xfd_priv *priv) + u8 tef_tail, len, l; + int err, i; + +- err = mcp251xfd_tef_ring_update(priv); ++ err = mcp251xfd_get_tef_len(priv, &len); + if (err) + return err; + + tef_tail = mcp251xfd_get_tef_tail(priv); +- len = mcp251xfd_get_tef_len(priv); +- l = mcp251xfd_get_tef_linear_len(priv); ++ l = mcp251xfd_get_tef_linear_len(priv, len); + err = mcp251xfd_tef_obj_read(priv, hw_tef_obj, tef_tail, l); + if (err) + return err; +@@ -203,12 +206,12 @@ int mcp251xfd_handle_tefif(struct mcp251xfd_priv *priv) + unsigned int frame_len = 0; + + err = mcp251xfd_handle_tefif_one(priv, &hw_tef_obj[i], &frame_len); +- /* -EAGAIN means the Sequence Number in the TEF +- * doesn't match our tef_tail. This can happen if we +- * read the TEF objects too early. Leave loop let the +- * interrupt handler call us again. ++ /* -EBADMSG means we're affected by mcp2518fd erratum ++ * DS80000789E 6., i.e. the Sequence Number in the TEF ++ * doesn't match our tef_tail. Don't process any ++ * further and mark processed frames as good. + */ +- if (err == -EAGAIN) ++ if (err == -EBADMSG) + goto out_netif_wake_queue; + if (err) + return err; +@@ -223,6 +226,8 @@ int mcp251xfd_handle_tefif(struct mcp251xfd_priv *priv) + struct mcp251xfd_tx_ring *tx_ring = priv->tx; + int offset; + ++ ring->head += len; ++ + /* Increment the TEF FIFO tail pointer 'len' times in + * a single SPI message. + * +diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd.h b/drivers/net/can/spi/mcp251xfd/mcp251xfd.h +index b35bfebd23f29..4628bf847bc9b 100644 +--- a/drivers/net/can/spi/mcp251xfd/mcp251xfd.h ++++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd.h +@@ -524,6 +524,7 @@ struct mcp251xfd_tef_ring { + + /* u8 obj_num equals tx_ring->obj_num */ + /* u8 obj_size equals sizeof(struct mcp251xfd_hw_tef_obj) */ ++ /* u8 obj_num_shift_to_u8 equals tx_ring->obj_num_shift_to_u8 */ + + union mcp251xfd_write_reg_buf irq_enable_buf; + struct spi_transfer irq_enable_xfer; +@@ -542,6 +543,7 @@ struct mcp251xfd_tx_ring { + u8 nr; + u8 fifo_nr; + u8 obj_num; ++ u8 obj_num_shift_to_u8; + u8 obj_size; + + struct mcp251xfd_tx_obj obj[MCP251XFD_TX_OBJ_NUM_MAX]; +@@ -861,17 +863,8 @@ static inline u8 mcp251xfd_get_tef_tail(const struct mcp251xfd_priv *priv) + return priv->tef->tail & (priv->tx->obj_num - 1); + } + +-static inline u8 mcp251xfd_get_tef_len(const struct mcp251xfd_priv *priv) ++static inline u8 mcp251xfd_get_tef_linear_len(const struct mcp251xfd_priv *priv, u8 len) + { +- return priv->tef->head - priv->tef->tail; +-} +- +-static inline u8 mcp251xfd_get_tef_linear_len(const struct mcp251xfd_priv *priv) +-{ +- u8 len; +- +- len = mcp251xfd_get_tef_len(priv); +- + return min_t(u8, len, priv->tx->obj_num - mcp251xfd_get_tef_tail(priv)); + } + +diff --git a/drivers/net/dsa/bcm_sf2.c b/drivers/net/dsa/bcm_sf2.c +index cd1f240c90f39..257df16768750 100644 +--- a/drivers/net/dsa/bcm_sf2.c ++++ b/drivers/net/dsa/bcm_sf2.c +@@ -678,8 +678,10 @@ static int bcm_sf2_mdio_register(struct dsa_switch *ds) + of_remove_property(child, prop); + + phydev = of_phy_find_device(child); +- if (phydev) ++ if (phydev) { + phy_device_remove(phydev); ++ phy_device_free(phydev); ++ } + } + + err = mdiobus_register(priv->slave_mii_bus); +diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c b/drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c +index 1248792d7fd4d..0715ea5bf13ed 100644 +--- a/drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c ++++ b/drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c +@@ -42,19 +42,15 @@ void bcmgenet_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) + struct bcmgenet_priv *priv = netdev_priv(dev); + struct device *kdev = &priv->pdev->dev; + +- if (dev->phydev) { ++ if (dev->phydev) + phy_ethtool_get_wol(dev->phydev, wol); +- if (wol->supported) +- return; +- } + +- if (!device_can_wakeup(kdev)) { +- wol->supported = 0; +- wol->wolopts = 0; ++ /* MAC is not wake-up capable, return what the PHY does */ ++ if (!device_can_wakeup(kdev)) + return; +- } + +- wol->supported = WAKE_MAGIC | WAKE_MAGICSECURE | WAKE_FILTER; ++ /* Overlay MAC capabilities with that of the PHY queried before */ ++ wol->supported |= WAKE_MAGIC | WAKE_MAGICSECURE | WAKE_FILTER; + wol->wolopts = priv->wolopts; + memset(wol->sopass, 0, sizeof(wol->sopass)); + +diff --git a/drivers/net/ethernet/freescale/fec_ptp.c b/drivers/net/ethernet/freescale/fec_ptp.c +index e32f6724f5681..2e4f3e1782a25 100644 +--- a/drivers/net/ethernet/freescale/fec_ptp.c ++++ b/drivers/net/ethernet/freescale/fec_ptp.c +@@ -775,6 +775,9 @@ void fec_ptp_stop(struct platform_device *pdev) + struct net_device *ndev = platform_get_drvdata(pdev); + struct fec_enet_private *fep = netdev_priv(ndev); + ++ if (fep->pps_enable) ++ fec_ptp_enable_pps(fep, 0); ++ + cancel_delayed_work_sync(&fep->time_keep); + hrtimer_cancel(&fep->perout_timer); + if (fep->ptp_clock) +diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c +index 600a2f5370875..b168a37a5dfff 100644 +--- a/drivers/net/ethernet/intel/ice/ice_main.c ++++ b/drivers/net/ethernet/intel/ice/ice_main.c +@@ -557,6 +557,8 @@ ice_prepare_for_reset(struct ice_pf *pf, enum ice_reset_req reset_type) + if (test_bit(ICE_PREPARED_FOR_RESET, pf->state)) + return; + ++ synchronize_irq(pf->oicr_irq.virq); ++ + ice_unplug_aux_dev(pf); + + /* Notify VFs of impending reset */ +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c +index 8d9743a5e42c7..79ec6fcc9e259 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c +@@ -2374,6 +2374,9 @@ static void mlx5e_handle_rx_cqe_mpwrq_shampo(struct mlx5e_rq *rq, struct mlx5_cq + if (likely(wi->consumed_strides < rq->mpwqe.num_strides)) + return; + ++ if (unlikely(!cstrides)) ++ return; ++ + wq = &rq->mpwqe.wq; + wqe = mlx5_wq_ll_get_wqe(wq, wqe_id); + mlx5_wq_ll_pop(wq, cqe->wqe_id, &wqe->next.next_wqe_index); +diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c +index d5d2a4c776c1c..ded1bbda5266f 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c ++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c +@@ -21,6 +21,7 @@ + #define RGMII_IO_MACRO_CONFIG2 0x1C + #define RGMII_IO_MACRO_DEBUG1 0x20 + #define EMAC_SYSTEM_LOW_POWER_DEBUG 0x28 ++#define EMAC_WRAPPER_SGMII_PHY_CNTRL1 0xf4 + + /* RGMII_IO_MACRO_CONFIG fields */ + #define RGMII_CONFIG_FUNC_CLK_EN BIT(30) +@@ -79,6 +80,9 @@ + #define ETHQOS_MAC_CTRL_SPEED_MODE BIT(14) + #define ETHQOS_MAC_CTRL_PORT_SEL BIT(15) + ++/* EMAC_WRAPPER_SGMII_PHY_CNTRL1 bits */ ++#define SGMII_PHY_CNTRL1_SGMII_TX_TO_RX_LOOPBACK_EN BIT(3) ++ + #define SGMII_10M_RX_CLK_DVDR 0x31 + + struct ethqos_emac_por { +@@ -95,6 +99,7 @@ struct ethqos_emac_driver_data { + bool has_integrated_pcs; + u32 dma_addr_width; + struct dwmac4_addrs dwmac4_addrs; ++ bool needs_sgmii_loopback; + }; + + struct qcom_ethqos { +@@ -113,6 +118,7 @@ struct qcom_ethqos { + unsigned int num_por; + bool rgmii_config_loopback_en; + bool has_emac_ge_3; ++ bool needs_sgmii_loopback; + }; + + static int rgmii_readl(struct qcom_ethqos *ethqos, unsigned int offset) +@@ -187,8 +193,22 @@ ethqos_update_link_clk(struct qcom_ethqos *ethqos, unsigned int speed) + clk_set_rate(ethqos->link_clk, ethqos->link_clk_rate); + } + ++static void ++qcom_ethqos_set_sgmii_loopback(struct qcom_ethqos *ethqos, bool enable) ++{ ++ if (!ethqos->needs_sgmii_loopback || ++ ethqos->phy_mode != PHY_INTERFACE_MODE_2500BASEX) ++ return; ++ ++ rgmii_updatel(ethqos, ++ SGMII_PHY_CNTRL1_SGMII_TX_TO_RX_LOOPBACK_EN, ++ enable ? SGMII_PHY_CNTRL1_SGMII_TX_TO_RX_LOOPBACK_EN : 0, ++ EMAC_WRAPPER_SGMII_PHY_CNTRL1); ++} ++ + static void ethqos_set_func_clk_en(struct qcom_ethqos *ethqos) + { ++ qcom_ethqos_set_sgmii_loopback(ethqos, true); + rgmii_updatel(ethqos, RGMII_CONFIG_FUNC_CLK_EN, + RGMII_CONFIG_FUNC_CLK_EN, RGMII_IO_MACRO_CONFIG); + } +@@ -273,6 +293,7 @@ static const struct ethqos_emac_driver_data emac_v4_0_0_data = { + .has_emac_ge_3 = true, + .link_clk_name = "phyaux", + .has_integrated_pcs = true, ++ .needs_sgmii_loopback = true, + .dma_addr_width = 36, + .dwmac4_addrs = { + .dma_chan = 0x00008100, +@@ -646,6 +667,7 @@ static void ethqos_fix_mac_speed(void *priv, unsigned int speed, unsigned int mo + { + struct qcom_ethqos *ethqos = priv; + ++ qcom_ethqos_set_sgmii_loopback(ethqos, false); + ethqos->speed = speed; + ethqos_update_link_clk(ethqos, speed); + ethqos_configure(ethqos); +@@ -781,6 +803,7 @@ static int qcom_ethqos_probe(struct platform_device *pdev) + ethqos->num_por = data->num_por; + ethqos->rgmii_config_loopback_en = data->rgmii_config_loopback_en; + ethqos->has_emac_ge_3 = data->has_emac_ge_3; ++ ethqos->needs_sgmii_loopback = data->needs_sgmii_loopback; + + ethqos->link_clk = devm_clk_get(dev, data->link_clk_name ?: "rgmii"); + if (IS_ERR(ethqos->link_clk)) +diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c +index befbca01bfe37..b1380cf1b13ab 100644 +--- a/drivers/net/usb/qmi_wwan.c ++++ b/drivers/net/usb/qmi_wwan.c +@@ -201,6 +201,7 @@ static int qmimux_rx_fixup(struct usbnet *dev, struct sk_buff *skb) + break; + default: + /* not ip - do not know what to do */ ++ kfree_skb(skbn); + goto skip; + } + +diff --git a/drivers/net/wireless/ath/ath12k/core.h b/drivers/net/wireless/ath/ath12k/core.h +index c926952c956ef..33f4706af880d 100644 +--- a/drivers/net/wireless/ath/ath12k/core.h ++++ b/drivers/net/wireless/ath/ath12k/core.h +@@ -181,6 +181,8 @@ enum ath12k_dev_flags { + ATH12K_FLAG_REGISTERED, + ATH12K_FLAG_QMI_FAIL, + ATH12K_FLAG_HTC_SUSPEND_COMPLETE, ++ ATH12K_FLAG_CE_IRQ_ENABLED, ++ ATH12K_FLAG_EXT_IRQ_ENABLED, + }; + + enum ath12k_monitor_flags { +diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c +index 2c17b1e7681a5..d9bc07844fb71 100644 +--- a/drivers/net/wireless/ath/ath12k/dp_rx.c ++++ b/drivers/net/wireless/ath/ath12k/dp_rx.c +@@ -2759,6 +2759,7 @@ int ath12k_dp_rx_peer_frag_setup(struct ath12k *ar, const u8 *peer_mac, int vdev + peer = ath12k_peer_find(ab, vdev_id, peer_mac); + if (!peer) { + spin_unlock_bh(&ab->base_lock); ++ crypto_free_shash(tfm); + ath12k_warn(ab, "failed to find the peer to set up fragment info\n"); + return -ENOENT; + } +diff --git a/drivers/net/wireless/ath/ath12k/hif.h b/drivers/net/wireless/ath/ath12k/hif.h +index 4cbf9b5c04b9c..c653ca1f59b22 100644 +--- a/drivers/net/wireless/ath/ath12k/hif.h ++++ b/drivers/net/wireless/ath/ath12k/hif.h +@@ -10,17 +10,17 @@ + #include "core.h" + + struct ath12k_hif_ops { +- u32 (*read32)(struct ath12k_base *sc, u32 address); +- void (*write32)(struct ath12k_base *sc, u32 address, u32 data); +- void (*irq_enable)(struct ath12k_base *sc); +- void (*irq_disable)(struct ath12k_base *sc); +- int (*start)(struct ath12k_base *sc); +- void (*stop)(struct ath12k_base *sc); +- int (*power_up)(struct ath12k_base *sc); +- void (*power_down)(struct ath12k_base *sc); ++ u32 (*read32)(struct ath12k_base *ab, u32 address); ++ void (*write32)(struct ath12k_base *ab, u32 address, u32 data); ++ void (*irq_enable)(struct ath12k_base *ab); ++ void (*irq_disable)(struct ath12k_base *ab); ++ int (*start)(struct ath12k_base *ab); ++ void (*stop)(struct ath12k_base *ab); ++ int (*power_up)(struct ath12k_base *ab); ++ void (*power_down)(struct ath12k_base *ab); + int (*suspend)(struct ath12k_base *ab); + int (*resume)(struct ath12k_base *ab); +- int (*map_service_to_pipe)(struct ath12k_base *sc, u16 service_id, ++ int (*map_service_to_pipe)(struct ath12k_base *ab, u16 service_id, + u8 *ul_pipe, u8 *dl_pipe); + int (*get_user_msi_vector)(struct ath12k_base *ab, char *user_name, + int *num_vectors, u32 *user_base_data, +diff --git a/drivers/net/wireless/ath/ath12k/pci.c b/drivers/net/wireless/ath/ath12k/pci.c +index 58cd678555964..041a9602f0e15 100644 +--- a/drivers/net/wireless/ath/ath12k/pci.c ++++ b/drivers/net/wireless/ath/ath12k/pci.c +@@ -373,6 +373,8 @@ static void ath12k_pci_ce_irqs_disable(struct ath12k_base *ab) + { + int i; + ++ clear_bit(ATH12K_FLAG_CE_IRQ_ENABLED, &ab->dev_flags); ++ + for (i = 0; i < ab->hw_params->ce_count; i++) { + if (ath12k_ce_get_attr_flags(ab, i) & CE_ATTR_DIS_INTR) + continue; +@@ -406,6 +408,10 @@ static void ath12k_pci_ce_tasklet(struct tasklet_struct *t) + static irqreturn_t ath12k_pci_ce_interrupt_handler(int irq, void *arg) + { + struct ath12k_ce_pipe *ce_pipe = arg; ++ struct ath12k_base *ab = ce_pipe->ab; ++ ++ if (!test_bit(ATH12K_FLAG_CE_IRQ_ENABLED, &ab->dev_flags)) ++ return IRQ_HANDLED; + + /* last interrupt received for this CE */ + ce_pipe->timestamp = jiffies; +@@ -424,12 +430,15 @@ static void ath12k_pci_ext_grp_disable(struct ath12k_ext_irq_grp *irq_grp) + disable_irq_nosync(irq_grp->ab->irq_num[irq_grp->irqs[i]]); + } + +-static void __ath12k_pci_ext_irq_disable(struct ath12k_base *sc) ++static void __ath12k_pci_ext_irq_disable(struct ath12k_base *ab) + { + int i; + ++ if (!test_and_clear_bit(ATH12K_FLAG_EXT_IRQ_ENABLED, &ab->dev_flags)) ++ return; ++ + for (i = 0; i < ATH12K_EXT_IRQ_GRP_NUM_MAX; i++) { +- struct ath12k_ext_irq_grp *irq_grp = &sc->ext_irq_grp[i]; ++ struct ath12k_ext_irq_grp *irq_grp = &ab->ext_irq_grp[i]; + + ath12k_pci_ext_grp_disable(irq_grp); + +@@ -483,6 +492,10 @@ static int ath12k_pci_ext_grp_napi_poll(struct napi_struct *napi, int budget) + static irqreturn_t ath12k_pci_ext_interrupt_handler(int irq, void *arg) + { + struct ath12k_ext_irq_grp *irq_grp = arg; ++ struct ath12k_base *ab = irq_grp->ab; ++ ++ if (!test_bit(ATH12K_FLAG_EXT_IRQ_ENABLED, &ab->dev_flags)) ++ return IRQ_HANDLED; + + ath12k_dbg(irq_grp->ab, ATH12K_DBG_PCI, "ext irq:%d\n", irq); + +@@ -626,6 +639,8 @@ static void ath12k_pci_ce_irqs_enable(struct ath12k_base *ab) + { + int i; + ++ set_bit(ATH12K_FLAG_CE_IRQ_ENABLED, &ab->dev_flags); ++ + for (i = 0; i < ab->hw_params->ce_count; i++) { + if (ath12k_ce_get_attr_flags(ab, i) & CE_ATTR_DIS_INTR) + continue; +@@ -956,6 +971,8 @@ void ath12k_pci_ext_irq_enable(struct ath12k_base *ab) + { + int i; + ++ set_bit(ATH12K_FLAG_EXT_IRQ_ENABLED, &ab->dev_flags); ++ + for (i = 0; i < ATH12K_EXT_IRQ_GRP_NUM_MAX; i++) { + struct ath12k_ext_irq_grp *irq_grp = &ab->ext_irq_grp[i]; + +diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c +index 796c2a00fea4a..0fc7aa78b2e5b 100644 +--- a/drivers/nvme/host/pci.c ++++ b/drivers/nvme/host/pci.c +@@ -826,9 +826,9 @@ static blk_status_t nvme_map_metadata(struct nvme_dev *dev, struct request *req, + struct nvme_command *cmnd) + { + struct nvme_iod *iod = blk_mq_rq_to_pdu(req); ++ struct bio_vec bv = rq_integrity_vec(req); + +- iod->meta_dma = dma_map_bvec(dev->dev, rq_integrity_vec(req), +- rq_dma_dir(req), 0); ++ iod->meta_dma = dma_map_bvec(dev->dev, &bv, rq_dma_dir(req), 0); + if (dma_mapping_error(dev->dev, iod->meta_dma)) + return BLK_STS_IOERR; + cmnd->rw.metadata = cpu_to_le64(iod->meta_dma); +@@ -969,7 +969,7 @@ static __always_inline void nvme_pci_unmap_rq(struct request *req) + struct nvme_iod *iod = blk_mq_rq_to_pdu(req); + + dma_unmap_page(dev->dev, iod->meta_dma, +- rq_integrity_vec(req)->bv_len, rq_dma_dir(req)); ++ rq_integrity_vec(req).bv_len, rq_dma_dir(req)); + } + + if (blk_rq_nr_phys_segments(req)) +diff --git a/drivers/platform/x86/intel/ifs/core.c b/drivers/platform/x86/intel/ifs/core.c +index 306f886b52d20..4ff2aa4b484bc 100644 +--- a/drivers/platform/x86/intel/ifs/core.c ++++ b/drivers/platform/x86/intel/ifs/core.c +@@ -1,6 +1,7 @@ + // SPDX-License-Identifier: GPL-2.0-only + /* Copyright(c) 2022 Intel Corporation. */ + ++#include <linux/bitfield.h> + #include <linux/module.h> + #include <linux/kdev_t.h> + #include <linux/semaphore.h> +@@ -94,6 +95,8 @@ static int __init ifs_init(void) + for (i = 0; i < IFS_NUMTESTS; i++) { + if (!(msrval & BIT(ifs_devices[i].test_caps->integrity_cap_bit))) + continue; ++ ifs_devices[i].rw_data.generation = FIELD_GET(MSR_INTEGRITY_CAPS_SAF_GEN_MASK, ++ msrval); + ret = misc_register(&ifs_devices[i].misc); + if (ret) + goto err_exit; +diff --git a/drivers/platform/x86/intel/ifs/ifs.h b/drivers/platform/x86/intel/ifs/ifs.h +index 93191855890f2..6bc63ab705175 100644 +--- a/drivers/platform/x86/intel/ifs/ifs.h ++++ b/drivers/platform/x86/intel/ifs/ifs.h +@@ -174,9 +174,17 @@ union ifs_chunks_auth_status { + union ifs_scan { + u64 data; + struct { +- u32 start :8; +- u32 stop :8; +- u32 rsvd :16; ++ union { ++ struct { ++ u8 start; ++ u8 stop; ++ u16 rsvd; ++ } gen0; ++ struct { ++ u16 start; ++ u16 stop; ++ } gen2; ++ }; + u32 delay :31; + u32 sigmce :1; + }; +@@ -186,9 +194,17 @@ union ifs_scan { + union ifs_status { + u64 data; + struct { +- u32 chunk_num :8; +- u32 chunk_stop_index :8; +- u32 rsvd1 :16; ++ union { ++ struct { ++ u8 chunk_num; ++ u8 chunk_stop_index; ++ u16 rsvd1; ++ } gen0; ++ struct { ++ u16 chunk_num; ++ u16 chunk_stop_index; ++ } gen2; ++ }; + u32 error_code :8; + u32 rsvd2 :22; + u32 control_error :1; +@@ -229,6 +245,7 @@ struct ifs_test_caps { + * @status: it holds simple status pass/fail/untested + * @scan_details: opaque scan status code from h/w + * @cur_batch: number indicating the currently loaded test file ++ * @generation: IFS test generation enumerated by hardware + */ + struct ifs_data { + int loaded_version; +@@ -238,6 +255,7 @@ struct ifs_data { + int status; + u64 scan_details; + u32 cur_batch; ++ u32 generation; + }; + + struct ifs_work { +diff --git a/drivers/platform/x86/intel/ifs/runtest.c b/drivers/platform/x86/intel/ifs/runtest.c +index 43c864add778f..c7a5bf24bef35 100644 +--- a/drivers/platform/x86/intel/ifs/runtest.c ++++ b/drivers/platform/x86/intel/ifs/runtest.c +@@ -167,25 +167,35 @@ static int doscan(void *data) + */ + static void ifs_test_core(int cpu, struct device *dev) + { ++ union ifs_status status = {}; + union ifs_scan activate; +- union ifs_status status; + unsigned long timeout; + struct ifs_data *ifsd; ++ int to_start, to_stop; ++ int status_chunk; + u64 msrvals[2]; + int retries; + + ifsd = ifs_get_data(dev); + +- activate.rsvd = 0; ++ activate.gen0.rsvd = 0; + activate.delay = IFS_THREAD_WAIT; + activate.sigmce = 0; +- activate.start = 0; +- activate.stop = ifsd->valid_chunks - 1; ++ to_start = 0; ++ to_stop = ifsd->valid_chunks - 1; ++ ++ if (ifsd->generation) { ++ activate.gen2.start = to_start; ++ activate.gen2.stop = to_stop; ++ } else { ++ activate.gen0.start = to_start; ++ activate.gen0.stop = to_stop; ++ } + + timeout = jiffies + HZ / 2; + retries = MAX_IFS_RETRIES; + +- while (activate.start <= activate.stop) { ++ while (to_start <= to_stop) { + if (time_after(jiffies, timeout)) { + status.error_code = IFS_SW_TIMEOUT; + break; +@@ -196,13 +206,14 @@ static void ifs_test_core(int cpu, struct device *dev) + + status.data = msrvals[1]; + +- trace_ifs_status(cpu, activate, status); ++ trace_ifs_status(cpu, to_start, to_stop, status.data); + + /* Some cases can be retried, give up for others */ + if (!can_restart(status)) + break; + +- if (status.chunk_num == activate.start) { ++ status_chunk = ifsd->generation ? status.gen2.chunk_num : status.gen0.chunk_num; ++ if (status_chunk == to_start) { + /* Check for forward progress */ + if (--retries == 0) { + if (status.error_code == IFS_NO_ERROR) +@@ -211,7 +222,11 @@ static void ifs_test_core(int cpu, struct device *dev) + } + } else { + retries = MAX_IFS_RETRIES; +- activate.start = status.chunk_num; ++ if (ifsd->generation) ++ activate.gen2.start = status_chunk; ++ else ++ activate.gen0.start = status_chunk; ++ to_start = status_chunk; + } + } + +diff --git a/drivers/power/supply/axp288_charger.c b/drivers/power/supply/axp288_charger.c +index b5903193e2f96..ac05942e4e6ac 100644 +--- a/drivers/power/supply/axp288_charger.c ++++ b/drivers/power/supply/axp288_charger.c +@@ -178,18 +178,18 @@ static inline int axp288_charger_set_cv(struct axp288_chrg_info *info, int cv) + u8 reg_val; + int ret; + +- if (cv <= CV_4100MV) { +- reg_val = CHRG_CCCV_CV_4100MV; +- cv = CV_4100MV; +- } else if (cv <= CV_4150MV) { +- reg_val = CHRG_CCCV_CV_4150MV; +- cv = CV_4150MV; +- } else if (cv <= CV_4200MV) { ++ if (cv >= CV_4350MV) { ++ reg_val = CHRG_CCCV_CV_4350MV; ++ cv = CV_4350MV; ++ } else if (cv >= CV_4200MV) { + reg_val = CHRG_CCCV_CV_4200MV; + cv = CV_4200MV; ++ } else if (cv >= CV_4150MV) { ++ reg_val = CHRG_CCCV_CV_4150MV; ++ cv = CV_4150MV; + } else { +- reg_val = CHRG_CCCV_CV_4350MV; +- cv = CV_4350MV; ++ reg_val = CHRG_CCCV_CV_4100MV; ++ cv = CV_4100MV; + } + + reg_val = reg_val << CHRG_CCCV_CV_BIT_POS; +@@ -337,8 +337,8 @@ static int axp288_charger_usb_set_property(struct power_supply *psy, + } + break; + case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE: +- scaled_val = min(val->intval, info->max_cv); +- scaled_val = DIV_ROUND_CLOSEST(scaled_val, 1000); ++ scaled_val = DIV_ROUND_CLOSEST(val->intval, 1000); ++ scaled_val = min(scaled_val, info->max_cv); + ret = axp288_charger_set_cv(info, scaled_val); + if (ret < 0) { + dev_warn(&info->pdev->dev, "set charge voltage failed\n"); +diff --git a/drivers/power/supply/qcom_battmgr.c b/drivers/power/supply/qcom_battmgr.c +index ec163d1bcd189..44c6301f5f174 100644 +--- a/drivers/power/supply/qcom_battmgr.c ++++ b/drivers/power/supply/qcom_battmgr.c +@@ -486,7 +486,7 @@ static int qcom_battmgr_bat_get_property(struct power_supply *psy, + int ret; + + if (!battmgr->service_up) +- return -ENODEV; ++ return -EAGAIN; + + if (battmgr->variant == QCOM_BATTMGR_SC8280XP) + ret = qcom_battmgr_bat_sc8280xp_update(battmgr, psp); +@@ -683,7 +683,7 @@ static int qcom_battmgr_ac_get_property(struct power_supply *psy, + int ret; + + if (!battmgr->service_up) +- return -ENODEV; ++ return -EAGAIN; + + ret = qcom_battmgr_bat_sc8280xp_update(battmgr, psp); + if (ret) +@@ -748,7 +748,7 @@ static int qcom_battmgr_usb_get_property(struct power_supply *psy, + int ret; + + if (!battmgr->service_up) +- return -ENODEV; ++ return -EAGAIN; + + if (battmgr->variant == QCOM_BATTMGR_SC8280XP) + ret = qcom_battmgr_bat_sc8280xp_update(battmgr, psp); +@@ -867,7 +867,7 @@ static int qcom_battmgr_wls_get_property(struct power_supply *psy, + int ret; + + if (!battmgr->service_up) +- return -ENODEV; ++ return -EAGAIN; + + if (battmgr->variant == QCOM_BATTMGR_SC8280XP) + ret = qcom_battmgr_bat_sc8280xp_update(battmgr, psp); +diff --git a/drivers/s390/char/sclp_sd.c b/drivers/s390/char/sclp_sd.c +index f9e164be7568f..944e75beb160c 100644 +--- a/drivers/s390/char/sclp_sd.c ++++ b/drivers/s390/char/sclp_sd.c +@@ -320,8 +320,14 @@ static int sclp_sd_store_data(struct sclp_sd_data *result, u8 di) + &esize); + if (rc) { + /* Cancel running request if interrupted */ +- if (rc == -ERESTARTSYS) +- sclp_sd_sync(page, SD_EQ_HALT, di, 0, 0, NULL, NULL); ++ if (rc == -ERESTARTSYS) { ++ if (sclp_sd_sync(page, SD_EQ_HALT, di, 0, 0, NULL, NULL)) { ++ pr_warn("Could not stop Store Data request - leaking at least %zu bytes\n", ++ (size_t)dsize * PAGE_SIZE); ++ data = NULL; ++ asce = 0; ++ } ++ } + vfree(data); + goto out; + } +diff --git a/drivers/scsi/mpi3mr/mpi3mr_os.c b/drivers/scsi/mpi3mr/mpi3mr_os.c +index 80d71041086e1..7f32619234696 100644 +--- a/drivers/scsi/mpi3mr/mpi3mr_os.c ++++ b/drivers/scsi/mpi3mr/mpi3mr_os.c +@@ -3447,6 +3447,17 @@ static int mpi3mr_prepare_sg_scmd(struct mpi3mr_ioc *mrioc, + scmd->sc_data_direction); + priv->meta_sg_valid = 1; /* To unmap meta sg DMA */ + } else { ++ /* ++ * Some firmware versions byte-swap the REPORT ZONES command ++ * reply from ATA-ZAC devices by directly accessing in the host ++ * buffer. This does not respect the default command DMA ++ * direction and causes IOMMU page faults on some architectures ++ * with an IOMMU enforcing write mappings (e.g. AMD hosts). ++ * Avoid such issue by making the REPORT ZONES buffer mapping ++ * bi-directional. ++ */ ++ if (scmd->cmnd[0] == ZBC_IN && scmd->cmnd[1] == ZI_REPORT_ZONES) ++ scmd->sc_data_direction = DMA_BIDIRECTIONAL; + sg_scmd = scsi_sglist(scmd); + sges_left = scsi_dma_map(scmd); + } +diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c b/drivers/scsi/mpt3sas/mpt3sas_base.c +index 04116e02ffe8c..8acf586dc8b2e 100644 +--- a/drivers/scsi/mpt3sas/mpt3sas_base.c ++++ b/drivers/scsi/mpt3sas/mpt3sas_base.c +@@ -2671,6 +2671,22 @@ _base_build_zero_len_sge_ieee(struct MPT3SAS_ADAPTER *ioc, void *paddr) + _base_add_sg_single_ieee(paddr, sgl_flags, 0, 0, -1); + } + ++static inline int _base_scsi_dma_map(struct scsi_cmnd *cmd) ++{ ++ /* ++ * Some firmware versions byte-swap the REPORT ZONES command reply from ++ * ATA-ZAC devices by directly accessing in the host buffer. This does ++ * not respect the default command DMA direction and causes IOMMU page ++ * faults on some architectures with an IOMMU enforcing write mappings ++ * (e.g. AMD hosts). Avoid such issue by making the report zones buffer ++ * mapping bi-directional. ++ */ ++ if (cmd->cmnd[0] == ZBC_IN && cmd->cmnd[1] == ZI_REPORT_ZONES) ++ cmd->sc_data_direction = DMA_BIDIRECTIONAL; ++ ++ return scsi_dma_map(cmd); ++} ++ + /** + * _base_build_sg_scmd - main sg creation routine + * pcie_device is unused here! +@@ -2717,7 +2733,7 @@ _base_build_sg_scmd(struct MPT3SAS_ADAPTER *ioc, + sgl_flags = sgl_flags << MPI2_SGE_FLAGS_SHIFT; + + sg_scmd = scsi_sglist(scmd); +- sges_left = scsi_dma_map(scmd); ++ sges_left = _base_scsi_dma_map(scmd); + if (sges_left < 0) + return -ENOMEM; + +@@ -2861,7 +2877,7 @@ _base_build_sg_scmd_ieee(struct MPT3SAS_ADAPTER *ioc, + } + + sg_scmd = scsi_sglist(scmd); +- sges_left = scsi_dma_map(scmd); ++ sges_left = _base_scsi_dma_map(scmd); + if (sges_left < 0) + return -ENOMEM; + +diff --git a/drivers/spi/spi-fsl-lpspi.c b/drivers/spi/spi-fsl-lpspi.c +index 079035db7dd85..3c0f7dc9614d1 100644 +--- a/drivers/spi/spi-fsl-lpspi.c ++++ b/drivers/spi/spi-fsl-lpspi.c +@@ -296,7 +296,7 @@ static void fsl_lpspi_set_watermark(struct fsl_lpspi_data *fsl_lpspi) + static int fsl_lpspi_set_bitrate(struct fsl_lpspi_data *fsl_lpspi) + { + struct lpspi_config config = fsl_lpspi->config; +- unsigned int perclk_rate, scldiv; ++ unsigned int perclk_rate, scldiv, div; + u8 prescale; + + perclk_rate = clk_get_rate(fsl_lpspi->clk_per); +@@ -313,8 +313,10 @@ static int fsl_lpspi_set_bitrate(struct fsl_lpspi_data *fsl_lpspi) + return -EINVAL; + } + ++ div = DIV_ROUND_UP(perclk_rate, config.speed_hz); ++ + for (prescale = 0; prescale < 8; prescale++) { +- scldiv = perclk_rate / config.speed_hz / (1 << prescale) - 2; ++ scldiv = div / (1 << prescale) - 2; + if (scldiv < 256) { + fsl_lpspi->config.prescale = prescale; + break; +diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c +index 1a8dd10012448..b97206d47ec6d 100644 +--- a/drivers/spi/spidev.c ++++ b/drivers/spi/spidev.c +@@ -704,6 +704,7 @@ static const struct file_operations spidev_fops = { + static struct class *spidev_class; + + static const struct spi_device_id spidev_spi_ids[] = { ++ { .name = "bh2228fv" }, + { .name = "dh2228fv" }, + { .name = "ltc2488" }, + { .name = "sx1301" }, +diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c +index 2eceef54e0b30..ed8798fdf522a 100644 +--- a/drivers/tty/serial/serial_core.c ++++ b/drivers/tty/serial/serial_core.c +@@ -876,6 +876,14 @@ static int uart_set_info(struct tty_struct *tty, struct tty_port *port, + new_flags = (__force upf_t)new_info->flags; + old_custom_divisor = uport->custom_divisor; + ++ if (!(uport->flags & UPF_FIXED_PORT)) { ++ unsigned int uartclk = new_info->baud_base * 16; ++ /* check needs to be done here before other settings made */ ++ if (uartclk == 0) { ++ retval = -EINVAL; ++ goto exit; ++ } ++ } + if (!capable(CAP_SYS_ADMIN)) { + retval = -EPERM; + if (change_irq || change_port || +diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c +index 808979a093505..94edac17b95f8 100644 +--- a/drivers/ufs/core/ufshcd.c ++++ b/drivers/ufs/core/ufshcd.c +@@ -3971,11 +3971,16 @@ static inline void ufshcd_add_delay_before_dme_cmd(struct ufs_hba *hba) + min_sleep_time_us = + MIN_DELAY_BEFORE_DME_CMDS_US - delta; + else +- return; /* no more delay required */ ++ min_sleep_time_us = 0; /* no more delay required */ + } + +- /* allow sleep for extra 50us if needed */ +- usleep_range(min_sleep_time_us, min_sleep_time_us + 50); ++ if (min_sleep_time_us > 0) { ++ /* allow sleep for extra 50us if needed */ ++ usleep_range(min_sleep_time_us, min_sleep_time_us + 50); ++ } ++ ++ /* update the last_dme_cmd_tstamp */ ++ hba->last_dme_cmd_tstamp = ktime_get(); + } + + /** +@@ -10157,9 +10162,6 @@ int ufshcd_system_restore(struct device *dev) + */ + ufshcd_readl(hba, REG_UTP_TASK_REQ_LIST_BASE_H); + +- /* Resuming from hibernate, assume that link was OFF */ +- ufshcd_set_link_off(hba); +- + return 0; + + } +diff --git a/drivers/usb/gadget/function/f_midi2.c b/drivers/usb/gadget/function/f_midi2.c +index 0e38bb145e8f5..6908fdd4a83f3 100644 +--- a/drivers/usb/gadget/function/f_midi2.c ++++ b/drivers/usb/gadget/function/f_midi2.c +@@ -642,12 +642,21 @@ static void process_ump_stream_msg(struct f_midi2_ep *ep, const u32 *data) + if (format) + return; // invalid + blk = (*data >> 8) & 0xff; +- if (blk >= ep->num_blks) +- return; +- if (*data & UMP_STREAM_MSG_REQUEST_FB_INFO) +- reply_ump_stream_fb_info(ep, blk); +- if (*data & UMP_STREAM_MSG_REQUEST_FB_NAME) +- reply_ump_stream_fb_name(ep, blk); ++ if (blk == 0xff) { ++ /* inquiry for all blocks */ ++ for (blk = 0; blk < ep->num_blks; blk++) { ++ if (*data & UMP_STREAM_MSG_REQUEST_FB_INFO) ++ reply_ump_stream_fb_info(ep, blk); ++ if (*data & UMP_STREAM_MSG_REQUEST_FB_NAME) ++ reply_ump_stream_fb_name(ep, blk); ++ } ++ } else if (blk < ep->num_blks) { ++ /* only the specified block */ ++ if (*data & UMP_STREAM_MSG_REQUEST_FB_INFO) ++ reply_ump_stream_fb_info(ep, blk); ++ if (*data & UMP_STREAM_MSG_REQUEST_FB_NAME) ++ reply_ump_stream_fb_name(ep, blk); ++ } + return; + } + } +diff --git a/drivers/usb/gadget/function/u_audio.c b/drivers/usb/gadget/function/u_audio.c +index ec1dceb087293..0be0966973c7f 100644 +--- a/drivers/usb/gadget/function/u_audio.c ++++ b/drivers/usb/gadget/function/u_audio.c +@@ -592,16 +592,25 @@ int u_audio_start_capture(struct g_audio *audio_dev) + struct usb_ep *ep, *ep_fback; + struct uac_rtd_params *prm; + struct uac_params *params = &audio_dev->params; +- int req_len, i; ++ int req_len, i, ret; + + prm = &uac->c_prm; + dev_dbg(dev, "start capture with rate %d\n", prm->srate); + ep = audio_dev->out_ep; +- config_ep_by_speed(gadget, &audio_dev->func, ep); ++ ret = config_ep_by_speed(gadget, &audio_dev->func, ep); ++ if (ret < 0) { ++ dev_err(dev, "config_ep_by_speed for out_ep failed (%d)\n", ret); ++ return ret; ++ } ++ + req_len = ep->maxpacket; + + prm->ep_enabled = true; +- usb_ep_enable(ep); ++ ret = usb_ep_enable(ep); ++ if (ret < 0) { ++ dev_err(dev, "usb_ep_enable failed for out_ep (%d)\n", ret); ++ return ret; ++ } + + for (i = 0; i < params->req_number; i++) { + if (!prm->reqs[i]) { +@@ -629,9 +638,18 @@ int u_audio_start_capture(struct g_audio *audio_dev) + return 0; + + /* Setup feedback endpoint */ +- config_ep_by_speed(gadget, &audio_dev->func, ep_fback); ++ ret = config_ep_by_speed(gadget, &audio_dev->func, ep_fback); ++ if (ret < 0) { ++ dev_err(dev, "config_ep_by_speed in_ep_fback failed (%d)\n", ret); ++ return ret; // TODO: Clean up out_ep ++ } ++ + prm->fb_ep_enabled = true; +- usb_ep_enable(ep_fback); ++ ret = usb_ep_enable(ep_fback); ++ if (ret < 0) { ++ dev_err(dev, "usb_ep_enable failed for in_ep_fback (%d)\n", ret); ++ return ret; // TODO: Clean up out_ep ++ } + req_len = ep_fback->maxpacket; + + req_fback = usb_ep_alloc_request(ep_fback, GFP_ATOMIC); +@@ -687,13 +705,17 @@ int u_audio_start_playback(struct g_audio *audio_dev) + struct uac_params *params = &audio_dev->params; + unsigned int factor; + const struct usb_endpoint_descriptor *ep_desc; +- int req_len, i; ++ int req_len, i, ret; + unsigned int p_pktsize; + + prm = &uac->p_prm; + dev_dbg(dev, "start playback with rate %d\n", prm->srate); + ep = audio_dev->in_ep; +- config_ep_by_speed(gadget, &audio_dev->func, ep); ++ ret = config_ep_by_speed(gadget, &audio_dev->func, ep); ++ if (ret < 0) { ++ dev_err(dev, "config_ep_by_speed for in_ep failed (%d)\n", ret); ++ return ret; ++ } + + ep_desc = ep->desc; + /* +@@ -720,7 +742,11 @@ int u_audio_start_playback(struct g_audio *audio_dev) + uac->p_residue_mil = 0; + + prm->ep_enabled = true; +- usb_ep_enable(ep); ++ ret = usb_ep_enable(ep); ++ if (ret < 0) { ++ dev_err(dev, "usb_ep_enable failed for in_ep (%d)\n", ret); ++ return ret; ++ } + + for (i = 0; i < params->req_number; i++) { + if (!prm->reqs[i]) { +diff --git a/drivers/usb/gadget/function/u_serial.c b/drivers/usb/gadget/function/u_serial.c +index a92eb6d909768..8962f96ae7294 100644 +--- a/drivers/usb/gadget/function/u_serial.c ++++ b/drivers/usb/gadget/function/u_serial.c +@@ -1441,6 +1441,7 @@ void gserial_suspend(struct gserial *gser) + spin_lock(&port->port_lock); + spin_unlock(&serial_port_lock); + port->suspended = true; ++ port->start_delayed = true; + spin_unlock_irqrestore(&port->port_lock, flags); + } + EXPORT_SYMBOL_GPL(gserial_suspend); +diff --git a/drivers/usb/gadget/udc/core.c b/drivers/usb/gadget/udc/core.c +index 358394fc3db93..9886e1cb13985 100644 +--- a/drivers/usb/gadget/udc/core.c ++++ b/drivers/usb/gadget/udc/core.c +@@ -118,12 +118,10 @@ int usb_ep_enable(struct usb_ep *ep) + goto out; + + /* UDC drivers can't handle endpoints with maxpacket size 0 */ +- if (usb_endpoint_maxp(ep->desc) == 0) { +- /* +- * We should log an error message here, but we can't call +- * dev_err() because there's no way to find the gadget +- * given only ep. +- */ ++ if (!ep->desc || usb_endpoint_maxp(ep->desc) == 0) { ++ WARN_ONCE(1, "%s: ep%d (%s) has %s\n", __func__, ep->address, ep->name, ++ (!ep->desc) ? "NULL descriptor" : "maxpacket 0"); ++ + ret = -EINVAL; + goto out; + } +diff --git a/drivers/usb/serial/usb_debug.c b/drivers/usb/serial/usb_debug.c +index 6934970f180d7..5a8869cd95d52 100644 +--- a/drivers/usb/serial/usb_debug.c ++++ b/drivers/usb/serial/usb_debug.c +@@ -76,6 +76,11 @@ static void usb_debug_process_read_urb(struct urb *urb) + usb_serial_generic_process_read_urb(urb); + } + ++static void usb_debug_init_termios(struct tty_struct *tty) ++{ ++ tty->termios.c_lflag &= ~(ECHO | ECHONL); ++} ++ + static struct usb_serial_driver debug_device = { + .driver = { + .owner = THIS_MODULE, +@@ -85,6 +90,7 @@ static struct usb_serial_driver debug_device = { + .num_ports = 1, + .bulk_out_size = USB_DEBUG_MAX_PACKET_SIZE, + .break_ctl = usb_debug_break_ctl, ++ .init_termios = usb_debug_init_termios, + .process_read_urb = usb_debug_process_read_urb, + }; + +@@ -96,6 +102,7 @@ static struct usb_serial_driver dbc_device = { + .id_table = dbc_id_table, + .num_ports = 1, + .break_ctl = usb_debug_break_ctl, ++ .init_termios = usb_debug_init_termios, + .process_read_urb = usb_debug_process_read_urb, + }; + +diff --git a/drivers/usb/usbip/vhci_hcd.c b/drivers/usb/usbip/vhci_hcd.c +index 37d1fc34e8a56..14a5f55f24fc8 100644 +--- a/drivers/usb/usbip/vhci_hcd.c ++++ b/drivers/usb/usbip/vhci_hcd.c +@@ -745,6 +745,7 @@ static int vhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flag + * + */ + if (usb_pipedevice(urb->pipe) == 0) { ++ struct usb_device *old; + __u8 type = usb_pipetype(urb->pipe); + struct usb_ctrlrequest *ctrlreq = + (struct usb_ctrlrequest *) urb->setup_packet; +@@ -755,14 +756,15 @@ static int vhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flag + goto no_need_xmit; + } + ++ old = vdev->udev; + switch (ctrlreq->bRequest) { + case USB_REQ_SET_ADDRESS: + /* set_address may come when a device is reset */ + dev_info(dev, "SetAddress Request (%d) to port %d\n", + ctrlreq->wValue, vdev->rhport); + +- usb_put_dev(vdev->udev); + vdev->udev = usb_get_dev(urb->dev); ++ usb_put_dev(old); + + spin_lock(&vdev->ud.lock); + vdev->ud.status = VDEV_ST_USED; +@@ -781,8 +783,8 @@ static int vhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flag + usbip_dbg_vhci_hc( + "Not yet?:Get_Descriptor to device 0 (get max pipe size)\n"); + +- usb_put_dev(vdev->udev); + vdev->udev = usb_get_dev(urb->dev); ++ usb_put_dev(old); + goto out; + + default: +@@ -1067,6 +1069,7 @@ static void vhci_shutdown_connection(struct usbip_device *ud) + static void vhci_device_reset(struct usbip_device *ud) + { + struct vhci_device *vdev = container_of(ud, struct vhci_device, ud); ++ struct usb_device *old = vdev->udev; + unsigned long flags; + + spin_lock_irqsave(&ud->lock, flags); +@@ -1074,8 +1077,8 @@ static void vhci_device_reset(struct usbip_device *ud) + vdev->speed = 0; + vdev->devid = 0; + +- usb_put_dev(vdev->udev); + vdev->udev = NULL; ++ usb_put_dev(old); + + if (ud->tcp_socket) { + sockfd_put(ud->tcp_socket); +diff --git a/drivers/vhost/vdpa.c b/drivers/vhost/vdpa.c +index fb590e346e43d..da2c31ccc1380 100644 +--- a/drivers/vhost/vdpa.c ++++ b/drivers/vhost/vdpa.c +@@ -1378,13 +1378,7 @@ static vm_fault_t vhost_vdpa_fault(struct vm_fault *vmf) + + notify = ops->get_vq_notification(vdpa, index); + +- vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); +- if (remap_pfn_range(vma, vmf->address & PAGE_MASK, +- PFN_DOWN(notify.addr), PAGE_SIZE, +- vma->vm_page_prot)) +- return VM_FAULT_SIGBUS; +- +- return VM_FAULT_NOPAGE; ++ return vmf_insert_pfn(vma, vmf->address & PAGE_MASK, PFN_DOWN(notify.addr)); + } + + static const struct vm_operations_struct vhost_vdpa_vm_ops = { +diff --git a/drivers/xen/privcmd.c b/drivers/xen/privcmd.c +index da88173bac432..923f064c7e3e9 100644 +--- a/drivers/xen/privcmd.c ++++ b/drivers/xen/privcmd.c +@@ -841,7 +841,7 @@ static long privcmd_ioctl_mmap_resource(struct file *file, + #ifdef CONFIG_XEN_PRIVCMD_IRQFD + /* Irqfd support */ + static struct workqueue_struct *irqfd_cleanup_wq; +-static DEFINE_MUTEX(irqfds_lock); ++static DEFINE_SPINLOCK(irqfds_lock); + static LIST_HEAD(irqfds_list); + + struct privcmd_kernel_irqfd { +@@ -905,9 +905,11 @@ irqfd_wakeup(wait_queue_entry_t *wait, unsigned int mode, int sync, void *key) + irqfd_inject(kirqfd); + + if (flags & EPOLLHUP) { +- mutex_lock(&irqfds_lock); ++ unsigned long flags; ++ ++ spin_lock_irqsave(&irqfds_lock, flags); + irqfd_deactivate(kirqfd); +- mutex_unlock(&irqfds_lock); ++ spin_unlock_irqrestore(&irqfds_lock, flags); + } + + return 0; +@@ -925,6 +927,7 @@ irqfd_poll_func(struct file *file, wait_queue_head_t *wqh, poll_table *pt) + static int privcmd_irqfd_assign(struct privcmd_irqfd *irqfd) + { + struct privcmd_kernel_irqfd *kirqfd, *tmp; ++ unsigned long flags; + __poll_t events; + struct fd f; + void *dm_op; +@@ -964,18 +967,18 @@ static int privcmd_irqfd_assign(struct privcmd_irqfd *irqfd) + init_waitqueue_func_entry(&kirqfd->wait, irqfd_wakeup); + init_poll_funcptr(&kirqfd->pt, irqfd_poll_func); + +- mutex_lock(&irqfds_lock); ++ spin_lock_irqsave(&irqfds_lock, flags); + + list_for_each_entry(tmp, &irqfds_list, list) { + if (kirqfd->eventfd == tmp->eventfd) { + ret = -EBUSY; +- mutex_unlock(&irqfds_lock); ++ spin_unlock_irqrestore(&irqfds_lock, flags); + goto error_eventfd; + } + } + + list_add_tail(&kirqfd->list, &irqfds_list); +- mutex_unlock(&irqfds_lock); ++ spin_unlock_irqrestore(&irqfds_lock, flags); + + /* + * Check if there was an event already pending on the eventfd before we +@@ -1007,12 +1010,13 @@ static int privcmd_irqfd_deassign(struct privcmd_irqfd *irqfd) + { + struct privcmd_kernel_irqfd *kirqfd; + struct eventfd_ctx *eventfd; ++ unsigned long flags; + + eventfd = eventfd_ctx_fdget(irqfd->fd); + if (IS_ERR(eventfd)) + return PTR_ERR(eventfd); + +- mutex_lock(&irqfds_lock); ++ spin_lock_irqsave(&irqfds_lock, flags); + + list_for_each_entry(kirqfd, &irqfds_list, list) { + if (kirqfd->eventfd == eventfd) { +@@ -1021,7 +1025,7 @@ static int privcmd_irqfd_deassign(struct privcmd_irqfd *irqfd) + } + } + +- mutex_unlock(&irqfds_lock); ++ spin_unlock_irqrestore(&irqfds_lock, flags); + + eventfd_ctx_put(eventfd); + +@@ -1069,13 +1073,14 @@ static int privcmd_irqfd_init(void) + static void privcmd_irqfd_exit(void) + { + struct privcmd_kernel_irqfd *kirqfd, *tmp; ++ unsigned long flags; + +- mutex_lock(&irqfds_lock); ++ spin_lock_irqsave(&irqfds_lock, flags); + + list_for_each_entry_safe(kirqfd, tmp, &irqfds_list, list) + irqfd_deactivate(kirqfd); + +- mutex_unlock(&irqfds_lock); ++ spin_unlock_irqrestore(&irqfds_lock, flags); + + destroy_workqueue(irqfd_cleanup_wq); + } +diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h +index 06333a74d6c4c..86c7f8ce1715e 100644 +--- a/fs/btrfs/ctree.h ++++ b/fs/btrfs/ctree.h +@@ -445,6 +445,7 @@ struct btrfs_file_private { + void *filldir_buf; + u64 last_index; + struct extent_state *llseek_cached_state; ++ bool fsync_skip_inode_lock; + }; + + static inline u32 BTRFS_LEAF_DATA_SIZE(const struct btrfs_fs_info *info) +diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c +index 9fbffd84b16c5..c6a95dfa59c81 100644 +--- a/fs/btrfs/extent_io.c ++++ b/fs/btrfs/extent_io.c +@@ -2172,10 +2172,8 @@ void extent_write_locked_range(struct inode *inode, struct page *locked_page, + + page = find_get_page(mapping, cur >> PAGE_SHIFT); + ASSERT(PageLocked(page)); +- if (pages_dirty && page != locked_page) { ++ if (pages_dirty && page != locked_page) + ASSERT(PageDirty(page)); +- clear_page_dirty_for_io(page); +- } + + ret = __extent_writepage_io(BTRFS_I(inode), page, &bio_ctrl, + i_size, &nr); +diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c +index c997b790568fa..952cf145c6295 100644 +--- a/fs/btrfs/file.c ++++ b/fs/btrfs/file.c +@@ -1535,21 +1535,37 @@ static ssize_t btrfs_direct_write(struct kiocb *iocb, struct iov_iter *from) + * So here we disable page faults in the iov_iter and then retry if we + * got -EFAULT, faulting in the pages before the retry. + */ ++again: + from->nofault = true; + dio = btrfs_dio_write(iocb, from, written); + from->nofault = false; + +- /* +- * iomap_dio_complete() will call btrfs_sync_file() if we have a dsync +- * iocb, and that needs to lock the inode. So unlock it before calling +- * iomap_dio_complete() to avoid a deadlock. +- */ +- btrfs_inode_unlock(BTRFS_I(inode), ilock_flags); +- +- if (IS_ERR_OR_NULL(dio)) ++ if (IS_ERR_OR_NULL(dio)) { + err = PTR_ERR_OR_ZERO(dio); +- else ++ } else { ++ struct btrfs_file_private stack_private = { 0 }; ++ struct btrfs_file_private *private; ++ const bool have_private = (file->private_data != NULL); ++ ++ if (!have_private) ++ file->private_data = &stack_private; ++ ++ /* ++ * If we have a synchoronous write, we must make sure the fsync ++ * triggered by the iomap_dio_complete() call below doesn't ++ * deadlock on the inode lock - we are already holding it and we ++ * can't call it after unlocking because we may need to complete ++ * partial writes due to the input buffer (or parts of it) not ++ * being already faulted in. ++ */ ++ private = file->private_data; ++ private->fsync_skip_inode_lock = true; + err = iomap_dio_complete(dio); ++ private->fsync_skip_inode_lock = false; ++ ++ if (!have_private) ++ file->private_data = NULL; ++ } + + /* No increment (+=) because iomap returns a cumulative value. */ + if (err > 0) +@@ -1576,10 +1592,12 @@ static ssize_t btrfs_direct_write(struct kiocb *iocb, struct iov_iter *from) + } else { + fault_in_iov_iter_readable(from, left); + prev_left = left; +- goto relock; ++ goto again; + } + } + ++ btrfs_inode_unlock(BTRFS_I(inode), ilock_flags); ++ + /* + * If 'err' is -ENOTBLK or we have not written all data, then it means + * we must fallback to buffered IO. +@@ -1778,6 +1796,7 @@ static inline bool skip_inode_logging(const struct btrfs_log_ctx *ctx) + */ + int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync) + { ++ struct btrfs_file_private *private = file->private_data; + struct dentry *dentry = file_dentry(file); + struct inode *inode = d_inode(dentry); + struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); +@@ -1787,6 +1806,7 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync) + int ret = 0, err; + u64 len; + bool full_sync; ++ const bool skip_ilock = (private ? private->fsync_skip_inode_lock : false); + + trace_btrfs_sync_file(file, datasync); + +@@ -1814,7 +1834,10 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync) + if (ret) + goto out; + +- btrfs_inode_lock(BTRFS_I(inode), BTRFS_ILOCK_MMAP); ++ if (skip_ilock) ++ down_write(&BTRFS_I(inode)->i_mmap_lock); ++ else ++ btrfs_inode_lock(BTRFS_I(inode), BTRFS_ILOCK_MMAP); + + atomic_inc(&root->log_batch); + +@@ -1838,7 +1861,10 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync) + */ + ret = start_ordered_ops(inode, start, end); + if (ret) { +- btrfs_inode_unlock(BTRFS_I(inode), BTRFS_ILOCK_MMAP); ++ if (skip_ilock) ++ up_write(&BTRFS_I(inode)->i_mmap_lock); ++ else ++ btrfs_inode_unlock(BTRFS_I(inode), BTRFS_ILOCK_MMAP); + goto out; + } + +@@ -1941,7 +1967,10 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync) + * file again, but that will end up using the synchronization + * inside btrfs_sync_log to keep things safe. + */ +- btrfs_inode_unlock(BTRFS_I(inode), BTRFS_ILOCK_MMAP); ++ if (skip_ilock) ++ up_write(&BTRFS_I(inode)->i_mmap_lock); ++ else ++ btrfs_inode_unlock(BTRFS_I(inode), BTRFS_ILOCK_MMAP); + + if (ret == BTRFS_NO_LOG_SYNC) { + ret = btrfs_end_transaction(trans); +@@ -2009,7 +2038,10 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync) + + out_release_extents: + btrfs_release_log_ctx_extents(&ctx); +- btrfs_inode_unlock(BTRFS_I(inode), BTRFS_ILOCK_MMAP); ++ if (skip_ilock) ++ up_write(&BTRFS_I(inode)->i_mmap_lock); ++ else ++ btrfs_inode_unlock(BTRFS_I(inode), BTRFS_ILOCK_MMAP); + goto out; + } + +diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c +index f59e599766662..3e141c4dd2630 100644 +--- a/fs/btrfs/free-space-cache.c ++++ b/fs/btrfs/free-space-cache.c +@@ -855,6 +855,7 @@ static int __load_free_space_cache(struct btrfs_root *root, struct inode *inode, + spin_unlock(&ctl->tree_lock); + btrfs_err(fs_info, + "Duplicate entries in free space cache, dumping"); ++ kmem_cache_free(btrfs_free_space_bitmap_cachep, e->bitmap); + kmem_cache_free(btrfs_free_space_cachep, e); + goto free_cache; + } +diff --git a/fs/btrfs/print-tree.c b/fs/btrfs/print-tree.c +index 0c93439e929fb..815a5fc3ff9d8 100644 +--- a/fs/btrfs/print-tree.c ++++ b/fs/btrfs/print-tree.c +@@ -12,7 +12,7 @@ + + struct root_name_map { + u64 id; +- char name[16]; ++ const char *name; + }; + + static const struct root_name_map root_map[] = { +diff --git a/fs/ext4/inline.c b/fs/ext4/inline.c +index 012d9259ff532..a604aa1d23aed 100644 +--- a/fs/ext4/inline.c ++++ b/fs/ext4/inline.c +@@ -1411,7 +1411,11 @@ int ext4_inlinedir_to_tree(struct file *dir_file, + hinfo->hash = EXT4_DIRENT_HASH(de); + hinfo->minor_hash = EXT4_DIRENT_MINOR_HASH(de); + } else { +- ext4fs_dirhash(dir, de->name, de->name_len, hinfo); ++ err = ext4fs_dirhash(dir, de->name, de->name_len, hinfo); ++ if (err) { ++ ret = err; ++ goto out; ++ } + } + if ((hinfo->hash < start_hash) || + ((hinfo->hash == start_hash) && +diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c +index 0168d28427077..57264eb4d9da3 100644 +--- a/fs/jbd2/journal.c ++++ b/fs/jbd2/journal.c +@@ -399,6 +399,7 @@ int jbd2_journal_write_metadata_buffer(transaction_t *transaction, + tmp = jbd2_alloc(bh_in->b_size, GFP_NOFS); + if (!tmp) { + brelse(new_bh); ++ free_buffer_head(new_bh); + return -ENOMEM; + } + spin_lock(&jh_in->b_state_lock); +diff --git a/fs/smb/client/cifs_debug.c b/fs/smb/client/cifs_debug.c +index c71ae5c043060..4a20e92474b23 100644 +--- a/fs/smb/client/cifs_debug.c ++++ b/fs/smb/client/cifs_debug.c +@@ -1072,7 +1072,7 @@ static int cifs_security_flags_proc_open(struct inode *inode, struct file *file) + static void + cifs_security_flags_handle_must_flags(unsigned int *flags) + { +- unsigned int signflags = *flags & CIFSSEC_MUST_SIGN; ++ unsigned int signflags = *flags & (CIFSSEC_MUST_SIGN | CIFSSEC_MUST_SEAL); + + if ((*flags & CIFSSEC_MUST_KRB5) == CIFSSEC_MUST_KRB5) + *flags = CIFSSEC_MUST_KRB5; +diff --git a/fs/smb/client/cifsglob.h b/fs/smb/client/cifsglob.h +index 53e00255d96b6..54a84003950a4 100644 +--- a/fs/smb/client/cifsglob.h ++++ b/fs/smb/client/cifsglob.h +@@ -1922,7 +1922,7 @@ static inline bool is_replayable_error(int error) + #define CIFSSEC_MAY_SIGN 0x00001 + #define CIFSSEC_MAY_NTLMV2 0x00004 + #define CIFSSEC_MAY_KRB5 0x00008 +-#define CIFSSEC_MAY_SEAL 0x00040 /* not supported yet */ ++#define CIFSSEC_MAY_SEAL 0x00040 + #define CIFSSEC_MAY_NTLMSSP 0x00080 /* raw ntlmssp with ntlmv2 */ + + #define CIFSSEC_MUST_SIGN 0x01001 +@@ -1932,11 +1932,11 @@ require use of the stronger protocol */ + #define CIFSSEC_MUST_NTLMV2 0x04004 + #define CIFSSEC_MUST_KRB5 0x08008 + #ifdef CONFIG_CIFS_UPCALL +-#define CIFSSEC_MASK 0x8F08F /* flags supported if no weak allowed */ ++#define CIFSSEC_MASK 0xCF0CF /* flags supported if no weak allowed */ + #else +-#define CIFSSEC_MASK 0x87087 /* flags supported if no weak allowed */ ++#define CIFSSEC_MASK 0xC70C7 /* flags supported if no weak allowed */ + #endif /* UPCALL */ +-#define CIFSSEC_MUST_SEAL 0x40040 /* not supported yet */ ++#define CIFSSEC_MUST_SEAL 0x40040 + #define CIFSSEC_MUST_NTLMSSP 0x80080 /* raw ntlmssp with ntlmv2 */ + + #define CIFSSEC_DEF (CIFSSEC_MAY_SIGN | CIFSSEC_MAY_NTLMV2 | CIFSSEC_MAY_NTLMSSP | CIFSSEC_MAY_SEAL) +diff --git a/fs/smb/client/inode.c b/fs/smb/client/inode.c +index 9cdbc3ccc1d14..e74ba047902d8 100644 +--- a/fs/smb/client/inode.c ++++ b/fs/smb/client/inode.c +@@ -1023,13 +1023,26 @@ static int reparse_info_to_fattr(struct cifs_open_info_data *data, + } + + rc = -EOPNOTSUPP; +- switch ((data->reparse.tag = tag)) { +- case 0: /* SMB1 symlink */ ++ data->reparse.tag = tag; ++ if (!data->reparse.tag) { + if (server->ops->query_symlink) { + rc = server->ops->query_symlink(xid, tcon, + cifs_sb, full_path, + &data->symlink_target); + } ++ if (rc == -EOPNOTSUPP) ++ data->reparse.tag = IO_REPARSE_TAG_INTERNAL; ++ } ++ ++ switch (data->reparse.tag) { ++ case 0: /* SMB1 symlink */ ++ break; ++ case IO_REPARSE_TAG_INTERNAL: ++ rc = 0; ++ if (le32_to_cpu(data->fi.Attributes) & ATTR_DIRECTORY) { ++ cifs_create_junction_fattr(fattr, sb); ++ goto out; ++ } + break; + case IO_REPARSE_TAG_MOUNT_POINT: + cifs_create_junction_fattr(fattr, sb); +diff --git a/fs/smb/client/misc.c b/fs/smb/client/misc.c +index 07c468ddb88a8..65d4b72b4d51a 100644 +--- a/fs/smb/client/misc.c ++++ b/fs/smb/client/misc.c +@@ -1288,6 +1288,7 @@ int cifs_inval_name_dfs_link_error(const unsigned int xid, + const char *full_path, + bool *islink) + { ++ struct TCP_Server_Info *server = tcon->ses->server; + struct cifs_ses *ses = tcon->ses; + size_t len; + char *path; +@@ -1304,12 +1305,12 @@ int cifs_inval_name_dfs_link_error(const unsigned int xid, + !is_tcon_dfs(tcon)) + return 0; + +- spin_lock(&tcon->tc_lock); +- if (!tcon->origin_fullpath) { +- spin_unlock(&tcon->tc_lock); ++ spin_lock(&server->srv_lock); ++ if (!server->leaf_fullpath) { ++ spin_unlock(&server->srv_lock); + return 0; + } +- spin_unlock(&tcon->tc_lock); ++ spin_unlock(&server->srv_lock); + + /* + * Slow path - tcon is DFS and @full_path has prefix path, so attempt +diff --git a/fs/smb/client/reparse.c b/fs/smb/client/reparse.c +index a0ffbda907331..689d8a506d459 100644 +--- a/fs/smb/client/reparse.c ++++ b/fs/smb/client/reparse.c +@@ -505,6 +505,10 @@ bool cifs_reparse_point_to_fattr(struct cifs_sb_info *cifs_sb, + } + + switch (tag) { ++ case IO_REPARSE_TAG_INTERNAL: ++ if (!(fattr->cf_cifsattrs & ATTR_DIRECTORY)) ++ return false; ++ fallthrough; + case IO_REPARSE_TAG_DFS: + case IO_REPARSE_TAG_DFSR: + case IO_REPARSE_TAG_MOUNT_POINT: +diff --git a/fs/smb/client/reparse.h b/fs/smb/client/reparse.h +index 6b55d1df9e2f8..2c0644bc4e65a 100644 +--- a/fs/smb/client/reparse.h ++++ b/fs/smb/client/reparse.h +@@ -12,6 +12,12 @@ + #include "fs_context.h" + #include "cifsglob.h" + ++/* ++ * Used only by cifs.ko to ignore reparse points from files when client or ++ * server doesn't support FSCTL_GET_REPARSE_POINT. ++ */ ++#define IO_REPARSE_TAG_INTERNAL ((__u32)~0U) ++ + static inline dev_t reparse_nfs_mkdev(struct reparse_posix_data *buf) + { + u64 v = le64_to_cpu(*(__le64 *)buf->DataBuffer); +@@ -78,10 +84,19 @@ static inline u32 reparse_mode_wsl_tag(mode_t mode) + static inline bool reparse_inode_match(struct inode *inode, + struct cifs_fattr *fattr) + { ++ struct cifsInodeInfo *cinode = CIFS_I(inode); + struct timespec64 ctime = inode_get_ctime(inode); + +- return (CIFS_I(inode)->cifsAttrs & ATTR_REPARSE) && +- CIFS_I(inode)->reparse_tag == fattr->cf_cifstag && ++ /* ++ * Do not match reparse tags when client or server doesn't support ++ * FSCTL_GET_REPARSE_POINT. @fattr->cf_cifstag should contain correct ++ * reparse tag from query dir response but the client won't be able to ++ * read the reparse point data anyway. This spares us a revalidation. ++ */ ++ if (cinode->reparse_tag != IO_REPARSE_TAG_INTERNAL && ++ cinode->reparse_tag != fattr->cf_cifstag) ++ return false; ++ return (cinode->cifsAttrs & ATTR_REPARSE) && + timespec64_equal(&ctime, &fattr->cf_ctime); + } + +diff --git a/fs/smb/client/smb2inode.c b/fs/smb/client/smb2inode.c +index 86f8c81791374..28031c7ba6b19 100644 +--- a/fs/smb/client/smb2inode.c ++++ b/fs/smb/client/smb2inode.c +@@ -930,6 +930,8 @@ int smb2_query_path_info(const unsigned int xid, + + switch (rc) { + case 0: ++ rc = parse_create_response(data, cifs_sb, &out_iov[0]); ++ break; + case -EOPNOTSUPP: + /* + * BB TODO: When support for special files added to Samba +diff --git a/fs/smb/client/smb2pdu.c b/fs/smb/client/smb2pdu.c +index a5efce03cb58e..61df8a5c68242 100644 +--- a/fs/smb/client/smb2pdu.c ++++ b/fs/smb/client/smb2pdu.c +@@ -80,6 +80,9 @@ int smb3_encryption_required(const struct cifs_tcon *tcon) + if (tcon->seal && + (tcon->ses->server->capabilities & SMB2_GLOBAL_CAP_ENCRYPTION)) + return 1; ++ if (((global_secflags & CIFSSEC_MUST_SEAL) == CIFSSEC_MUST_SEAL) && ++ (tcon->ses->server->capabilities & SMB2_GLOBAL_CAP_ENCRYPTION)) ++ return 1; + return 0; + } + +diff --git a/fs/tracefs/event_inode.c b/fs/tracefs/event_inode.c +index b406bb3430f3d..aa54be1ce1242 100644 +--- a/fs/tracefs/event_inode.c ++++ b/fs/tracefs/event_inode.c +@@ -113,7 +113,7 @@ static void release_ei(struct kref *ref) + entry->release(entry->name, ei->data); + } + +- call_rcu(&ei->rcu, free_ei_rcu); ++ call_srcu(&eventfs_srcu, &ei->rcu, free_ei_rcu); + } + + static inline void put_ei(struct eventfs_inode *ei) +@@ -806,7 +806,7 @@ struct eventfs_inode *eventfs_create_dir(const char *name, struct eventfs_inode + /* Was the parent freed? */ + if (list_empty(&ei->list)) { + cleanup_ei(ei); +- ei = NULL; ++ ei = ERR_PTR(-EBUSY); + } + return ei; + } +diff --git a/fs/tracefs/inode.c b/fs/tracefs/inode.c +index 4ea11d1f72ace..7d389dd5ed519 100644 +--- a/fs/tracefs/inode.c ++++ b/fs/tracefs/inode.c +@@ -42,7 +42,7 @@ static struct inode *tracefs_alloc_inode(struct super_block *sb) + struct tracefs_inode *ti; + unsigned long flags; + +- ti = kmem_cache_alloc(tracefs_inode_cachep, GFP_KERNEL); ++ ti = alloc_inode_sb(sb, tracefs_inode_cachep, GFP_KERNEL); + if (!ti) + return NULL; + +@@ -53,15 +53,14 @@ static struct inode *tracefs_alloc_inode(struct super_block *sb) + return &ti->vfs_inode; + } + +-static void tracefs_free_inode_rcu(struct rcu_head *rcu) ++static void tracefs_free_inode(struct inode *inode) + { +- struct tracefs_inode *ti; ++ struct tracefs_inode *ti = get_tracefs(inode); + +- ti = container_of(rcu, struct tracefs_inode, rcu); + kmem_cache_free(tracefs_inode_cachep, ti); + } + +-static void tracefs_free_inode(struct inode *inode) ++static void tracefs_destroy_inode(struct inode *inode) + { + struct tracefs_inode *ti = get_tracefs(inode); + unsigned long flags; +@@ -69,8 +68,6 @@ static void tracefs_free_inode(struct inode *inode) + spin_lock_irqsave(&tracefs_inode_lock, flags); + list_del_rcu(&ti->list); + spin_unlock_irqrestore(&tracefs_inode_lock, flags); +- +- call_rcu(&ti->rcu, tracefs_free_inode_rcu); + } + + static ssize_t default_read_file(struct file *file, char __user *buf, +@@ -458,6 +455,7 @@ static int tracefs_drop_inode(struct inode *inode) + static const struct super_operations tracefs_super_operations = { + .alloc_inode = tracefs_alloc_inode, + .free_inode = tracefs_free_inode, ++ .destroy_inode = tracefs_destroy_inode, + .drop_inode = tracefs_drop_inode, + .statfs = simple_statfs, + .remount_fs = tracefs_remount, +diff --git a/fs/tracefs/internal.h b/fs/tracefs/internal.h +index f704d8348357e..d83c2a25f288e 100644 +--- a/fs/tracefs/internal.h ++++ b/fs/tracefs/internal.h +@@ -10,10 +10,7 @@ enum { + }; + + struct tracefs_inode { +- union { +- struct inode vfs_inode; +- struct rcu_head rcu; +- }; ++ struct inode vfs_inode; + /* The below gets initialized with memset_after(ti, 0, vfs_inode) */ + struct list_head list; + unsigned long flags; +diff --git a/fs/udf/balloc.c b/fs/udf/balloc.c +index 558ad046972ad..bb471ec364046 100644 +--- a/fs/udf/balloc.c ++++ b/fs/udf/balloc.c +@@ -18,6 +18,7 @@ + #include "udfdecl.h" + + #include <linux/bitops.h> ++#include <linux/overflow.h> + + #include "udf_i.h" + #include "udf_sb.h" +@@ -140,7 +141,6 @@ static void udf_bitmap_free_blocks(struct super_block *sb, + { + struct udf_sb_info *sbi = UDF_SB(sb); + struct buffer_head *bh = NULL; +- struct udf_part_map *partmap; + unsigned long block; + unsigned long block_group; + unsigned long bit; +@@ -149,19 +149,9 @@ static void udf_bitmap_free_blocks(struct super_block *sb, + unsigned long overflow; + + mutex_lock(&sbi->s_alloc_mutex); +- partmap = &sbi->s_partmaps[bloc->partitionReferenceNum]; +- if (bloc->logicalBlockNum + count < count || +- (bloc->logicalBlockNum + count) > partmap->s_partition_len) { +- udf_debug("%u < %d || %u + %u > %u\n", +- bloc->logicalBlockNum, 0, +- bloc->logicalBlockNum, count, +- partmap->s_partition_len); +- goto error_return; +- } +- ++ /* We make sure this cannot overflow when mounting the filesystem */ + block = bloc->logicalBlockNum + offset + + (sizeof(struct spaceBitmapDesc) << 3); +- + do { + overflow = 0; + block_group = block >> (sb->s_blocksize_bits + 3); +@@ -391,7 +381,6 @@ static void udf_table_free_blocks(struct super_block *sb, + uint32_t count) + { + struct udf_sb_info *sbi = UDF_SB(sb); +- struct udf_part_map *partmap; + uint32_t start, end; + uint32_t elen; + struct kernel_lb_addr eloc; +@@ -400,16 +389,6 @@ static void udf_table_free_blocks(struct super_block *sb, + struct udf_inode_info *iinfo; + + mutex_lock(&sbi->s_alloc_mutex); +- partmap = &sbi->s_partmaps[bloc->partitionReferenceNum]; +- if (bloc->logicalBlockNum + count < count || +- (bloc->logicalBlockNum + count) > partmap->s_partition_len) { +- udf_debug("%u < %d || %u + %u > %u\n", +- bloc->logicalBlockNum, 0, +- bloc->logicalBlockNum, count, +- partmap->s_partition_len); +- goto error_return; +- } +- + iinfo = UDF_I(table); + udf_add_free_space(sb, sbi->s_partition, count); + +@@ -684,6 +663,17 @@ void udf_free_blocks(struct super_block *sb, struct inode *inode, + { + uint16_t partition = bloc->partitionReferenceNum; + struct udf_part_map *map = &UDF_SB(sb)->s_partmaps[partition]; ++ uint32_t blk; ++ ++ if (check_add_overflow(bloc->logicalBlockNum, offset, &blk) || ++ check_add_overflow(blk, count, &blk) || ++ bloc->logicalBlockNum + count > map->s_partition_len) { ++ udf_debug("Invalid request to free blocks: (%d, %u), off %u, " ++ "len %u, partition len %u\n", ++ partition, bloc->logicalBlockNum, offset, count, ++ map->s_partition_len); ++ return; ++ } + + if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_BITMAP) { + udf_bitmap_free_blocks(sb, map->s_uspace.s_bitmap, +diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c +index 57f366c3d3554..9f9d3abad2cf3 100644 +--- a/fs/xfs/xfs_log_recover.c ++++ b/fs/xfs/xfs_log_recover.c +@@ -2965,7 +2965,7 @@ xlog_do_recovery_pass( + int error = 0, h_size, h_len; + int error2 = 0; + int bblks, split_bblks; +- int hblks, split_hblks, wrapped_hblks; ++ int hblks = 1, split_hblks, wrapped_hblks; + int i; + struct hlist_head rhash[XLOG_RHASH_SIZE]; + LIST_HEAD (buffer_list); +@@ -3021,14 +3021,22 @@ xlog_do_recovery_pass( + if (error) + goto bread_err1; + +- hblks = xlog_logrec_hblks(log, rhead); +- if (hblks != 1) { +- kmem_free(hbp); +- hbp = xlog_alloc_buffer(log, hblks); ++ /* ++ * This open codes xlog_logrec_hblks so that we can reuse the ++ * fixed up h_size value calculated above. Without that we'd ++ * still allocate the buffer based on the incorrect on-disk ++ * size. ++ */ ++ if (h_size > XLOG_HEADER_CYCLE_SIZE && ++ (rhead->h_version & cpu_to_be32(XLOG_VERSION_2))) { ++ hblks = DIV_ROUND_UP(h_size, XLOG_HEADER_CYCLE_SIZE); ++ if (hblks > 1) { ++ kmem_free(hbp); ++ hbp = xlog_alloc_buffer(log, hblks); ++ } + } + } else { + ASSERT(log->l_sectBBsize == 1); +- hblks = 1; + hbp = xlog_alloc_buffer(log, 1); + h_size = XLOG_BIG_RECORD_BSIZE; + } +diff --git a/include/linux/blk-integrity.h b/include/linux/blk-integrity.h +index 378b2459efe2d..f7cc8080672cc 100644 +--- a/include/linux/blk-integrity.h ++++ b/include/linux/blk-integrity.h +@@ -105,14 +105,13 @@ static inline bool blk_integrity_rq(struct request *rq) + } + + /* +- * Return the first bvec that contains integrity data. Only drivers that are +- * limited to a single integrity segment should use this helper. ++ * Return the current bvec that contains the integrity data. bip_iter may be ++ * advanced to iterate over the integrity data. + */ +-static inline struct bio_vec *rq_integrity_vec(struct request *rq) ++static inline struct bio_vec rq_integrity_vec(struct request *rq) + { +- if (WARN_ON_ONCE(queue_max_integrity_segments(rq->q) > 1)) +- return NULL; +- return rq->bio->bi_integrity->bip_vec; ++ return mp_bvec_iter_bvec(rq->bio->bi_integrity->bip_vec, ++ rq->bio->bi_integrity->bip_iter); + } + #else /* CONFIG_BLK_DEV_INTEGRITY */ + static inline int blk_rq_count_integrity_sg(struct request_queue *q, +@@ -176,9 +175,10 @@ static inline int blk_integrity_rq(struct request *rq) + return 0; + } + +-static inline struct bio_vec *rq_integrity_vec(struct request *rq) ++static inline struct bio_vec rq_integrity_vec(struct request *rq) + { +- return NULL; ++ /* the optimizer will remove all calls to this function */ ++ return (struct bio_vec){ }; + } + #endif /* CONFIG_BLK_DEV_INTEGRITY */ + #endif /* _LINUX_BLK_INTEGRITY_H */ +diff --git a/include/linux/clocksource.h b/include/linux/clocksource.h +index 1d42d4b173271..0ad8b550bb4b4 100644 +--- a/include/linux/clocksource.h ++++ b/include/linux/clocksource.h +@@ -291,7 +291,19 @@ static inline void timer_probe(void) {} + #define TIMER_ACPI_DECLARE(name, table_id, fn) \ + ACPI_DECLARE_PROBE_ENTRY(timer, name, table_id, 0, NULL, 0, fn) + +-extern ulong max_cswd_read_retries; ++static inline unsigned int clocksource_get_max_watchdog_retry(void) ++{ ++ /* ++ * When system is in the boot phase or under heavy workload, there ++ * can be random big latencies during the clocksource/watchdog ++ * read, so allow retries to filter the noise latency. As the ++ * latency's frequency and maximum value goes up with the number of ++ * CPUs, scale the number of retries with the number of online ++ * CPUs. ++ */ ++ return (ilog2(num_online_cpus()) / 2) + 1; ++} ++ + void clocksource_verify_percpu(struct clocksource *cs); + + #endif /* _LINUX_CLOCKSOURCE_H */ +diff --git a/include/linux/fs.h b/include/linux/fs.h +index ee5efad0d7801..56dce38c47862 100644 +--- a/include/linux/fs.h ++++ b/include/linux/fs.h +@@ -642,6 +642,7 @@ struct inode { + umode_t i_mode; + unsigned short i_opflags; + kuid_t i_uid; ++ struct list_head i_lru; /* inode LRU list */ + kgid_t i_gid; + unsigned int i_flags; + +@@ -703,7 +704,6 @@ struct inode { + u16 i_wb_frn_avg_time; + u16 i_wb_frn_history; + #endif +- struct list_head i_lru; /* inode LRU list */ + struct list_head i_sb_list; + struct list_head i_wb_list; /* backing dev writeback list */ + union { +diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h +index 0a85ff5c8db3c..abff4e3b6a58b 100644 +--- a/include/linux/pci_ids.h ++++ b/include/linux/pci_ids.h +@@ -2124,6 +2124,8 @@ + + #define PCI_VENDOR_ID_CHELSIO 0x1425 + ++#define PCI_VENDOR_ID_EDIMAX 0x1432 ++ + #define PCI_VENDOR_ID_ADLINK 0x144a + + #define PCI_VENDOR_ID_SAMSUNG 0x144d +diff --git a/include/linux/profile.h b/include/linux/profile.h +index 11db1ec516e27..12da750a88a04 100644 +--- a/include/linux/profile.h ++++ b/include/linux/profile.h +@@ -11,7 +11,6 @@ + + #define CPU_PROFILING 1 + #define SCHED_PROFILING 2 +-#define SLEEP_PROFILING 3 + #define KVM_PROFILING 4 + + struct proc_dir_entry; +diff --git a/include/linux/trace_events.h b/include/linux/trace_events.h +index 696f8dc4aa53c..cb8bd759e8005 100644 +--- a/include/linux/trace_events.h ++++ b/include/linux/trace_events.h +@@ -869,7 +869,6 @@ do { \ + struct perf_event; + + DECLARE_PER_CPU(struct pt_regs, perf_trace_regs); +-DECLARE_PER_CPU(int, bpf_kprobe_override); + + extern int perf_trace_init(struct perf_event *event); + extern void perf_trace_destroy(struct perf_event *event); +diff --git a/include/linux/virtio_net.h b/include/linux/virtio_net.h +index d1d7825318c32..6c395a2600e8d 100644 +--- a/include/linux/virtio_net.h ++++ b/include/linux/virtio_net.h +@@ -56,7 +56,6 @@ static inline int virtio_net_hdr_to_skb(struct sk_buff *skb, + unsigned int thlen = 0; + unsigned int p_off = 0; + unsigned int ip_proto; +- u64 ret, remainder, gso_size; + + if (hdr->gso_type != VIRTIO_NET_HDR_GSO_NONE) { + switch (hdr->gso_type & ~VIRTIO_NET_HDR_GSO_ECN) { +@@ -99,16 +98,6 @@ static inline int virtio_net_hdr_to_skb(struct sk_buff *skb, + u32 off = __virtio16_to_cpu(little_endian, hdr->csum_offset); + u32 needed = start + max_t(u32, thlen, off + sizeof(__sum16)); + +- if (hdr->gso_size) { +- gso_size = __virtio16_to_cpu(little_endian, hdr->gso_size); +- ret = div64_u64_rem(skb->len, gso_size, &remainder); +- if (!(ret && (hdr->gso_size > needed) && +- ((remainder > needed) || (remainder == 0)))) { +- return -EINVAL; +- } +- skb_shinfo(skb)->tx_flags |= SKBFL_SHARED_FRAG; +- } +- + if (!pskb_may_pull(skb, needed)) + return -EINVAL; + +@@ -182,6 +171,11 @@ static inline int virtio_net_hdr_to_skb(struct sk_buff *skb, + if (gso_type != SKB_GSO_UDP_L4) + return -EINVAL; + break; ++ case SKB_GSO_TCPV4: ++ case SKB_GSO_TCPV6: ++ if (skb->csum_offset != offsetof(struct tcphdr, check)) ++ return -EINVAL; ++ break; + } + + /* Kernel has a special handling for GSO_BY_FRAGS. */ +diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h +index b32539bb0fb05..61cfc8891f820 100644 +--- a/include/net/ip6_route.h ++++ b/include/net/ip6_route.h +@@ -128,18 +128,26 @@ void rt6_age_exceptions(struct fib6_info *f6i, struct fib6_gc_args *gc_args, + + static inline int ip6_route_get_saddr(struct net *net, struct fib6_info *f6i, + const struct in6_addr *daddr, +- unsigned int prefs, ++ unsigned int prefs, int l3mdev_index, + struct in6_addr *saddr) + { ++ struct net_device *l3mdev; ++ struct net_device *dev; ++ bool same_vrf; + int err = 0; + +- if (f6i && f6i->fib6_prefsrc.plen) { ++ rcu_read_lock(); ++ ++ l3mdev = dev_get_by_index_rcu(net, l3mdev_index); ++ if (!f6i || !f6i->fib6_prefsrc.plen || l3mdev) ++ dev = f6i ? fib6_info_nh_dev(f6i) : NULL; ++ same_vrf = !l3mdev || l3mdev_master_dev_rcu(dev) == l3mdev; ++ if (f6i && f6i->fib6_prefsrc.plen && same_vrf) + *saddr = f6i->fib6_prefsrc.addr; +- } else { +- struct net_device *dev = f6i ? fib6_info_nh_dev(f6i) : NULL; ++ else ++ err = ipv6_dev_get_saddr(net, same_vrf ? dev : l3mdev, daddr, prefs, saddr); + +- err = ipv6_dev_get_saddr(net, dev, daddr, prefs, saddr); +- } ++ rcu_read_unlock(); + + return err; + } +diff --git a/include/trace/events/intel_ifs.h b/include/trace/events/intel_ifs.h +index d7353024016cc..af0af3f1d9b7c 100644 +--- a/include/trace/events/intel_ifs.h ++++ b/include/trace/events/intel_ifs.h +@@ -10,25 +10,25 @@ + + TRACE_EVENT(ifs_status, + +- TP_PROTO(int cpu, union ifs_scan activate, union ifs_status status), ++ TP_PROTO(int cpu, int start, int stop, u64 status), + +- TP_ARGS(cpu, activate, status), ++ TP_ARGS(cpu, start, stop, status), + + TP_STRUCT__entry( + __field( u64, status ) + __field( int, cpu ) +- __field( u8, start ) +- __field( u8, stop ) ++ __field( u16, start ) ++ __field( u16, stop ) + ), + + TP_fast_assign( + __entry->cpu = cpu; +- __entry->start = activate.start; +- __entry->stop = activate.stop; +- __entry->status = status.data; ++ __entry->start = start; ++ __entry->stop = stop; ++ __entry->status = status; + ), + +- TP_printk("cpu: %d, start: %.2x, stop: %.2x, status: %llx", ++ TP_printk("cpu: %d, start: %.4x, stop: %.4x, status: %.16llx", + __entry->cpu, + __entry->start, + __entry->stop, +diff --git a/kernel/irq/irqdesc.c b/kernel/irq/irqdesc.c +index 5c9888901ef44..46094f0c9fcda 100644 +--- a/kernel/irq/irqdesc.c ++++ b/kernel/irq/irqdesc.c +@@ -517,6 +517,7 @@ static int alloc_descs(unsigned int start, unsigned int cnt, int node, + flags = IRQD_AFFINITY_MANAGED | + IRQD_MANAGED_SHUTDOWN; + } ++ flags |= IRQD_AFFINITY_SET; + mask = &affinity->mask; + node = cpu_to_node(cpumask_first(mask)); + affinity++; +diff --git a/kernel/jump_label.c b/kernel/jump_label.c +index eec802175ccc6..1ed269b2c4035 100644 +--- a/kernel/jump_label.c ++++ b/kernel/jump_label.c +@@ -231,7 +231,7 @@ void static_key_disable_cpuslocked(struct static_key *key) + } + + jump_label_lock(); +- if (atomic_cmpxchg(&key->enabled, 1, 0)) ++ if (atomic_cmpxchg(&key->enabled, 1, 0) == 1) + jump_label_update(key); + jump_label_unlock(); + } +@@ -284,7 +284,7 @@ static void __static_key_slow_dec_cpuslocked(struct static_key *key) + return; + + guard(mutex)(&jump_label_mutex); +- if (atomic_cmpxchg(&key->enabled, 1, 0)) ++ if (atomic_cmpxchg(&key->enabled, 1, 0) == 1) + jump_label_update(key); + else + WARN_ON_ONCE(!static_key_slow_try_dec(key)); +diff --git a/kernel/kcov.c b/kernel/kcov.c +index 9f4affae4fad4..72d9aa6fb50c3 100644 +--- a/kernel/kcov.c ++++ b/kernel/kcov.c +@@ -161,6 +161,15 @@ static void kcov_remote_area_put(struct kcov_remote_area *area, + kmsan_unpoison_memory(&area->list, sizeof(area->list)); + } + ++/* ++ * Unlike in_serving_softirq(), this function returns false when called during ++ * a hardirq or an NMI that happened in the softirq context. ++ */ ++static inline bool in_softirq_really(void) ++{ ++ return in_serving_softirq() && !in_hardirq() && !in_nmi(); ++} ++ + static notrace bool check_kcov_mode(enum kcov_mode needed_mode, struct task_struct *t) + { + unsigned int mode; +@@ -170,7 +179,7 @@ static notrace bool check_kcov_mode(enum kcov_mode needed_mode, struct task_stru + * so we ignore code executed in interrupts, unless we are in a remote + * coverage collection section in a softirq. + */ +- if (!in_task() && !(in_serving_softirq() && t->kcov_softirq)) ++ if (!in_task() && !(in_softirq_really() && t->kcov_softirq)) + return false; + mode = READ_ONCE(t->kcov_mode); + /* +@@ -848,7 +857,7 @@ void kcov_remote_start(u64 handle) + + if (WARN_ON(!kcov_check_handle(handle, true, true, true))) + return; +- if (!in_task() && !in_serving_softirq()) ++ if (!in_task() && !in_softirq_really()) + return; + + local_lock_irqsave(&kcov_percpu_data.lock, flags); +@@ -990,7 +999,7 @@ void kcov_remote_stop(void) + int sequence; + unsigned long flags; + +- if (!in_task() && !in_serving_softirq()) ++ if (!in_task() && !in_softirq_really()) + return; + + local_lock_irqsave(&kcov_percpu_data.lock, flags); +diff --git a/kernel/kprobes.c b/kernel/kprobes.c +index add63428c0b40..c10954bd84448 100644 +--- a/kernel/kprobes.c ++++ b/kernel/kprobes.c +@@ -1558,8 +1558,8 @@ static bool is_cfi_preamble_symbol(unsigned long addr) + if (lookup_symbol_name(addr, symbuf)) + return false; + +- return str_has_prefix("__cfi_", symbuf) || +- str_has_prefix("__pfx_", symbuf); ++ return str_has_prefix(symbuf, "__cfi_") || ++ str_has_prefix(symbuf, "__pfx_"); + } + + static int check_kprobe_address_safe(struct kprobe *p, +diff --git a/kernel/module/main.c b/kernel/module/main.c +index 34d9e718c2c7d..b00e31721a73e 100644 +--- a/kernel/module/main.c ++++ b/kernel/module/main.c +@@ -3081,7 +3081,7 @@ static bool idempotent(struct idempotent *u, const void *cookie) + struct idempotent *existing; + bool first; + +- u->ret = 0; ++ u->ret = -EINTR; + u->cookie = cookie; + init_completion(&u->complete); + +@@ -3117,7 +3117,7 @@ static int idempotent_complete(struct idempotent *u, int ret) + hlist_for_each_entry_safe(pos, next, head, entry) { + if (pos->cookie != cookie) + continue; +- hlist_del(&pos->entry); ++ hlist_del_init(&pos->entry); + pos->ret = ret; + complete(&pos->complete); + } +@@ -3125,6 +3125,28 @@ static int idempotent_complete(struct idempotent *u, int ret) + return ret; + } + ++/* ++ * Wait for the idempotent worker. ++ * ++ * If we get interrupted, we need to remove ourselves from the ++ * the idempotent list, and the completion may still come in. ++ * ++ * The 'idem_lock' protects against the race, and 'idem.ret' was ++ * initialized to -EINTR and is thus always the right return ++ * value even if the idempotent work then completes between ++ * the wait_for_completion and the cleanup. ++ */ ++static int idempotent_wait_for_completion(struct idempotent *u) ++{ ++ if (wait_for_completion_interruptible(&u->complete)) { ++ spin_lock(&idem_lock); ++ if (!hlist_unhashed(&u->entry)) ++ hlist_del(&u->entry); ++ spin_unlock(&idem_lock); ++ } ++ return u->ret; ++} ++ + static int init_module_from_file(struct file *f, const char __user * uargs, int flags) + { + struct load_info info = { }; +@@ -3160,15 +3182,16 @@ static int idempotent_init_module(struct file *f, const char __user * uargs, int + if (!f || !(f->f_mode & FMODE_READ)) + return -EBADF; + +- /* See if somebody else is doing the operation? */ +- if (idempotent(&idem, file_inode(f))) { +- wait_for_completion(&idem.complete); +- return idem.ret; ++ /* Are we the winners of the race and get to do this? */ ++ if (!idempotent(&idem, file_inode(f))) { ++ int ret = init_module_from_file(f, uargs, flags); ++ return idempotent_complete(&idem, ret); + } + +- /* Otherwise, we'll do it and complete others */ +- return idempotent_complete(&idem, +- init_module_from_file(f, uargs, flags)); ++ /* ++ * Somebody else won the race and is loading the module. ++ */ ++ return idempotent_wait_for_completion(&idem); + } + + SYSCALL_DEFINE3(finit_module, int, fd, const char __user *, uargs, int, flags) +diff --git a/kernel/padata.c b/kernel/padata.c +index c974568f65f5d..29545dd6dd53d 100644 +--- a/kernel/padata.c ++++ b/kernel/padata.c +@@ -516,6 +516,13 @@ void __init padata_do_multithreaded(struct padata_mt_job *job) + ps.chunk_size = max(ps.chunk_size, job->min_chunk); + ps.chunk_size = roundup(ps.chunk_size, job->align); + ++ /* ++ * chunk_size can be 0 if the caller sets min_chunk to 0. So force it ++ * to at least 1 to prevent divide-by-0 panic in padata_mt_helper().` ++ */ ++ if (!ps.chunk_size) ++ ps.chunk_size = 1U; ++ + list_for_each_entry(pw, &works, pw_list) + queue_work(system_unbound_wq, &pw->pw_work); + +diff --git a/kernel/profile.c b/kernel/profile.c +index 8a77769bc4b4c..984f819b701c9 100644 +--- a/kernel/profile.c ++++ b/kernel/profile.c +@@ -57,20 +57,11 @@ static DEFINE_MUTEX(profile_flip_mutex); + int profile_setup(char *str) + { + static const char schedstr[] = "schedule"; +- static const char sleepstr[] = "sleep"; + static const char kvmstr[] = "kvm"; + const char *select = NULL; + int par; + +- if (!strncmp(str, sleepstr, strlen(sleepstr))) { +-#ifdef CONFIG_SCHEDSTATS +- force_schedstat_enabled(); +- prof_on = SLEEP_PROFILING; +- select = sleepstr; +-#else +- pr_warn("kernel sleep profiling requires CONFIG_SCHEDSTATS\n"); +-#endif /* CONFIG_SCHEDSTATS */ +- } else if (!strncmp(str, schedstr, strlen(schedstr))) { ++ if (!strncmp(str, schedstr, strlen(schedstr))) { + prof_on = SCHED_PROFILING; + select = schedstr; + } else if (!strncmp(str, kvmstr, strlen(kvmstr))) { +diff --git a/kernel/rcu/rcutorture.c b/kernel/rcu/rcutorture.c +index 781146600aa49..46612fb15fc6d 100644 +--- a/kernel/rcu/rcutorture.c ++++ b/kernel/rcu/rcutorture.c +@@ -2592,7 +2592,7 @@ static void rcu_torture_fwd_cb_cr(struct rcu_head *rhp) + spin_lock_irqsave(&rfp->rcu_fwd_lock, flags); + rfcpp = rfp->rcu_fwd_cb_tail; + rfp->rcu_fwd_cb_tail = &rfcp->rfc_next; +- WRITE_ONCE(*rfcpp, rfcp); ++ smp_store_release(rfcpp, rfcp); + WRITE_ONCE(rfp->n_launders_cb, rfp->n_launders_cb + 1); + i = ((jiffies - rfp->rcu_fwd_startat) / (HZ / FWD_CBS_HIST_DIV)); + if (i >= ARRAY_SIZE(rfp->n_launders_hist)) +diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c +index 8cf6a6fef7965..583cc29080764 100644 +--- a/kernel/rcu/tree.c ++++ b/kernel/rcu/tree.c +@@ -4595,11 +4595,15 @@ void rcutree_migrate_callbacks(int cpu) + struct rcu_data *rdp = per_cpu_ptr(&rcu_data, cpu); + bool needwake; + +- if (rcu_rdp_is_offloaded(rdp) || +- rcu_segcblist_empty(&rdp->cblist)) +- return; /* No callbacks to migrate. */ ++ if (rcu_rdp_is_offloaded(rdp)) ++ return; + + raw_spin_lock_irqsave(&rcu_state.barrier_lock, flags); ++ if (rcu_segcblist_empty(&rdp->cblist)) { ++ raw_spin_unlock_irqrestore(&rcu_state.barrier_lock, flags); ++ return; /* No callbacks to migrate. */ ++ } ++ + WARN_ON_ONCE(rcu_rdp_cpu_online(rdp)); + rcu_barrier_entrain(rdp); + my_rdp = this_cpu_ptr(&rcu_data); +diff --git a/kernel/sched/core.c b/kernel/sched/core.c +index 92e4afeb71add..97571d390f184 100644 +--- a/kernel/sched/core.c ++++ b/kernel/sched/core.c +@@ -9596,6 +9596,30 @@ void set_rq_offline(struct rq *rq) + } + } + ++static inline void sched_set_rq_online(struct rq *rq, int cpu) ++{ ++ struct rq_flags rf; ++ ++ rq_lock_irqsave(rq, &rf); ++ if (rq->rd) { ++ BUG_ON(!cpumask_test_cpu(cpu, rq->rd->span)); ++ set_rq_online(rq); ++ } ++ rq_unlock_irqrestore(rq, &rf); ++} ++ ++static inline void sched_set_rq_offline(struct rq *rq, int cpu) ++{ ++ struct rq_flags rf; ++ ++ rq_lock_irqsave(rq, &rf); ++ if (rq->rd) { ++ BUG_ON(!cpumask_test_cpu(cpu, rq->rd->span)); ++ set_rq_offline(rq); ++ } ++ rq_unlock_irqrestore(rq, &rf); ++} ++ + /* + * used to mark begin/end of suspend/resume: + */ +@@ -9646,10 +9670,25 @@ static int cpuset_cpu_inactive(unsigned int cpu) + return 0; + } + ++static inline void sched_smt_present_inc(int cpu) ++{ ++#ifdef CONFIG_SCHED_SMT ++ if (cpumask_weight(cpu_smt_mask(cpu)) == 2) ++ static_branch_inc_cpuslocked(&sched_smt_present); ++#endif ++} ++ ++static inline void sched_smt_present_dec(int cpu) ++{ ++#ifdef CONFIG_SCHED_SMT ++ if (cpumask_weight(cpu_smt_mask(cpu)) == 2) ++ static_branch_dec_cpuslocked(&sched_smt_present); ++#endif ++} ++ + int sched_cpu_activate(unsigned int cpu) + { + struct rq *rq = cpu_rq(cpu); +- struct rq_flags rf; + + /* + * Clear the balance_push callback and prepare to schedule +@@ -9657,13 +9696,10 @@ int sched_cpu_activate(unsigned int cpu) + */ + balance_push_set(cpu, false); + +-#ifdef CONFIG_SCHED_SMT + /* + * When going up, increment the number of cores with SMT present. + */ +- if (cpumask_weight(cpu_smt_mask(cpu)) == 2) +- static_branch_inc_cpuslocked(&sched_smt_present); +-#endif ++ sched_smt_present_inc(cpu); + set_cpu_active(cpu, true); + + if (sched_smp_initialized) { +@@ -9681,12 +9717,7 @@ int sched_cpu_activate(unsigned int cpu) + * 2) At runtime, if cpuset_cpu_active() fails to rebuild the + * domains. + */ +- rq_lock_irqsave(rq, &rf); +- if (rq->rd) { +- BUG_ON(!cpumask_test_cpu(cpu, rq->rd->span)); +- set_rq_online(rq); +- } +- rq_unlock_irqrestore(rq, &rf); ++ sched_set_rq_online(rq, cpu); + + return 0; + } +@@ -9694,7 +9725,6 @@ int sched_cpu_activate(unsigned int cpu) + int sched_cpu_deactivate(unsigned int cpu) + { + struct rq *rq = cpu_rq(cpu); +- struct rq_flags rf; + int ret; + + /* +@@ -9725,20 +9755,14 @@ int sched_cpu_deactivate(unsigned int cpu) + */ + synchronize_rcu(); + +- rq_lock_irqsave(rq, &rf); +- if (rq->rd) { +- BUG_ON(!cpumask_test_cpu(cpu, rq->rd->span)); +- set_rq_offline(rq); +- } +- rq_unlock_irqrestore(rq, &rf); ++ sched_set_rq_offline(rq, cpu); + +-#ifdef CONFIG_SCHED_SMT + /* + * When going down, decrement the number of cores with SMT present. + */ +- if (cpumask_weight(cpu_smt_mask(cpu)) == 2) +- static_branch_dec_cpuslocked(&sched_smt_present); ++ sched_smt_present_dec(cpu); + ++#ifdef CONFIG_SCHED_SMT + sched_core_cpu_deactivate(cpu); + #endif + +@@ -9748,6 +9772,8 @@ int sched_cpu_deactivate(unsigned int cpu) + sched_update_numa(cpu, false); + ret = cpuset_cpu_inactive(cpu); + if (ret) { ++ sched_smt_present_inc(cpu); ++ sched_set_rq_online(rq, cpu); + balance_push_set(cpu, false); + set_cpu_active(cpu, true); + sched_update_numa(cpu, true); +diff --git a/kernel/sched/cputime.c b/kernel/sched/cputime.c +index af7952f12e6cf..b453f8a6a7c76 100644 +--- a/kernel/sched/cputime.c ++++ b/kernel/sched/cputime.c +@@ -595,6 +595,12 @@ void cputime_adjust(struct task_cputime *curr, struct prev_cputime *prev, + } + + stime = mul_u64_u64_div_u64(stime, rtime, stime + utime); ++ /* ++ * Because mul_u64_u64_div_u64() can approximate on some ++ * achitectures; enforce the constraint that: a*b/(b+c) <= a. ++ */ ++ if (unlikely(stime > rtime)) ++ stime = rtime; + + update: + /* +diff --git a/kernel/sched/stats.c b/kernel/sched/stats.c +index 857f837f52cbe..966f4eacfe51d 100644 +--- a/kernel/sched/stats.c ++++ b/kernel/sched/stats.c +@@ -92,16 +92,6 @@ void __update_stats_enqueue_sleeper(struct rq *rq, struct task_struct *p, + + trace_sched_stat_blocked(p, delta); + +- /* +- * Blocking time is in units of nanosecs, so shift by +- * 20 to get a milliseconds-range estimation of the +- * amount of time that the task spent sleeping: +- */ +- if (unlikely(prof_on == SLEEP_PROFILING)) { +- profile_hits(SLEEP_PROFILING, +- (void *)get_wchan(p), +- delta >> 20); +- } + account_scheduler_latency(p, delta >> 10, 0); + } + } +diff --git a/kernel/time/clocksource-wdtest.c b/kernel/time/clocksource-wdtest.c +index df922f49d171b..d06185e054ea2 100644 +--- a/kernel/time/clocksource-wdtest.c ++++ b/kernel/time/clocksource-wdtest.c +@@ -104,8 +104,8 @@ static void wdtest_ktime_clocksource_reset(void) + static int wdtest_func(void *arg) + { + unsigned long j1, j2; ++ int i, max_retries; + char *s; +- int i; + + schedule_timeout_uninterruptible(holdoff * HZ); + +@@ -139,18 +139,19 @@ static int wdtest_func(void *arg) + WARN_ON_ONCE(time_before(j2, j1 + NSEC_PER_USEC)); + + /* Verify tsc-like stability with various numbers of errors injected. */ +- for (i = 0; i <= max_cswd_read_retries + 1; i++) { +- if (i <= 1 && i < max_cswd_read_retries) ++ max_retries = clocksource_get_max_watchdog_retry(); ++ for (i = 0; i <= max_retries + 1; i++) { ++ if (i <= 1 && i < max_retries) + s = ""; +- else if (i <= max_cswd_read_retries) ++ else if (i <= max_retries) + s = ", expect message"; + else + s = ", expect clock skew"; +- pr_info("--- Watchdog with %dx error injection, %lu retries%s.\n", i, max_cswd_read_retries, s); ++ pr_info("--- Watchdog with %dx error injection, %d retries%s.\n", i, max_retries, s); + WRITE_ONCE(wdtest_ktime_read_ndelays, i); + schedule_timeout_uninterruptible(2 * HZ); + WARN_ON_ONCE(READ_ONCE(wdtest_ktime_read_ndelays)); +- WARN_ON_ONCE((i <= max_cswd_read_retries) != ++ WARN_ON_ONCE((i <= max_retries) != + !(clocksource_wdtest_ktime.flags & CLOCK_SOURCE_UNSTABLE)); + wdtest_ktime_clocksource_reset(); + } +diff --git a/kernel/time/clocksource.c b/kernel/time/clocksource.c +index 3052b1f1168e2..3260bbe98894b 100644 +--- a/kernel/time/clocksource.c ++++ b/kernel/time/clocksource.c +@@ -210,9 +210,6 @@ void clocksource_mark_unstable(struct clocksource *cs) + spin_unlock_irqrestore(&watchdog_lock, flags); + } + +-ulong max_cswd_read_retries = 2; +-module_param(max_cswd_read_retries, ulong, 0644); +-EXPORT_SYMBOL_GPL(max_cswd_read_retries); + static int verify_n_cpus = 8; + module_param(verify_n_cpus, int, 0644); + +@@ -224,11 +221,12 @@ enum wd_read_status { + + static enum wd_read_status cs_watchdog_read(struct clocksource *cs, u64 *csnow, u64 *wdnow) + { +- unsigned int nretries; ++ unsigned int nretries, max_retries; + u64 wd_end, wd_end2, wd_delta; + int64_t wd_delay, wd_seq_delay; + +- for (nretries = 0; nretries <= max_cswd_read_retries; nretries++) { ++ max_retries = clocksource_get_max_watchdog_retry(); ++ for (nretries = 0; nretries <= max_retries; nretries++) { + local_irq_disable(); + *wdnow = watchdog->read(watchdog); + *csnow = cs->read(cs); +@@ -240,7 +238,7 @@ static enum wd_read_status cs_watchdog_read(struct clocksource *cs, u64 *csnow, + wd_delay = clocksource_cyc2ns(wd_delta, watchdog->mult, + watchdog->shift); + if (wd_delay <= WATCHDOG_MAX_SKEW) { +- if (nretries > 1 || nretries >= max_cswd_read_retries) { ++ if (nretries > 1 && nretries >= max_retries) { + pr_warn("timekeeping watchdog on CPU%d: %s retried %d times before success\n", + smp_processor_id(), watchdog->name, nretries); + } +diff --git a/kernel/time/ntp.c b/kernel/time/ntp.c +index 406dccb79c2b6..8d2dd214ec682 100644 +--- a/kernel/time/ntp.c ++++ b/kernel/time/ntp.c +@@ -727,17 +727,16 @@ static inline void process_adjtimex_modes(const struct __kernel_timex *txc, + } + + if (txc->modes & ADJ_MAXERROR) +- time_maxerror = txc->maxerror; ++ time_maxerror = clamp(txc->maxerror, 0, NTP_PHASE_LIMIT); + + if (txc->modes & ADJ_ESTERROR) +- time_esterror = txc->esterror; ++ time_esterror = clamp(txc->esterror, 0, NTP_PHASE_LIMIT); + + if (txc->modes & ADJ_TIMECONST) { +- time_constant = txc->constant; ++ time_constant = clamp(txc->constant, 0, MAXTC); + if (!(time_status & STA_NANO)) + time_constant += 4; +- time_constant = min(time_constant, (long)MAXTC); +- time_constant = max(time_constant, 0l); ++ time_constant = clamp(time_constant, 0, MAXTC); + } + + if (txc->modes & ADJ_TAI && +diff --git a/kernel/time/tick-broadcast.c b/kernel/time/tick-broadcast.c +index b4843099a8da7..ed58eebb4e8f4 100644 +--- a/kernel/time/tick-broadcast.c ++++ b/kernel/time/tick-broadcast.c +@@ -1141,7 +1141,6 @@ void tick_broadcast_switch_to_oneshot(void) + #ifdef CONFIG_HOTPLUG_CPU + void hotplug_cpu__broadcast_tick_pull(int deadcpu) + { +- struct tick_device *td = this_cpu_ptr(&tick_cpu_device); + struct clock_event_device *bc; + unsigned long flags; + +@@ -1167,6 +1166,8 @@ void hotplug_cpu__broadcast_tick_pull(int deadcpu) + * device to avoid the starvation. + */ + if (tick_check_broadcast_expired()) { ++ struct tick_device *td = this_cpu_ptr(&tick_cpu_device); ++ + cpumask_clear_cpu(smp_processor_id(), tick_broadcast_force_mask); + tick_program_event(td->evtdev->next_event, 1); + } +diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c +index 8aab7ed414907..11b7000d5e1d4 100644 +--- a/kernel/time/timekeeping.c ++++ b/kernel/time/timekeeping.c +@@ -2476,7 +2476,7 @@ int do_adjtimex(struct __kernel_timex *txc) + clock_set |= timekeeping_advance(TK_ADV_FREQ); + + if (clock_set) +- clock_was_set(CLOCK_REALTIME); ++ clock_was_set(CLOCK_SET_WALL); + + ntp_notify_cmos_timer(); + +diff --git a/kernel/trace/tracing_map.c b/kernel/trace/tracing_map.c +index a4dcf0f243521..3a56e7c8aa4f6 100644 +--- a/kernel/trace/tracing_map.c ++++ b/kernel/trace/tracing_map.c +@@ -454,7 +454,7 @@ static struct tracing_map_elt *get_free_elt(struct tracing_map *map) + struct tracing_map_elt *elt = NULL; + int idx; + +- idx = atomic_inc_return(&map->next_elt); ++ idx = atomic_fetch_add_unless(&map->next_elt, 1, map->max_elts); + if (idx < map->max_elts) { + elt = *(TRACING_MAP_ELT(map->elts, idx)); + if (map->ops && map->ops->elt_init) +@@ -699,7 +699,7 @@ void tracing_map_clear(struct tracing_map *map) + { + unsigned int i; + +- atomic_set(&map->next_elt, -1); ++ atomic_set(&map->next_elt, 0); + atomic64_set(&map->hits, 0); + atomic64_set(&map->drops, 0); + +@@ -783,7 +783,7 @@ struct tracing_map *tracing_map_create(unsigned int map_bits, + + map->map_bits = map_bits; + map->max_elts = (1 << map_bits); +- atomic_set(&map->next_elt, -1); ++ atomic_set(&map->next_elt, 0); + + map->map_size = (1 << (map_bits + 1)); + map->ops = ops; +diff --git a/mm/huge_memory.c b/mm/huge_memory.c +index 79fbd6ddec49f..7ac2877e76629 100644 +--- a/mm/huge_memory.c ++++ b/mm/huge_memory.c +@@ -37,6 +37,7 @@ + #include <linux/page_owner.h> + #include <linux/sched/sysctl.h> + #include <linux/memory-tiers.h> ++#include <linux/compat.h> + + #include <asm/tlb.h> + #include <asm/pgalloc.h> +@@ -601,6 +602,9 @@ static unsigned long __thp_get_unmapped_area(struct file *filp, + loff_t off_align = round_up(off, size); + unsigned long len_pad, ret; + ++ if (!IS_ENABLED(CONFIG_64BIT) || in_compat_syscall()) ++ return 0; ++ + if (off_end <= off_align || (off_end - off_align) < size) + return 0; + +diff --git a/mm/hugetlb.c b/mm/hugetlb.c +index a480affd475bf..fb7a531fce717 100644 +--- a/mm/hugetlb.c ++++ b/mm/hugetlb.c +@@ -1769,13 +1769,6 @@ static void __update_and_free_hugetlb_folio(struct hstate *h, + return; + } + +- /* +- * Move PageHWPoison flag from head page to the raw error pages, +- * which makes any healthy subpages reusable. +- */ +- if (unlikely(folio_test_hwpoison(folio))) +- folio_clear_hugetlb_hwpoison(folio); +- + /* + * If vmemmap pages were allocated above, then we need to clear the + * hugetlb destructor under the hugetlb lock. +@@ -1786,6 +1779,13 @@ static void __update_and_free_hugetlb_folio(struct hstate *h, + spin_unlock_irq(&hugetlb_lock); + } + ++ /* ++ * Move PageHWPoison flag from head page to the raw error pages, ++ * which makes any healthy subpages reusable. ++ */ ++ if (unlikely(folio_test_hwpoison(folio))) ++ folio_clear_hugetlb_hwpoison(folio); ++ + /* + * Non-gigantic pages demoted from CMA allocated gigantic pages + * need to be given back to CMA in free_gigantic_folio. +diff --git a/mm/memcontrol.c b/mm/memcontrol.c +index dd854cc65fd9d..fd1b707f5de40 100644 +--- a/mm/memcontrol.c ++++ b/mm/memcontrol.c +@@ -5167,11 +5167,28 @@ static struct cftype mem_cgroup_legacy_files[] = { + + #define MEM_CGROUP_ID_MAX ((1UL << MEM_CGROUP_ID_SHIFT) - 1) + static DEFINE_IDR(mem_cgroup_idr); ++static DEFINE_SPINLOCK(memcg_idr_lock); ++ ++static int mem_cgroup_alloc_id(void) ++{ ++ int ret; ++ ++ idr_preload(GFP_KERNEL); ++ spin_lock(&memcg_idr_lock); ++ ret = idr_alloc(&mem_cgroup_idr, NULL, 1, MEM_CGROUP_ID_MAX + 1, ++ GFP_NOWAIT); ++ spin_unlock(&memcg_idr_lock); ++ idr_preload_end(); ++ return ret; ++} + + static void mem_cgroup_id_remove(struct mem_cgroup *memcg) + { + if (memcg->id.id > 0) { ++ spin_lock(&memcg_idr_lock); + idr_remove(&mem_cgroup_idr, memcg->id.id); ++ spin_unlock(&memcg_idr_lock); ++ + memcg->id.id = 0; + } + } +@@ -5294,8 +5311,7 @@ static struct mem_cgroup *mem_cgroup_alloc(void) + if (!memcg) + return ERR_PTR(error); + +- memcg->id.id = idr_alloc(&mem_cgroup_idr, NULL, +- 1, MEM_CGROUP_ID_MAX + 1, GFP_KERNEL); ++ memcg->id.id = mem_cgroup_alloc_id(); + if (memcg->id.id < 0) { + error = memcg->id.id; + goto fail; +@@ -5430,7 +5446,9 @@ static int mem_cgroup_css_online(struct cgroup_subsys_state *css) + * publish it here at the end of onlining. This matches the + * regular ID destruction during offlining. + */ ++ spin_lock(&memcg_idr_lock); + idr_replace(&mem_cgroup_idr, memcg, memcg->id.id); ++ spin_unlock(&memcg_idr_lock); + + return 0; + offline_kmem: +diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c +index 6dab0c99c82c7..38fee34887d8a 100644 +--- a/net/bluetooth/hci_sync.c ++++ b/net/bluetooth/hci_sync.c +@@ -2905,6 +2905,20 @@ static int hci_passive_scan_sync(struct hci_dev *hdev) + } else if (hci_is_adv_monitoring(hdev)) { + window = hdev->le_scan_window_adv_monitor; + interval = hdev->le_scan_int_adv_monitor; ++ ++ /* Disable duplicates filter when scanning for advertisement ++ * monitor for the following reasons. ++ * ++ * For HW pattern filtering (ex. MSFT), Realtek and Qualcomm ++ * controllers ignore RSSI_Sampling_Period when the duplicates ++ * filter is enabled. ++ * ++ * For SW pattern filtering, when we're not doing interleaved ++ * scanning, it is necessary to disable duplicates filter, ++ * otherwise hosts can only receive one advertisement and it's ++ * impossible to know if a peer is still in range. ++ */ ++ filter_dups = LE_SCAN_FILTER_DUP_DISABLE; + } else { + window = hdev->le_scan_window; + interval = hdev->le_scan_interval; +diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c +index 1164c6d927281..2651cc2d5c283 100644 +--- a/net/bluetooth/l2cap_core.c ++++ b/net/bluetooth/l2cap_core.c +@@ -6775,6 +6775,7 @@ static void l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, + bt_cb(skb)->l2cap.psm = psm; + + if (!chan->ops->recv(chan, skb)) { ++ l2cap_chan_unlock(chan); + l2cap_chan_put(chan); + return; + } +diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c +index 38373b4fb7ddf..c38244d60ff86 100644 +--- a/net/bridge/br_multicast.c ++++ b/net/bridge/br_multicast.c +@@ -2044,16 +2044,14 @@ void br_multicast_del_port(struct net_bridge_port *port) + { + struct net_bridge *br = port->br; + struct net_bridge_port_group *pg; +- HLIST_HEAD(deleted_head); + struct hlist_node *n; + + /* Take care of the remaining groups, only perm ones should be left */ + spin_lock_bh(&br->multicast_lock); + hlist_for_each_entry_safe(pg, n, &port->mglist, mglist) + br_multicast_find_del_pg(br, pg); +- hlist_move_list(&br->mcast_gc_list, &deleted_head); + spin_unlock_bh(&br->multicast_lock); +- br_multicast_gc(&deleted_head); ++ flush_work(&br->mcast_gc_work); + br_multicast_port_ctx_deinit(&port->multicast_ctx); + free_percpu(port->mcast_stats); + } +diff --git a/net/core/link_watch.c b/net/core/link_watch.c +index cb43f5aebfbcc..cf867f6e38bf1 100644 +--- a/net/core/link_watch.c ++++ b/net/core/link_watch.c +@@ -153,9 +153,9 @@ static void linkwatch_schedule_work(int urgent) + * override the existing timer. + */ + if (test_bit(LW_URGENT, &linkwatch_flags)) +- mod_delayed_work(system_wq, &linkwatch_work, 0); ++ mod_delayed_work(system_unbound_wq, &linkwatch_work, 0); + else +- schedule_delayed_work(&linkwatch_work, delay); ++ queue_delayed_work(system_unbound_wq, &linkwatch_work, delay); + } + + +diff --git a/net/ipv4/tcp_offload.c b/net/ipv4/tcp_offload.c +index 8311c38267b55..69e6012ae82fb 100644 +--- a/net/ipv4/tcp_offload.c ++++ b/net/ipv4/tcp_offload.c +@@ -73,6 +73,9 @@ struct sk_buff *tcp_gso_segment(struct sk_buff *skb, + if (thlen < sizeof(*th)) + goto out; + ++ if (unlikely(skb_checksum_start(skb) != skb_transport_header(skb))) ++ goto out; ++ + if (!pskb_may_pull(skb, thlen)) + goto out; + +diff --git a/net/ipv4/udp_offload.c b/net/ipv4/udp_offload.c +index e5971890d637d..9cb13a50011ef 100644 +--- a/net/ipv4/udp_offload.c ++++ b/net/ipv4/udp_offload.c +@@ -278,6 +278,10 @@ struct sk_buff *__udp_gso_segment(struct sk_buff *gso_skb, + if (gso_skb->len <= sizeof(*uh) + mss) + return ERR_PTR(-EINVAL); + ++ if (unlikely(skb_checksum_start(gso_skb) != ++ skb_transport_header(gso_skb))) ++ return ERR_PTR(-EINVAL); ++ + if (skb_gso_ok(gso_skb, features | NETIF_F_GSO_ROBUST)) { + /* Packet is from an untrusted source, reset gso_segs. */ + skb_shinfo(gso_skb)->gso_segs = DIV_ROUND_UP(gso_skb->len - sizeof(*uh), +diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c +index f97cb368e5a81..db8d0e1bf69ff 100644 +--- a/net/ipv6/ip6_output.c ++++ b/net/ipv6/ip6_output.c +@@ -1122,6 +1122,7 @@ static int ip6_dst_lookup_tail(struct net *net, const struct sock *sk, + from = rt ? rcu_dereference(rt->from) : NULL; + err = ip6_route_get_saddr(net, from, &fl6->daddr, + sk ? inet6_sk(sk)->srcprefs : 0, ++ fl6->flowi6_l3mdev, + &fl6->saddr); + rcu_read_unlock(); + +diff --git a/net/ipv6/route.c b/net/ipv6/route.c +index eb3afaee62e8f..49ef5623c55e2 100644 +--- a/net/ipv6/route.c ++++ b/net/ipv6/route.c +@@ -5678,7 +5678,7 @@ static int rt6_fill_node(struct net *net, struct sk_buff *skb, + goto nla_put_failure; + } else if (dest) { + struct in6_addr saddr_buf; +- if (ip6_route_get_saddr(net, rt, dest, 0, &saddr_buf) == 0 && ++ if (ip6_route_get_saddr(net, rt, dest, 0, 0, &saddr_buf) == 0 && + nla_put_in6_addr(skb, RTA_PREFSRC, &saddr_buf)) + goto nla_put_failure; + } +diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c +index 8d21ff25f1602..70da78ab95202 100644 +--- a/net/l2tp/l2tp_core.c ++++ b/net/l2tp/l2tp_core.c +@@ -88,6 +88,11 @@ + /* Default trace flags */ + #define L2TP_DEFAULT_DEBUG_FLAGS 0 + ++#define L2TP_DEPTH_NESTING 2 ++#if L2TP_DEPTH_NESTING == SINGLE_DEPTH_NESTING ++#error "L2TP requires its own lockdep subclass" ++#endif ++ + /* Private data stored for received packets in the skb. + */ + struct l2tp_skb_cb { +@@ -1041,7 +1046,13 @@ static int l2tp_xmit_core(struct l2tp_session *session, struct sk_buff *skb, uns + IPCB(skb)->flags &= ~(IPSKB_XFRM_TUNNEL_SIZE | IPSKB_XFRM_TRANSFORMED | IPSKB_REROUTED); + nf_reset_ct(skb); + +- bh_lock_sock_nested(sk); ++ /* L2TP uses its own lockdep subclass to avoid lockdep splats caused by ++ * nested socket calls on the same lockdep socket class. This can ++ * happen when data from a user socket is routed over l2tp, which uses ++ * another userspace socket. ++ */ ++ spin_lock_nested(&sk->sk_lock.slock, L2TP_DEPTH_NESTING); ++ + if (sock_owned_by_user(sk)) { + kfree_skb(skb); + ret = NET_XMIT_DROP; +@@ -1093,7 +1104,7 @@ static int l2tp_xmit_core(struct l2tp_session *session, struct sk_buff *skb, uns + ret = l2tp_xmit_queue(tunnel, skb, &inet->cork.fl); + + out_unlock: +- bh_unlock_sock(sk); ++ spin_unlock(&sk->sk_lock.slock); + + return ret; + } +diff --git a/net/mptcp/options.c b/net/mptcp/options.c +index 85aafa94cc8ab..604724cca887f 100644 +--- a/net/mptcp/options.c ++++ b/net/mptcp/options.c +@@ -958,7 +958,8 @@ static bool check_fully_established(struct mptcp_sock *msk, struct sock *ssk, + + if (subflow->remote_key_valid && + (((mp_opt->suboptions & OPTION_MPTCP_DSS) && mp_opt->use_ack) || +- ((mp_opt->suboptions & OPTION_MPTCP_ADD_ADDR) && !mp_opt->echo))) { ++ ((mp_opt->suboptions & OPTION_MPTCP_ADD_ADDR) && ++ (!mp_opt->echo || subflow->mp_join)))) { + /* subflows are fully established as soon as we get any + * additional ack, including ADD_ADDR. + */ +diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c +index d8da5374d9e13..cf70a376398be 100644 +--- a/net/mptcp/pm.c ++++ b/net/mptcp/pm.c +@@ -427,6 +427,18 @@ int mptcp_pm_get_local_id(struct mptcp_sock *msk, struct sock_common *skc) + return mptcp_pm_nl_get_local_id(msk, &skc_local); + } + ++bool mptcp_pm_is_backup(struct mptcp_sock *msk, struct sock_common *skc) ++{ ++ struct mptcp_addr_info skc_local; ++ ++ mptcp_local_address((struct sock_common *)skc, &skc_local); ++ ++ if (mptcp_pm_is_userspace(msk)) ++ return mptcp_userspace_pm_is_backup(msk, &skc_local); ++ ++ return mptcp_pm_nl_is_backup(msk, &skc_local); ++} ++ + int mptcp_pm_get_flags_and_ifindex_by_id(struct mptcp_sock *msk, unsigned int id, + u8 *flags, int *ifindex) + { +diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c +index db621933b2035..2c49182c674f3 100644 +--- a/net/mptcp/pm_netlink.c ++++ b/net/mptcp/pm_netlink.c +@@ -353,7 +353,7 @@ bool mptcp_pm_alloc_anno_list(struct mptcp_sock *msk, + add_entry = mptcp_lookup_anno_list_by_saddr(msk, addr); + + if (add_entry) { +- if (mptcp_pm_is_kernel(msk)) ++ if (WARN_ON_ONCE(mptcp_pm_is_kernel(msk))) + return false; + + sk_reset_timer(sk, &add_entry->add_timer, +@@ -520,8 +520,8 @@ __lookup_addr(struct pm_nl_pernet *pernet, const struct mptcp_addr_info *info, + + static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk) + { ++ struct mptcp_pm_addr_entry *local, *signal_and_subflow = NULL; + struct sock *sk = (struct sock *)msk; +- struct mptcp_pm_addr_entry *local; + unsigned int add_addr_signal_max; + unsigned int local_addr_max; + struct pm_nl_pernet *pernet; +@@ -563,8 +563,6 @@ static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk) + + /* check first for announce */ + if (msk->pm.add_addr_signaled < add_addr_signal_max) { +- local = select_signal_address(pernet, msk); +- + /* due to racing events on both ends we can reach here while + * previous add address is still running: if we invoke now + * mptcp_pm_announce_addr(), that will fail and the +@@ -575,16 +573,26 @@ static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk) + if (msk->pm.addr_signal & BIT(MPTCP_ADD_ADDR_SIGNAL)) + return; + +- if (local) { +- if (mptcp_pm_alloc_anno_list(msk, &local->addr)) { +- __clear_bit(local->addr.id, msk->pm.id_avail_bitmap); +- msk->pm.add_addr_signaled++; +- mptcp_pm_announce_addr(msk, &local->addr, false); +- mptcp_pm_nl_addr_send_ack(msk); +- } +- } ++ local = select_signal_address(pernet, msk); ++ if (!local) ++ goto subflow; ++ ++ /* If the alloc fails, we are on memory pressure, not worth ++ * continuing, and trying to create subflows. ++ */ ++ if (!mptcp_pm_alloc_anno_list(msk, &local->addr)) ++ return; ++ ++ __clear_bit(local->addr.id, msk->pm.id_avail_bitmap); ++ msk->pm.add_addr_signaled++; ++ mptcp_pm_announce_addr(msk, &local->addr, false); ++ mptcp_pm_nl_addr_send_ack(msk); ++ ++ if (local->flags & MPTCP_PM_ADDR_FLAG_SUBFLOW) ++ signal_and_subflow = local; + } + ++subflow: + /* check if should create a new subflow */ + while (msk->pm.local_addr_used < local_addr_max && + msk->pm.subflows < subflows_max) { +@@ -592,9 +600,14 @@ static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk) + bool fullmesh; + int i, nr; + +- local = select_local_address(pernet, msk); +- if (!local) +- break; ++ if (signal_and_subflow) { ++ local = signal_and_subflow; ++ signal_and_subflow = NULL; ++ } else { ++ local = select_local_address(pernet, msk); ++ if (!local) ++ break; ++ } + + fullmesh = !!(local->flags & MPTCP_PM_ADDR_FLAG_FULLMESH); + +@@ -1109,6 +1122,24 @@ int mptcp_pm_nl_get_local_id(struct mptcp_sock *msk, struct mptcp_addr_info *skc + return ret; + } + ++bool mptcp_pm_nl_is_backup(struct mptcp_sock *msk, struct mptcp_addr_info *skc) ++{ ++ struct pm_nl_pernet *pernet = pm_nl_get_pernet_from_msk(msk); ++ struct mptcp_pm_addr_entry *entry; ++ bool backup = false; ++ ++ rcu_read_lock(); ++ list_for_each_entry_rcu(entry, &pernet->local_addr_list, list) { ++ if (mptcp_addresses_equal(&entry->addr, skc, entry->addr.port)) { ++ backup = !!(entry->flags & MPTCP_PM_ADDR_FLAG_BACKUP); ++ break; ++ } ++ } ++ rcu_read_unlock(); ++ ++ return backup; ++} ++ + #define MPTCP_PM_CMD_GRP_OFFSET 0 + #define MPTCP_PM_EV_GRP_OFFSET 1 + +@@ -1341,8 +1372,8 @@ static int mptcp_nl_cmd_add_addr(struct sk_buff *skb, struct genl_info *info) + if (ret < 0) + return ret; + +- if (addr.addr.port && !(addr.flags & MPTCP_PM_ADDR_FLAG_SIGNAL)) { +- GENL_SET_ERR_MSG(info, "flags must have signal when using port"); ++ if (addr.addr.port && !address_use_port(&addr)) { ++ GENL_SET_ERR_MSG(info, "flags must have signal and not subflow when using port"); + return -EINVAL; + } + +diff --git a/net/mptcp/pm_userspace.c b/net/mptcp/pm_userspace.c +index f36f87a62dd0d..6738bad048cec 100644 +--- a/net/mptcp/pm_userspace.c ++++ b/net/mptcp/pm_userspace.c +@@ -157,6 +157,24 @@ int mptcp_userspace_pm_get_local_id(struct mptcp_sock *msk, + return mptcp_userspace_pm_append_new_local_addr(msk, &new_entry, true); + } + ++bool mptcp_userspace_pm_is_backup(struct mptcp_sock *msk, ++ struct mptcp_addr_info *skc) ++{ ++ struct mptcp_pm_addr_entry *entry; ++ bool backup = false; ++ ++ spin_lock_bh(&msk->pm.lock); ++ list_for_each_entry(entry, &msk->pm.userspace_pm_local_addr_list, list) { ++ if (mptcp_addresses_equal(&entry->addr, skc, false)) { ++ backup = !!(entry->flags & MPTCP_PM_ADDR_FLAG_BACKUP); ++ break; ++ } ++ } ++ spin_unlock_bh(&msk->pm.lock); ++ ++ return backup; ++} ++ + int mptcp_nl_cmd_announce(struct sk_buff *skb, struct genl_info *info) + { + struct nlattr *token = info->attrs[MPTCP_PM_ATTR_TOKEN]; +diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h +index c28ac5dfd0b58..0201b1004a3b9 100644 +--- a/net/mptcp/protocol.h ++++ b/net/mptcp/protocol.h +@@ -1032,6 +1032,9 @@ bool mptcp_pm_rm_addr_signal(struct mptcp_sock *msk, unsigned int remaining, + int mptcp_pm_get_local_id(struct mptcp_sock *msk, struct sock_common *skc); + int mptcp_pm_nl_get_local_id(struct mptcp_sock *msk, struct mptcp_addr_info *skc); + int mptcp_userspace_pm_get_local_id(struct mptcp_sock *msk, struct mptcp_addr_info *skc); ++bool mptcp_pm_is_backup(struct mptcp_sock *msk, struct sock_common *skc); ++bool mptcp_pm_nl_is_backup(struct mptcp_sock *msk, struct mptcp_addr_info *skc); ++bool mptcp_userspace_pm_is_backup(struct mptcp_sock *msk, struct mptcp_addr_info *skc); + + static inline u8 subflow_get_local_id(const struct mptcp_subflow_context *subflow) + { +diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c +index bc1efc1787720..927c2d5997dc7 100644 +--- a/net/mptcp/subflow.c ++++ b/net/mptcp/subflow.c +@@ -100,6 +100,7 @@ static struct mptcp_sock *subflow_token_join_request(struct request_sock *req) + return NULL; + } + subflow_req->local_id = local_id; ++ subflow_req->request_bkup = mptcp_pm_is_backup(msk, (struct sock_common *)req); + + return msk; + } +@@ -601,6 +602,8 @@ static int subflow_chk_local_id(struct sock *sk) + return err; + + subflow_set_local_id(subflow, err); ++ subflow->request_bkup = mptcp_pm_is_backup(msk, (struct sock_common *)sk); ++ + return 0; + } + +diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c +index dd044a47c8723..ea139fca74cb9 100644 +--- a/net/netfilter/nf_tables_api.c ++++ b/net/netfilter/nf_tables_api.c +@@ -3743,6 +3743,15 @@ static void nf_tables_rule_release(const struct nft_ctx *ctx, struct nft_rule *r + nf_tables_rule_destroy(ctx, rule); + } + ++/** nft_chain_validate - loop detection and hook validation ++ * ++ * @ctx: context containing call depth and base chain ++ * @chain: chain to validate ++ * ++ * Walk through the rules of the given chain and chase all jumps/gotos ++ * and set lookups until either the jump limit is hit or all reachable ++ * chains have been validated. ++ */ + int nft_chain_validate(const struct nft_ctx *ctx, const struct nft_chain *chain) + { + struct nft_expr *expr, *last; +@@ -3764,6 +3773,9 @@ int nft_chain_validate(const struct nft_ctx *ctx, const struct nft_chain *chain) + if (!expr->ops->validate) + continue; + ++ /* This may call nft_chain_validate() recursively, ++ * callers that do so must increment ctx->level. ++ */ + err = expr->ops->validate(ctx, expr, &data); + if (err < 0) + return err; +@@ -10621,146 +10633,6 @@ int nft_chain_validate_hooks(const struct nft_chain *chain, + } + EXPORT_SYMBOL_GPL(nft_chain_validate_hooks); + +-/* +- * Loop detection - walk through the ruleset beginning at the destination chain +- * of a new jump until either the source chain is reached (loop) or all +- * reachable chains have been traversed. +- * +- * The loop check is performed whenever a new jump verdict is added to an +- * expression or verdict map or a verdict map is bound to a new chain. +- */ +- +-static int nf_tables_check_loops(const struct nft_ctx *ctx, +- const struct nft_chain *chain); +- +-static int nft_check_loops(const struct nft_ctx *ctx, +- const struct nft_set_ext *ext) +-{ +- const struct nft_data *data; +- int ret; +- +- data = nft_set_ext_data(ext); +- switch (data->verdict.code) { +- case NFT_JUMP: +- case NFT_GOTO: +- ret = nf_tables_check_loops(ctx, data->verdict.chain); +- break; +- default: +- ret = 0; +- break; +- } +- +- return ret; +-} +- +-static int nf_tables_loop_check_setelem(const struct nft_ctx *ctx, +- struct nft_set *set, +- const struct nft_set_iter *iter, +- struct nft_set_elem *elem) +-{ +- const struct nft_set_ext *ext = nft_set_elem_ext(set, elem->priv); +- +- if (nft_set_ext_exists(ext, NFT_SET_EXT_FLAGS) && +- *nft_set_ext_flags(ext) & NFT_SET_ELEM_INTERVAL_END) +- return 0; +- +- return nft_check_loops(ctx, ext); +-} +- +-static int nft_set_catchall_loops(const struct nft_ctx *ctx, +- struct nft_set *set) +-{ +- u8 genmask = nft_genmask_next(ctx->net); +- struct nft_set_elem_catchall *catchall; +- struct nft_set_ext *ext; +- int ret = 0; +- +- list_for_each_entry_rcu(catchall, &set->catchall_list, list) { +- ext = nft_set_elem_ext(set, catchall->elem); +- if (!nft_set_elem_active(ext, genmask)) +- continue; +- +- ret = nft_check_loops(ctx, ext); +- if (ret < 0) +- return ret; +- } +- +- return ret; +-} +- +-static int nf_tables_check_loops(const struct nft_ctx *ctx, +- const struct nft_chain *chain) +-{ +- const struct nft_rule *rule; +- const struct nft_expr *expr, *last; +- struct nft_set *set; +- struct nft_set_binding *binding; +- struct nft_set_iter iter; +- +- if (ctx->chain == chain) +- return -ELOOP; +- +- if (fatal_signal_pending(current)) +- return -EINTR; +- +- list_for_each_entry(rule, &chain->rules, list) { +- nft_rule_for_each_expr(expr, last, rule) { +- struct nft_immediate_expr *priv; +- const struct nft_data *data; +- int err; +- +- if (strcmp(expr->ops->type->name, "immediate")) +- continue; +- +- priv = nft_expr_priv(expr); +- if (priv->dreg != NFT_REG_VERDICT) +- continue; +- +- data = &priv->data; +- switch (data->verdict.code) { +- case NFT_JUMP: +- case NFT_GOTO: +- err = nf_tables_check_loops(ctx, +- data->verdict.chain); +- if (err < 0) +- return err; +- break; +- default: +- break; +- } +- } +- } +- +- list_for_each_entry(set, &ctx->table->sets, list) { +- if (!nft_is_active_next(ctx->net, set)) +- continue; +- if (!(set->flags & NFT_SET_MAP) || +- set->dtype != NFT_DATA_VERDICT) +- continue; +- +- list_for_each_entry(binding, &set->bindings, list) { +- if (!(binding->flags & NFT_SET_MAP) || +- binding->chain != chain) +- continue; +- +- iter.genmask = nft_genmask_next(ctx->net); +- iter.skip = 0; +- iter.count = 0; +- iter.err = 0; +- iter.fn = nf_tables_loop_check_setelem; +- +- set->ops->walk(ctx, set, &iter); +- if (!iter.err) +- iter.err = nft_set_catchall_loops(ctx, set); +- +- if (iter.err < 0) +- return iter.err; +- } +- } +- +- return 0; +-} +- + /** + * nft_parse_u32_check - fetch u32 attribute and check for maximum value + * +@@ -10873,7 +10745,7 @@ static int nft_validate_register_store(const struct nft_ctx *ctx, + if (data != NULL && + (data->verdict.code == NFT_GOTO || + data->verdict.code == NFT_JUMP)) { +- err = nf_tables_check_loops(ctx, data->verdict.chain); ++ err = nft_chain_validate(ctx, data->verdict.chain); + if (err < 0) + return err; + } +diff --git a/net/sctp/input.c b/net/sctp/input.c +index 17fcaa9b0df94..a8a254a5008e5 100644 +--- a/net/sctp/input.c ++++ b/net/sctp/input.c +@@ -735,15 +735,19 @@ static int __sctp_hash_endpoint(struct sctp_endpoint *ep) + struct sock *sk = ep->base.sk; + struct net *net = sock_net(sk); + struct sctp_hashbucket *head; ++ int err = 0; + + ep->hashent = sctp_ep_hashfn(net, ep->base.bind_addr.port); + head = &sctp_ep_hashtable[ep->hashent]; + ++ write_lock(&head->lock); + if (sk->sk_reuseport) { + bool any = sctp_is_ep_boundall(sk); + struct sctp_endpoint *ep2; + struct list_head *list; +- int cnt = 0, err = 1; ++ int cnt = 0; ++ ++ err = 1; + + list_for_each(list, &ep->base.bind_addr.address_list) + cnt++; +@@ -761,24 +765,24 @@ static int __sctp_hash_endpoint(struct sctp_endpoint *ep) + if (!err) { + err = reuseport_add_sock(sk, sk2, any); + if (err) +- return err; ++ goto out; + break; + } else if (err < 0) { +- return err; ++ goto out; + } + } + + if (err) { + err = reuseport_alloc(sk, any); + if (err) +- return err; ++ goto out; + } + } + +- write_lock(&head->lock); + hlist_add_head(&ep->node, &head->chain); ++out: + write_unlock(&head->lock); +- return 0; ++ return err; + } + + /* Add an endpoint to the hash. Local BH-safe. */ +@@ -803,10 +807,9 @@ static void __sctp_unhash_endpoint(struct sctp_endpoint *ep) + + head = &sctp_ep_hashtable[ep->hashent]; + ++ write_lock(&head->lock); + if (rcu_access_pointer(sk->sk_reuseport_cb)) + reuseport_detach_sock(sk); +- +- write_lock(&head->lock); + hlist_del_init(&ep->node); + write_unlock(&head->lock); + } +diff --git a/net/smc/smc_stats.h b/net/smc/smc_stats.h +index 9d32058db2b5d..e19177ce40923 100644 +--- a/net/smc/smc_stats.h ++++ b/net/smc/smc_stats.h +@@ -19,7 +19,7 @@ + + #include "smc_clc.h" + +-#define SMC_MAX_FBACK_RSN_CNT 30 ++#define SMC_MAX_FBACK_RSN_CNT 36 + + enum { + SMC_BUF_8K, +diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c +index 6debf4fd42d4e..cef623ea15060 100644 +--- a/net/sunrpc/sched.c ++++ b/net/sunrpc/sched.c +@@ -369,8 +369,10 @@ static void rpc_make_runnable(struct workqueue_struct *wq, + if (RPC_IS_ASYNC(task)) { + INIT_WORK(&task->u.tk_work, rpc_async_schedule); + queue_work(wq, &task->u.tk_work); +- } else ++ } else { ++ smp_mb__after_atomic(); + wake_up_bit(&task->tk_runstate, RPC_TASK_QUEUED); ++ } + } + + /* +diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c +index a551be47cb6c6..b7f62442d8268 100644 +--- a/net/unix/af_unix.c ++++ b/net/unix/af_unix.c +@@ -1483,6 +1483,7 @@ static int unix_stream_connect(struct socket *sock, struct sockaddr *uaddr, + struct unix_sock *u = unix_sk(sk), *newu, *otheru; + struct net *net = sock_net(sk); + struct sk_buff *skb = NULL; ++ unsigned char state; + long timeo; + int err; + +@@ -1529,7 +1530,6 @@ static int unix_stream_connect(struct socket *sock, struct sockaddr *uaddr, + goto out; + } + +- /* Latch state of peer */ + unix_state_lock(other); + + /* Apparently VFS overslept socket death. Retry. */ +@@ -1559,37 +1559,21 @@ static int unix_stream_connect(struct socket *sock, struct sockaddr *uaddr, + goto restart; + } + +- /* Latch our state. +- +- It is tricky place. We need to grab our state lock and cannot +- drop lock on peer. It is dangerous because deadlock is +- possible. Connect to self case and simultaneous +- attempt to connect are eliminated by checking socket +- state. other is TCP_LISTEN, if sk is TCP_LISTEN we +- check this before attempt to grab lock. +- +- Well, and we have to recheck the state after socket locked. ++ /* self connect and simultaneous connect are eliminated ++ * by rejecting TCP_LISTEN socket to avoid deadlock. + */ +- switch (READ_ONCE(sk->sk_state)) { +- case TCP_CLOSE: +- /* This is ok... continue with connect */ +- break; +- case TCP_ESTABLISHED: +- /* Socket is already connected */ +- err = -EISCONN; +- goto out_unlock; +- default: +- err = -EINVAL; ++ state = READ_ONCE(sk->sk_state); ++ if (unlikely(state != TCP_CLOSE)) { ++ err = state == TCP_ESTABLISHED ? -EISCONN : -EINVAL; + goto out_unlock; + } + + unix_state_lock_nested(sk, U_LOCK_SECOND); + +- if (sk->sk_state != TCP_CLOSE) { ++ if (unlikely(sk->sk_state != TCP_CLOSE)) { ++ err = sk->sk_state == TCP_ESTABLISHED ? -EISCONN : -EINVAL; + unix_state_unlock(sk); +- unix_state_unlock(other); +- sock_put(other); +- goto restart; ++ goto out_unlock; + } + + err = security_unix_stream_connect(sk, other, newsk); +diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c +index 8f8f077e6cd40..be5c42d6ffbea 100644 +--- a/net/wireless/nl80211.c ++++ b/net/wireless/nl80211.c +@@ -3398,6 +3398,33 @@ static int __nl80211_set_channel(struct cfg80211_registered_device *rdev, + if (chandef.chan != cur_chan) + return -EBUSY; + ++ /* only allow this for regular channel widths */ ++ switch (wdev->links[link_id].ap.chandef.width) { ++ case NL80211_CHAN_WIDTH_20_NOHT: ++ case NL80211_CHAN_WIDTH_20: ++ case NL80211_CHAN_WIDTH_40: ++ case NL80211_CHAN_WIDTH_80: ++ case NL80211_CHAN_WIDTH_80P80: ++ case NL80211_CHAN_WIDTH_160: ++ case NL80211_CHAN_WIDTH_320: ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ switch (chandef.width) { ++ case NL80211_CHAN_WIDTH_20_NOHT: ++ case NL80211_CHAN_WIDTH_20: ++ case NL80211_CHAN_WIDTH_40: ++ case NL80211_CHAN_WIDTH_80: ++ case NL80211_CHAN_WIDTH_80P80: ++ case NL80211_CHAN_WIDTH_160: ++ case NL80211_CHAN_WIDTH_320: ++ break; ++ default: ++ return -EINVAL; ++ } ++ + result = rdev_set_ap_chanwidth(rdev, dev, link_id, + &chandef); + if (result) +@@ -4446,10 +4473,7 @@ static void get_key_callback(void *c, struct key_params *params) + struct nlattr *key; + struct get_key_cookie *cookie = c; + +- if ((params->key && +- nla_put(cookie->msg, NL80211_ATTR_KEY_DATA, +- params->key_len, params->key)) || +- (params->seq && ++ if ((params->seq && + nla_put(cookie->msg, NL80211_ATTR_KEY_SEQ, + params->seq_len, params->seq)) || + (params->cipher && +@@ -4461,10 +4485,7 @@ static void get_key_callback(void *c, struct key_params *params) + if (!key) + goto nla_put_failure; + +- if ((params->key && +- nla_put(cookie->msg, NL80211_KEY_DATA, +- params->key_len, params->key)) || +- (params->seq && ++ if ((params->seq && + nla_put(cookie->msg, NL80211_KEY_SEQ, + params->seq_len, params->seq)) || + (params->cipher && +diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c +index 038db8902c9ed..82c0d3a3327ab 100644 +--- a/sound/pci/hda/patch_hdmi.c ++++ b/sound/pci/hda/patch_hdmi.c +@@ -1989,6 +1989,8 @@ static int hdmi_add_cvt(struct hda_codec *codec, hda_nid_t cvt_nid) + } + + static const struct snd_pci_quirk force_connect_list[] = { ++ SND_PCI_QUIRK(0x103c, 0x83e2, "HP EliteDesk 800 G4", 1), ++ SND_PCI_QUIRK(0x103c, 0x83ef, "HP MP9 G4 Retail System AMS", 1), + SND_PCI_QUIRK(0x103c, 0x870f, "HP", 1), + SND_PCI_QUIRK(0x103c, 0x871a, "HP", 1), + SND_PCI_QUIRK(0x103c, 0x8711, "HP", 1), +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index 0b33a00771450..82dcea2b78000 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -10360,6 +10360,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x8086, 0x3038, "Intel NUC 13", ALC295_FIXUP_CHROME_BOOK), + SND_PCI_QUIRK(0xf111, 0x0001, "Framework Laptop", ALC295_FIXUP_FRAMEWORK_LAPTOP_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0xf111, 0x0006, "Framework Laptop", ALC295_FIXUP_FRAMEWORK_LAPTOP_MIC_NO_PRESENCE), ++ SND_PCI_QUIRK(0xf111, 0x0009, "Framework Laptop", ALC295_FIXUP_FRAMEWORK_LAPTOP_MIC_NO_PRESENCE), + + #if 0 + /* Below is a quirk table taken from the old code. +diff --git a/sound/soc/amd/yc/acp6x-mach.c b/sound/soc/amd/yc/acp6x-mach.c +index 36dddf230c2c4..d597e59863ee3 100644 +--- a/sound/soc/amd/yc/acp6x-mach.c ++++ b/sound/soc/amd/yc/acp6x-mach.c +@@ -409,6 +409,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = { + DMI_MATCH(DMI_BOARD_NAME, "8A43"), + } + }, ++ { ++ .driver_data = &acp6x_card, ++ .matches = { ++ DMI_MATCH(DMI_BOARD_VENDOR, "HP"), ++ DMI_MATCH(DMI_BOARD_NAME, "8A44"), ++ } ++ }, + { + .driver_data = &acp6x_card, + .matches = { +diff --git a/sound/soc/codecs/wcd938x-sdw.c b/sound/soc/codecs/wcd938x-sdw.c +index a1f04010da95f..132c1d24f8f6e 100644 +--- a/sound/soc/codecs/wcd938x-sdw.c ++++ b/sound/soc/codecs/wcd938x-sdw.c +@@ -1252,12 +1252,12 @@ static int wcd9380_probe(struct sdw_slave *pdev, + pdev->prop.lane_control_support = true; + pdev->prop.simple_clk_stop_capable = true; + if (wcd->is_tx) { +- pdev->prop.source_ports = GENMASK(WCD938X_MAX_SWR_PORTS, 0); ++ pdev->prop.source_ports = GENMASK(WCD938X_MAX_SWR_PORTS - 1, 0); + pdev->prop.src_dpn_prop = wcd938x_dpn_prop; + wcd->ch_info = &wcd938x_sdw_tx_ch_info[0]; + pdev->prop.wake_capable = true; + } else { +- pdev->prop.sink_ports = GENMASK(WCD938X_MAX_SWR_PORTS, 0); ++ pdev->prop.sink_ports = GENMASK(WCD938X_MAX_SWR_PORTS - 1, 0); + pdev->prop.sink_dpn_prop = wcd938x_dpn_prop; + wcd->ch_info = &wcd938x_sdw_rx_ch_info[0]; + } +diff --git a/sound/soc/codecs/wsa881x.c b/sound/soc/codecs/wsa881x.c +index 1253695bebd86..53b828f681020 100644 +--- a/sound/soc/codecs/wsa881x.c ++++ b/sound/soc/codecs/wsa881x.c +@@ -1152,7 +1152,7 @@ static int wsa881x_probe(struct sdw_slave *pdev, + wsa881x->sconfig.frame_rate = 48000; + wsa881x->sconfig.direction = SDW_DATA_DIR_RX; + wsa881x->sconfig.type = SDW_STREAM_PDM; +- pdev->prop.sink_ports = GENMASK(WSA881X_MAX_SWR_PORTS, 0); ++ pdev->prop.sink_ports = GENMASK(WSA881X_MAX_SWR_PORTS - 1, 0); + pdev->prop.sink_dpn_prop = wsa_sink_dpn_prop; + pdev->prop.scp_int1_mask = SDW_SCP_INT1_BUS_CLASH | SDW_SCP_INT1_PARITY; + pdev->prop.clk_stop_mode1 = true; +diff --git a/sound/soc/codecs/wsa883x.c b/sound/soc/codecs/wsa883x.c +index a2e86ef7d18f5..2169d93989841 100644 +--- a/sound/soc/codecs/wsa883x.c ++++ b/sound/soc/codecs/wsa883x.c +@@ -1399,7 +1399,15 @@ static int wsa883x_probe(struct sdw_slave *pdev, + wsa883x->sconfig.direction = SDW_DATA_DIR_RX; + wsa883x->sconfig.type = SDW_STREAM_PDM; + +- pdev->prop.sink_ports = GENMASK(WSA883X_MAX_SWR_PORTS, 0); ++ /** ++ * Port map index starts with 0, however the data port for this codec ++ * are from index 1 ++ */ ++ if (of_property_read_u32_array(dev->of_node, "qcom,port-mapping", &pdev->m_port_map[1], ++ WSA883X_MAX_SWR_PORTS)) ++ dev_dbg(dev, "Static Port mapping not specified\n"); ++ ++ pdev->prop.sink_ports = GENMASK(WSA883X_MAX_SWR_PORTS - 1, 0); + pdev->prop.simple_clk_stop_capable = true; + pdev->prop.sink_dpn_prop = wsa_sink_dpn_prop; + pdev->prop.scp_int1_mask = SDW_SCP_INT1_BUS_CLASH | SDW_SCP_INT1_PARITY; +diff --git a/sound/soc/codecs/wsa884x.c b/sound/soc/codecs/wsa884x.c +index 993d76b18b536..1cd52fab7b40d 100644 +--- a/sound/soc/codecs/wsa884x.c ++++ b/sound/soc/codecs/wsa884x.c +@@ -1858,7 +1858,15 @@ static int wsa884x_probe(struct sdw_slave *pdev, + wsa884x->sconfig.direction = SDW_DATA_DIR_RX; + wsa884x->sconfig.type = SDW_STREAM_PDM; + +- pdev->prop.sink_ports = GENMASK(WSA884X_MAX_SWR_PORTS, 0); ++ /** ++ * Port map index starts with 0, however the data port for this codec ++ * are from index 1 ++ */ ++ if (of_property_read_u32_array(dev->of_node, "qcom,port-mapping", &pdev->m_port_map[1], ++ WSA884X_MAX_SWR_PORTS)) ++ dev_dbg(dev, "Static Port mapping not specified\n"); ++ ++ pdev->prop.sink_ports = GENMASK(WSA884X_MAX_SWR_PORTS - 1, 0); + pdev->prop.simple_clk_stop_capable = true; + pdev->prop.sink_dpn_prop = wsa884x_sink_dpn_prop; + pdev->prop.scp_int1_mask = SDW_SCP_INT1_BUS_CLASH | SDW_SCP_INT1_PARITY; +diff --git a/sound/soc/meson/axg-fifo.c b/sound/soc/meson/axg-fifo.c +index 94b169a5493b5..5218e40aeb1bb 100644 +--- a/sound/soc/meson/axg-fifo.c ++++ b/sound/soc/meson/axg-fifo.c +@@ -207,25 +207,18 @@ static irqreturn_t axg_fifo_pcm_irq_block(int irq, void *dev_id) + status = FIELD_GET(STATUS1_INT_STS, status); + axg_fifo_ack_irq(fifo, status); + +- /* Use the thread to call period elapsed on nonatomic links */ +- if (status & FIFO_INT_COUNT_REPEAT) +- return IRQ_WAKE_THREAD; ++ if (status & ~FIFO_INT_COUNT_REPEAT) ++ dev_dbg(axg_fifo_dev(ss), "unexpected irq - STS 0x%02x\n", ++ status); + +- dev_dbg(axg_fifo_dev(ss), "unexpected irq - STS 0x%02x\n", +- status); ++ if (status & FIFO_INT_COUNT_REPEAT) { ++ snd_pcm_period_elapsed(ss); ++ return IRQ_HANDLED; ++ } + + return IRQ_NONE; + } + +-static irqreturn_t axg_fifo_pcm_irq_block_thread(int irq, void *dev_id) +-{ +- struct snd_pcm_substream *ss = dev_id; +- +- snd_pcm_period_elapsed(ss); +- +- return IRQ_HANDLED; +-} +- + int axg_fifo_pcm_open(struct snd_soc_component *component, + struct snd_pcm_substream *ss) + { +@@ -251,8 +244,9 @@ int axg_fifo_pcm_open(struct snd_soc_component *component, + if (ret) + return ret; + +- ret = request_threaded_irq(fifo->irq, axg_fifo_pcm_irq_block, +- axg_fifo_pcm_irq_block_thread, ++ /* Use the threaded irq handler only with non-atomic links */ ++ ret = request_threaded_irq(fifo->irq, NULL, ++ axg_fifo_pcm_irq_block, + IRQF_ONESHOT, dev_name(dev), ss); + if (ret) + return ret; +diff --git a/sound/soc/sof/mediatek/mt8195/mt8195.c b/sound/soc/sof/mediatek/mt8195/mt8195.c +index 7d6a568556ea4..b5b4ea854da4b 100644 +--- a/sound/soc/sof/mediatek/mt8195/mt8195.c ++++ b/sound/soc/sof/mediatek/mt8195/mt8195.c +@@ -624,7 +624,7 @@ static struct snd_sof_dsp_ops sof_mt8195_ops = { + static struct snd_sof_of_mach sof_mt8195_machs[] = { + { + .compatible = "google,tomato", +- .sof_tplg_filename = "sof-mt8195-mt6359-rt1019-rt5682-dts.tplg" ++ .sof_tplg_filename = "sof-mt8195-mt6359-rt1019-rt5682.tplg" + }, { + .compatible = "mediatek,mt8195", + .sof_tplg_filename = "sof-mt8195.tplg" +diff --git a/sound/soc/sti/sti_uniperif.c b/sound/soc/sti/sti_uniperif.c +index 2c21a86421e66..cc9a8122b9bc2 100644 +--- a/sound/soc/sti/sti_uniperif.c ++++ b/sound/soc/sti/sti_uniperif.c +@@ -352,7 +352,7 @@ static int sti_uniperiph_resume(struct snd_soc_component *component) + return ret; + } + +-static int sti_uniperiph_dai_probe(struct snd_soc_dai *dai) ++int sti_uniperiph_dai_probe(struct snd_soc_dai *dai) + { + struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai); + struct sti_uniperiph_dai *dai_data = &priv->dai_data; +diff --git a/sound/soc/sti/uniperif.h b/sound/soc/sti/uniperif.h +index 2a5de328501c1..74e51f0ff85c8 100644 +--- a/sound/soc/sti/uniperif.h ++++ b/sound/soc/sti/uniperif.h +@@ -1380,6 +1380,7 @@ int uni_reader_init(struct platform_device *pdev, + struct uniperif *reader); + + /* common */ ++int sti_uniperiph_dai_probe(struct snd_soc_dai *dai); + int sti_uniperiph_dai_set_fmt(struct snd_soc_dai *dai, + unsigned int fmt); + +diff --git a/sound/soc/sti/uniperif_player.c b/sound/soc/sti/uniperif_player.c +index dd9013c476649..6d1ce030963c6 100644 +--- a/sound/soc/sti/uniperif_player.c ++++ b/sound/soc/sti/uniperif_player.c +@@ -1038,6 +1038,7 @@ static const struct snd_soc_dai_ops uni_player_dai_ops = { + .startup = uni_player_startup, + .shutdown = uni_player_shutdown, + .prepare = uni_player_prepare, ++ .probe = sti_uniperiph_dai_probe, + .trigger = uni_player_trigger, + .hw_params = sti_uniperiph_dai_hw_params, + .set_fmt = sti_uniperiph_dai_set_fmt, +diff --git a/sound/soc/sti/uniperif_reader.c b/sound/soc/sti/uniperif_reader.c +index 065c5f0d1f5f0..05ea2b794eb92 100644 +--- a/sound/soc/sti/uniperif_reader.c ++++ b/sound/soc/sti/uniperif_reader.c +@@ -401,6 +401,7 @@ static const struct snd_soc_dai_ops uni_reader_dai_ops = { + .startup = uni_reader_startup, + .shutdown = uni_reader_shutdown, + .prepare = uni_reader_prepare, ++ .probe = sti_uniperiph_dai_probe, + .trigger = uni_reader_trigger, + .hw_params = sti_uniperiph_dai_hw_params, + .set_fmt = sti_uniperiph_dai_set_fmt, +diff --git a/sound/usb/line6/driver.c b/sound/usb/line6/driver.c +index f4437015d43a7..9df49a880b750 100644 +--- a/sound/usb/line6/driver.c ++++ b/sound/usb/line6/driver.c +@@ -286,12 +286,14 @@ static void line6_data_received(struct urb *urb) + { + struct usb_line6 *line6 = (struct usb_line6 *)urb->context; + struct midi_buffer *mb = &line6->line6midi->midibuf_in; ++ unsigned long flags; + int done; + + if (urb->status == -ESHUTDOWN) + return; + + if (line6->properties->capabilities & LINE6_CAP_CONTROL_MIDI) { ++ spin_lock_irqsave(&line6->line6midi->lock, flags); + done = + line6_midibuf_write(mb, urb->transfer_buffer, urb->actual_length); + +@@ -300,12 +302,15 @@ static void line6_data_received(struct urb *urb) + dev_dbg(line6->ifcdev, "%d %d buffer overflow - message skipped\n", + done, urb->actual_length); + } ++ spin_unlock_irqrestore(&line6->line6midi->lock, flags); + + for (;;) { ++ spin_lock_irqsave(&line6->line6midi->lock, flags); + done = + line6_midibuf_read(mb, line6->buffer_message, + LINE6_MIDI_MESSAGE_MAXLEN, + LINE6_MIDIBUF_READ_RX); ++ spin_unlock_irqrestore(&line6->line6midi->lock, flags); + + if (done <= 0) + break; +diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h +index 5d72dc8441cbb..af1b8cf5a9883 100644 +--- a/sound/usb/quirks-table.h ++++ b/sound/usb/quirks-table.h +@@ -2594,6 +2594,10 @@ YAMAHA_DEVICE(0x7010, "UB99"), + } + }, + ++/* Stanton ScratchAmp */ ++{ USB_DEVICE(0x103d, 0x0100) }, ++{ USB_DEVICE(0x103d, 0x0101) }, ++ + /* Novation EMS devices */ + { + USB_DEVICE_VENDOR_SPEC(0x1235, 0x0001), +diff --git a/tools/arch/arm64/include/asm/cputype.h b/tools/arch/arm64/include/asm/cputype.h +index 5f6f84837a490..329d41f8c9237 100644 +--- a/tools/arch/arm64/include/asm/cputype.h ++++ b/tools/arch/arm64/include/asm/cputype.h +@@ -84,6 +84,9 @@ + #define ARM_CPU_PART_CORTEX_X2 0xD48 + #define ARM_CPU_PART_NEOVERSE_N2 0xD49 + #define ARM_CPU_PART_CORTEX_A78C 0xD4B ++#define ARM_CPU_PART_NEOVERSE_V2 0xD4F ++#define ARM_CPU_PART_CORTEX_X4 0xD82 ++#define ARM_CPU_PART_NEOVERSE_V3 0xD84 + + #define APM_CPU_PART_POTENZA 0x000 + +@@ -153,6 +156,9 @@ + #define MIDR_CORTEX_X2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X2) + #define MIDR_NEOVERSE_N2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N2) + #define MIDR_CORTEX_A78C MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A78C) ++#define MIDR_NEOVERSE_V2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_V2) ++#define MIDR_CORTEX_X4 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X4) ++#define MIDR_NEOVERSE_V3 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_V3) + #define MIDR_THUNDERX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX) + #define MIDR_THUNDERX_81XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_81XX) + #define MIDR_THUNDERX_83XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_83XX) +diff --git a/tools/testing/selftests/bpf/prog_tests/send_signal.c b/tools/testing/selftests/bpf/prog_tests/send_signal.c +index b15b343ebb6b1..9adcda7f1fedc 100644 +--- a/tools/testing/selftests/bpf/prog_tests/send_signal.c ++++ b/tools/testing/selftests/bpf/prog_tests/send_signal.c +@@ -156,7 +156,8 @@ static void test_send_signal_tracepoint(bool signal_thread) + static void test_send_signal_perf(bool signal_thread) + { + struct perf_event_attr attr = { +- .sample_period = 1, ++ .freq = 1, ++ .sample_freq = 1000, + .type = PERF_TYPE_SOFTWARE, + .config = PERF_COUNT_SW_CPU_CLOCK, + }; +diff --git a/tools/testing/selftests/mm/Makefile b/tools/testing/selftests/mm/Makefile +index 292359a542429..8b2b9bb8bad10 100644 +--- a/tools/testing/selftests/mm/Makefile ++++ b/tools/testing/selftests/mm/Makefile +@@ -101,7 +101,7 @@ endif + + endif + +-ifneq (,$(filter $(ARCH),arm64 ia64 mips64 parisc64 powerpc riscv64 s390x sparc64 x86_64)) ++ifneq (,$(filter $(ARCH),arm64 ia64 mips64 parisc64 powerpc riscv64 s390x sparc64 x86_64 s390)) + TEST_GEN_FILES += va_high_addr_switch + TEST_GEN_FILES += virtual_address_range + TEST_GEN_FILES += write_to_hugetlbfs +diff --git a/tools/testing/selftests/net/mptcp/mptcp_join.sh b/tools/testing/selftests/net/mptcp/mptcp_join.sh +index a2dae2a3a93e0..b16b8278c4cea 100755 +--- a/tools/testing/selftests/net/mptcp/mptcp_join.sh ++++ b/tools/testing/selftests/net/mptcp/mptcp_join.sh +@@ -812,7 +812,7 @@ pm_nl_check_endpoint() + done + + if [ -z "$id" ]; then +- test_fail "bad test - missing endpoint id" ++ fail_test "bad test - missing endpoint id" + return + fi + +@@ -1559,18 +1559,28 @@ chk_add_nr() + local add_nr=$1 + local echo_nr=$2 + local port_nr=${3:-0} +- local syn_nr=${4:-$port_nr} +- local syn_ack_nr=${5:-$port_nr} +- local ack_nr=${6:-$port_nr} +- local mis_syn_nr=${7:-0} +- local mis_ack_nr=${8:-0} ++ local ns_invert=${4:-""} ++ local syn_nr=$port_nr ++ local syn_ack_nr=$port_nr ++ local ack_nr=$port_nr ++ local mis_syn_nr=0 ++ local mis_ack_nr=0 ++ local ns_tx=$ns1 ++ local ns_rx=$ns2 ++ local extra_msg="" + local count + local timeout + +- timeout=$(ip netns exec $ns1 sysctl -n net.mptcp.add_addr_timeout) ++ if [[ $ns_invert = "invert" ]]; then ++ ns_tx=$ns2 ++ ns_rx=$ns1 ++ extra_msg="invert" ++ fi ++ ++ timeout=$(ip netns exec ${ns_tx} sysctl -n net.mptcp.add_addr_timeout) + + print_check "add" +- count=$(mptcp_lib_get_counter ${ns2} "MPTcpExtAddAddr") ++ count=$(mptcp_lib_get_counter ${ns_rx} "MPTcpExtAddAddr") + if [ -z "$count" ]; then + print_skip + # if the test configured a short timeout tolerate greater then expected +@@ -1582,7 +1592,7 @@ chk_add_nr() + fi + + print_check "echo" +- count=$(mptcp_lib_get_counter ${ns1} "MPTcpExtEchoAdd") ++ count=$(mptcp_lib_get_counter ${ns_tx} "MPTcpExtEchoAdd") + if [ -z "$count" ]; then + print_skip + elif [ "$count" != "$echo_nr" ]; then +@@ -1593,7 +1603,7 @@ chk_add_nr() + + if [ $port_nr -gt 0 ]; then + print_check "pt" +- count=$(mptcp_lib_get_counter ${ns2} "MPTcpExtPortAdd") ++ count=$(mptcp_lib_get_counter ${ns_rx} "MPTcpExtPortAdd") + if [ -z "$count" ]; then + print_skip + elif [ "$count" != "$port_nr" ]; then +@@ -1603,7 +1613,7 @@ chk_add_nr() + fi + + print_check "syn" +- count=$(mptcp_lib_get_counter ${ns1} "MPTcpExtMPJoinPortSynRx") ++ count=$(mptcp_lib_get_counter ${ns_tx} "MPTcpExtMPJoinPortSynRx") + if [ -z "$count" ]; then + print_skip + elif [ "$count" != "$syn_nr" ]; then +@@ -1614,7 +1624,7 @@ chk_add_nr() + fi + + print_check "synack" +- count=$(mptcp_lib_get_counter ${ns2} "MPTcpExtMPJoinPortSynAckRx") ++ count=$(mptcp_lib_get_counter ${ns_rx} "MPTcpExtMPJoinPortSynAckRx") + if [ -z "$count" ]; then + print_skip + elif [ "$count" != "$syn_ack_nr" ]; then +@@ -1625,7 +1635,7 @@ chk_add_nr() + fi + + print_check "ack" +- count=$(mptcp_lib_get_counter ${ns1} "MPTcpExtMPJoinPortAckRx") ++ count=$(mptcp_lib_get_counter ${ns_tx} "MPTcpExtMPJoinPortAckRx") + if [ -z "$count" ]; then + print_skip + elif [ "$count" != "$ack_nr" ]; then +@@ -1636,7 +1646,7 @@ chk_add_nr() + fi + + print_check "syn" +- count=$(mptcp_lib_get_counter ${ns1} "MPTcpExtMismatchPortSynRx") ++ count=$(mptcp_lib_get_counter ${ns_tx} "MPTcpExtMismatchPortSynRx") + if [ -z "$count" ]; then + print_skip + elif [ "$count" != "$mis_syn_nr" ]; then +@@ -1647,7 +1657,7 @@ chk_add_nr() + fi + + print_check "ack" +- count=$(mptcp_lib_get_counter ${ns1} "MPTcpExtMismatchPortAckRx") ++ count=$(mptcp_lib_get_counter ${ns_tx} "MPTcpExtMismatchPortAckRx") + if [ -z "$count" ]; then + print_skip + elif [ "$count" != "$mis_ack_nr" ]; then +@@ -1657,6 +1667,8 @@ chk_add_nr() + print_ok + fi + fi ++ ++ print_info "$extra_msg" + } + + chk_add_tx_nr() +@@ -2121,6 +2133,21 @@ signal_address_tests() + chk_add_nr 1 1 + fi + ++ # uncommon: subflow and signal flags on the same endpoint ++ # or because the user wrongly picked both, but still expects the client ++ # to create additional subflows ++ if reset "subflow and signal together"; then ++ pm_nl_set_limits $ns1 0 2 ++ pm_nl_set_limits $ns2 0 2 ++ pm_nl_add_endpoint $ns2 10.0.3.2 flags signal,subflow ++ run_tests $ns1 $ns2 10.0.1.1 ++ chk_join_nr 1 1 1 ++ chk_add_nr 1 1 0 invert # only initiated by ns2 ++ chk_add_nr 0 0 0 # none initiated by ns1 ++ chk_rst_nr 0 0 invert # no RST sent by the client ++ chk_rst_nr 0 0 # no RST sent by the server ++ fi ++ + # accept and use add_addr with additional subflows + if reset "multiple subflows and signal"; then + pm_nl_set_limits $ns1 0 3 +diff --git a/tools/testing/selftests/net/mptcp/simult_flows.sh b/tools/testing/selftests/net/mptcp/simult_flows.sh +index be97a7ed09503..f24bd2bf08311 100755 +--- a/tools/testing/selftests/net/mptcp/simult_flows.sh ++++ b/tools/testing/selftests/net/mptcp/simult_flows.sh +@@ -262,7 +262,7 @@ run_test() + do_transfer $small $large $time + lret=$? + mptcp_lib_result_code "${lret}" "${msg}" +- if [ $lret -ne 0 ] && ! mptcp_lib_subtest_is_flaky; then ++ if [ $lret -ne 0 ]; then + ret=$lret + [ $bail -eq 0 ] || exit $ret + fi +@@ -272,7 +272,7 @@ run_test() + do_transfer $large $small $time + lret=$? + mptcp_lib_result_code "${lret}" "${msg}" +- if [ $lret -ne 0 ] && ! mptcp_lib_subtest_is_flaky; then ++ if [ $lret -ne 0 ]; then + ret=$lret + [ $bail -eq 0 ] || exit $ret + fi +@@ -305,7 +305,7 @@ run_test 10 10 0 0 "balanced bwidth" + run_test 10 10 1 25 "balanced bwidth with unbalanced delay" + + # we still need some additional infrastructure to pass the following test-cases +-MPTCP_LIB_SUBTEST_FLAKY=1 run_test 10 3 0 0 "unbalanced bwidth" ++run_test 10 3 0 0 "unbalanced bwidth" + run_test 10 3 1 25 "unbalanced bwidth with unbalanced delay" + run_test 10 3 25 1 "unbalanced bwidth with opposed, unbalanced delay" + +diff --git a/tools/testing/selftests/rcutorture/bin/torture.sh b/tools/testing/selftests/rcutorture/bin/torture.sh +index 12b50a4a881ac..89a82f6f140ef 100755 +--- a/tools/testing/selftests/rcutorture/bin/torture.sh ++++ b/tools/testing/selftests/rcutorture/bin/torture.sh +@@ -567,7 +567,7 @@ then + torture_bootargs="rcupdate.rcu_cpu_stall_suppress_at_boot=1 torture.disable_onoff_at_boot rcupdate.rcu_task_stall_timeout=30000 tsc=watchdog" + torture_set "clocksourcewd-1" tools/testing/selftests/rcutorture/bin/kvm.sh --allcpus --duration 45s --configs TREE03 --kconfig "CONFIG_TEST_CLOCKSOURCE_WATCHDOG=y" --trust-make + +- torture_bootargs="rcupdate.rcu_cpu_stall_suppress_at_boot=1 torture.disable_onoff_at_boot rcupdate.rcu_task_stall_timeout=30000 clocksource.max_cswd_read_retries=1 tsc=watchdog" ++ torture_bootargs="rcupdate.rcu_cpu_stall_suppress_at_boot=1 torture.disable_onoff_at_boot rcupdate.rcu_task_stall_timeout=30000 tsc=watchdog" + torture_set "clocksourcewd-2" tools/testing/selftests/rcutorture/bin/kvm.sh --allcpus --duration 45s --configs TREE03 --kconfig "CONFIG_TEST_CLOCKSOURCE_WATCHDOG=y" --trust-make + + # In case our work is already done... |