diff --git a/patch/kernel/archive/odroidxu4-5.4/patch-5.4.251-252.patch b/patch/kernel/archive/odroidxu4-5.4/patch-5.4.251-252.patch new file mode 100644 index 000000000000..c230d38f9342 --- /dev/null +++ b/patch/kernel/archive/odroidxu4-5.4/patch-5.4.251-252.patch @@ -0,0 +1,2163 @@ +diff --git a/Documentation/ABI/testing/sysfs-devices-system-cpu b/Documentation/ABI/testing/sysfs-devices-system-cpu +index 726ac2e01b777..08e153614e094 100644 +--- a/Documentation/ABI/testing/sysfs-devices-system-cpu ++++ b/Documentation/ABI/testing/sysfs-devices-system-cpu +@@ -480,16 +480,17 @@ Description: information about CPUs heterogeneity. + cpu_capacity: capacity of cpu#. + + What: /sys/devices/system/cpu/vulnerabilities ++ /sys/devices/system/cpu/vulnerabilities/gather_data_sampling ++ /sys/devices/system/cpu/vulnerabilities/itlb_multihit ++ /sys/devices/system/cpu/vulnerabilities/l1tf ++ /sys/devices/system/cpu/vulnerabilities/mds + /sys/devices/system/cpu/vulnerabilities/meltdown ++ /sys/devices/system/cpu/vulnerabilities/mmio_stale_data ++ /sys/devices/system/cpu/vulnerabilities/spec_store_bypass + /sys/devices/system/cpu/vulnerabilities/spectre_v1 + /sys/devices/system/cpu/vulnerabilities/spectre_v2 +- /sys/devices/system/cpu/vulnerabilities/spec_store_bypass +- /sys/devices/system/cpu/vulnerabilities/l1tf +- /sys/devices/system/cpu/vulnerabilities/mds + /sys/devices/system/cpu/vulnerabilities/srbds + /sys/devices/system/cpu/vulnerabilities/tsx_async_abort +- /sys/devices/system/cpu/vulnerabilities/itlb_multihit +- /sys/devices/system/cpu/vulnerabilities/mmio_stale_data + Date: January 2018 + Contact: Linux kernel mailing list + Description: Information about CPU vulnerabilities +diff --git a/Documentation/admin-guide/hw-vuln/gather_data_sampling.rst b/Documentation/admin-guide/hw-vuln/gather_data_sampling.rst +new file mode 100644 +index 0000000000000..264bfa937f7de +--- /dev/null ++++ b/Documentation/admin-guide/hw-vuln/gather_data_sampling.rst +@@ -0,0 +1,109 @@ ++.. SPDX-License-Identifier: GPL-2.0 ++ ++GDS - Gather Data Sampling ++========================== ++ ++Gather Data Sampling is a hardware vulnerability which allows unprivileged ++speculative access to data which was previously stored in vector registers. ++ ++Problem ++------- ++When a gather instruction performs loads from memory, different data elements ++are merged into the destination vector register. However, when a gather ++instruction that is transiently executed encounters a fault, stale data from ++architectural or internal vector registers may get transiently forwarded to the ++destination vector register instead. This will allow a malicious attacker to ++infer stale data using typical side channel techniques like cache timing ++attacks. GDS is a purely sampling-based attack. ++ ++The attacker uses gather instructions to infer the stale vector register data. ++The victim does not need to do anything special other than use the vector ++registers. The victim does not need to use gather instructions to be ++vulnerable. ++ ++Because the buffers are shared between Hyper-Threads cross Hyper-Thread attacks ++are possible. ++ ++Attack scenarios ++---------------- ++Without mitigation, GDS can infer stale data across virtually all ++permission boundaries: ++ ++ Non-enclaves can infer SGX enclave data ++ Userspace can infer kernel data ++ Guests can infer data from hosts ++ Guest can infer guest from other guests ++ Users can infer data from other users ++ ++Because of this, it is important to ensure that the mitigation stays enabled in ++lower-privilege contexts like guests and when running outside SGX enclaves. ++ ++The hardware enforces the mitigation for SGX. Likewise, VMMs should ensure ++that guests are not allowed to disable the GDS mitigation. If a host erred and ++allowed this, a guest could theoretically disable GDS mitigation, mount an ++attack, and re-enable it. ++ ++Mitigation mechanism ++-------------------- ++This issue is mitigated in microcode. The microcode defines the following new ++bits: ++ ++ ================================ === ============================ ++ IA32_ARCH_CAPABILITIES[GDS_CTRL] R/O Enumerates GDS vulnerability ++ and mitigation support. ++ IA32_ARCH_CAPABILITIES[GDS_NO] R/O Processor is not vulnerable. ++ IA32_MCU_OPT_CTRL[GDS_MITG_DIS] R/W Disables the mitigation ++ 0 by default. ++ IA32_MCU_OPT_CTRL[GDS_MITG_LOCK] R/W Locks GDS_MITG_DIS=0. Writes ++ to GDS_MITG_DIS are ignored ++ Can't be cleared once set. ++ ================================ === ============================ ++ ++GDS can also be mitigated on systems that don't have updated microcode by ++disabling AVX. This can be done by setting gather_data_sampling="force" or ++"clearcpuid=avx" on the kernel command-line. ++ ++If used, these options will disable AVX use by turning off XSAVE YMM support. ++However, the processor will still enumerate AVX support. Userspace that ++does not follow proper AVX enumeration to check both AVX *and* XSAVE YMM ++support will break. ++ ++Mitigation control on the kernel command line ++--------------------------------------------- ++The mitigation can be disabled by setting "gather_data_sampling=off" or ++"mitigations=off" on the kernel command line. Not specifying either will default ++to the mitigation being enabled. Specifying "gather_data_sampling=force" will ++use the microcode mitigation when available or disable AVX on affected systems ++where the microcode hasn't been updated to include the mitigation. ++ ++GDS System Information ++------------------------ ++The kernel provides vulnerability status information through sysfs. For ++GDS this can be accessed by the following sysfs file: ++ ++/sys/devices/system/cpu/vulnerabilities/gather_data_sampling ++ ++The possible values contained in this file are: ++ ++ ============================== ============================================= ++ Not affected Processor not vulnerable. ++ Vulnerable Processor vulnerable and mitigation disabled. ++ Vulnerable: No microcode Processor vulnerable and microcode is missing ++ mitigation. ++ Mitigation: AVX disabled, ++ no microcode Processor is vulnerable and microcode is missing ++ mitigation. AVX disabled as mitigation. ++ Mitigation: Microcode Processor is vulnerable and mitigation is in ++ effect. ++ Mitigation: Microcode (locked) Processor is vulnerable and mitigation is in ++ effect and cannot be disabled. ++ Unknown: Dependent on ++ hypervisor status Running on a virtual guest processor that is ++ affected but with no way to know if host ++ processor is mitigated or vulnerable. ++ ============================== ============================================= ++ ++GDS Default mitigation ++---------------------- ++The updated microcode will enable the mitigation by default. The kernel's ++default action is to leave the mitigation enabled. +diff --git a/Documentation/admin-guide/hw-vuln/index.rst b/Documentation/admin-guide/hw-vuln/index.rst +index 2adec1e6520a6..245468b0f2be8 100644 +--- a/Documentation/admin-guide/hw-vuln/index.rst ++++ b/Documentation/admin-guide/hw-vuln/index.rst +@@ -16,3 +16,4 @@ are configurable at compile, boot or run time. + multihit.rst + special-register-buffer-data-sampling.rst + processor_mmio_stale_data.rst ++ gather_data_sampling.rst +diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt +index 9d2185616d1ab..51f845419b9c7 100644 +--- a/Documentation/admin-guide/kernel-parameters.txt ++++ b/Documentation/admin-guide/kernel-parameters.txt +@@ -1336,6 +1336,26 @@ + Format: off | on + default: on + ++ gather_data_sampling= ++ [X86,INTEL] Control the Gather Data Sampling (GDS) ++ mitigation. ++ ++ Gather Data Sampling is a hardware vulnerability which ++ allows unprivileged speculative access to data which was ++ previously stored in vector registers. ++ ++ This issue is mitigated by default in updated microcode. ++ The mitigation may have a performance impact but can be ++ disabled. On systems without the microcode mitigation ++ disabling AVX serves as a mitigation. ++ ++ force: Disable AVX to mitigate systems without ++ microcode mitigation. No effect if the microcode ++ mitigation is present. Known to cause crashes in ++ userspace with buggy AVX enumeration. ++ ++ off: Disable GDS mitigation. ++ + gcov_persist= [GCOV] When non-zero (default), profiling data for + kernel modules is saved and remains accessible via + debugfs, even when the module is unloaded/reloaded. +@@ -2696,21 +2716,22 @@ + Disable all optional CPU mitigations. This + improves system performance, but it may also + expose users to several CPU vulnerabilities. +- Equivalent to: nopti [X86,PPC] ++ Equivalent to: gather_data_sampling=off [X86] + kpti=0 [ARM64] +- nospectre_v1 [X86,PPC] ++ kvm.nx_huge_pages=off [X86] ++ l1tf=off [X86] ++ mds=off [X86] ++ mmio_stale_data=off [X86] ++ no_entry_flush [PPC] ++ no_uaccess_flush [PPC] + nobp=0 [S390] ++ nopti [X86,PPC] ++ nospectre_v1 [X86,PPC] + nospectre_v2 [X86,PPC,S390,ARM64] +- spectre_v2_user=off [X86] + spec_store_bypass_disable=off [X86,PPC] ++ spectre_v2_user=off [X86] + ssbd=force-off [ARM64] +- l1tf=off [X86] +- mds=off [X86] + tsx_async_abort=off [X86] +- kvm.nx_huge_pages=off [X86] +- no_entry_flush [PPC] +- no_uaccess_flush [PPC] +- mmio_stale_data=off [X86] + + Exceptions: + This does not have any effect on +diff --git a/Makefile b/Makefile +index 0b17d6936c2f9..be75dc3ae8de0 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,7 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0 + VERSION = 5 + PATCHLEVEL = 4 +-SUBLEVEL = 251 ++SUBLEVEL = 252 + EXTRAVERSION = + NAME = Kleptomaniac Octopus + +diff --git a/arch/Kconfig b/arch/Kconfig +index 2219a07dca1ef..4d03616bf5970 100644 +--- a/arch/Kconfig ++++ b/arch/Kconfig +@@ -271,6 +271,9 @@ config ARCH_HAS_UNCACHED_SEGMENT + select ARCH_HAS_DMA_PREP_COHERENT + bool + ++config ARCH_HAS_CPU_FINALIZE_INIT ++ bool ++ + # Select if arch init_task must go in the __init_task_data section + config ARCH_TASK_STRUCT_ON_STACK + bool +diff --git a/arch/alpha/include/asm/bugs.h b/arch/alpha/include/asm/bugs.h +deleted file mode 100644 +index 78030d1c7e7e0..0000000000000 +--- a/arch/alpha/include/asm/bugs.h ++++ /dev/null +@@ -1,20 +0,0 @@ +-/* +- * include/asm-alpha/bugs.h +- * +- * Copyright (C) 1994 Linus Torvalds +- */ +- +-/* +- * This is included by init/main.c to check for architecture-dependent bugs. +- * +- * Needs: +- * void check_bugs(void); +- */ +- +-/* +- * I don't know of any alpha bugs yet.. Nice chip +- */ +- +-static void check_bugs(void) +-{ +-} +diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig +index a70696a95b795..2feb5dade1214 100644 +--- a/arch/arm/Kconfig ++++ b/arch/arm/Kconfig +@@ -5,6 +5,7 @@ config ARM + select ARCH_32BIT_OFF_T + select ARCH_CLOCKSOURCE_DATA + select ARCH_HAS_BINFMT_FLAT ++ select ARCH_HAS_CPU_FINALIZE_INIT if MMU + select ARCH_HAS_DEBUG_VIRTUAL if MMU + select ARCH_HAS_DEVMEM_IS_ALLOWED + select ARCH_HAS_DMA_COHERENT_TO_PFN if SWIOTLB +diff --git a/arch/arm/include/asm/bugs.h b/arch/arm/include/asm/bugs.h +index 97a312ba08401..fe385551edeca 100644 +--- a/arch/arm/include/asm/bugs.h ++++ b/arch/arm/include/asm/bugs.h +@@ -1,7 +1,5 @@ + /* SPDX-License-Identifier: GPL-2.0-only */ + /* +- * arch/arm/include/asm/bugs.h +- * + * Copyright (C) 1995-2003 Russell King + */ + #ifndef __ASM_BUGS_H +@@ -10,10 +8,8 @@ + extern void check_writebuffer_bugs(void); + + #ifdef CONFIG_MMU +-extern void check_bugs(void); + extern void check_other_bugs(void); + #else +-#define check_bugs() do { } while (0) + #define check_other_bugs() do { } while (0) + #endif + +diff --git a/arch/arm/kernel/bugs.c b/arch/arm/kernel/bugs.c +index 14c8dbbb7d2df..087bce6ec8e9b 100644 +--- a/arch/arm/kernel/bugs.c ++++ b/arch/arm/kernel/bugs.c +@@ -1,5 +1,6 @@ + // SPDX-License-Identifier: GPL-2.0 + #include ++#include + #include + #include + +@@ -11,7 +12,7 @@ void check_other_bugs(void) + #endif + } + +-void __init check_bugs(void) ++void __init arch_cpu_finalize_init(void) + { + check_writebuffer_bugs(); + check_other_bugs(); +diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig +index 6a6036f16abe6..72dc0ac46d6b4 100644 +--- a/arch/ia64/Kconfig ++++ b/arch/ia64/Kconfig +@@ -8,6 +8,7 @@ menu "Processor type and features" + + config IA64 + bool ++ select ARCH_HAS_CPU_FINALIZE_INIT + select ARCH_MIGHT_HAVE_PC_PARPORT + select ARCH_MIGHT_HAVE_PC_SERIO + select ACPI +diff --git a/arch/ia64/include/asm/bugs.h b/arch/ia64/include/asm/bugs.h +deleted file mode 100644 +index 0d6b9bded56c6..0000000000000 +--- a/arch/ia64/include/asm/bugs.h ++++ /dev/null +@@ -1,20 +0,0 @@ +-/* SPDX-License-Identifier: GPL-2.0 */ +-/* +- * This is included by init/main.c to check for architecture-dependent bugs. +- * +- * Needs: +- * void check_bugs(void); +- * +- * Based on . +- * +- * Modified 1998, 1999, 2003 +- * David Mosberger-Tang , Hewlett-Packard Co. +- */ +-#ifndef _ASM_IA64_BUGS_H +-#define _ASM_IA64_BUGS_H +- +-#include +- +-extern void check_bugs (void); +- +-#endif /* _ASM_IA64_BUGS_H */ +diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c +index bb320c6d0cc98..6700f066f59c9 100644 +--- a/arch/ia64/kernel/setup.c ++++ b/arch/ia64/kernel/setup.c +@@ -1073,8 +1073,7 @@ cpu_init (void) + } + } + +-void __init +-check_bugs (void) ++void __init arch_cpu_finalize_init(void) + { + ia64_patch_mckinley_e9((unsigned long) __start___mckinley_e9_bundles, + (unsigned long) __end___mckinley_e9_bundles); +diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig +index 6663f1741798e..d84a6a63d36a1 100644 +--- a/arch/m68k/Kconfig ++++ b/arch/m68k/Kconfig +@@ -4,6 +4,7 @@ config M68K + default y + select ARCH_32BIT_OFF_T + select ARCH_HAS_BINFMT_FLAT ++ select ARCH_HAS_CPU_FINALIZE_INIT if MMU + select ARCH_HAS_DMA_PREP_COHERENT if HAS_DMA && MMU && !COLDFIRE + select ARCH_HAS_SYNC_DMA_FOR_DEVICE if HAS_DMA + select ARCH_MIGHT_HAVE_PC_PARPORT if ISA +diff --git a/arch/m68k/include/asm/bugs.h b/arch/m68k/include/asm/bugs.h +deleted file mode 100644 +index 745530651e0bf..0000000000000 +--- a/arch/m68k/include/asm/bugs.h ++++ /dev/null +@@ -1,21 +0,0 @@ +-/* SPDX-License-Identifier: GPL-2.0 */ +-/* +- * include/asm-m68k/bugs.h +- * +- * Copyright (C) 1994 Linus Torvalds +- */ +- +-/* +- * This is included by init/main.c to check for architecture-dependent bugs. +- * +- * Needs: +- * void check_bugs(void); +- */ +- +-#ifdef CONFIG_MMU +-extern void check_bugs(void); /* in arch/m68k/kernel/setup.c */ +-#else +-static void check_bugs(void) +-{ +-} +-#endif +diff --git a/arch/m68k/kernel/setup_mm.c b/arch/m68k/kernel/setup_mm.c +index 528484feff800..a9ef8b6b01bc0 100644 +--- a/arch/m68k/kernel/setup_mm.c ++++ b/arch/m68k/kernel/setup_mm.c +@@ -10,6 +10,7 @@ + */ + + #include ++#include + #include + #include + #include +@@ -527,7 +528,7 @@ static int __init proc_hardware_init(void) + module_init(proc_hardware_init); + #endif + +-void check_bugs(void) ++void __init arch_cpu_finalize_init(void) + { + #if defined(CONFIG_FPU) && !defined(CONFIG_M68KFPU_EMU) + if (m68k_fputype == 0) { +diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig +index 2811ecc1f3c71..a353d1d1b4571 100644 +--- a/arch/mips/Kconfig ++++ b/arch/mips/Kconfig +@@ -5,6 +5,7 @@ config MIPS + select ARCH_32BIT_OFF_T if !64BIT + select ARCH_BINFMT_ELF_STATE if MIPS_FP_SUPPORT + select ARCH_CLOCKSOURCE_DATA ++ select ARCH_HAS_CPU_FINALIZE_INIT + select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST + select ARCH_HAS_UBSAN_SANITIZE_ALL + select ARCH_SUPPORTS_UPROBES +diff --git a/arch/mips/include/asm/bugs.h b/arch/mips/include/asm/bugs.h +index d8ab8b7129b53..6d04d7d3a8f2d 100644 +--- a/arch/mips/include/asm/bugs.h ++++ b/arch/mips/include/asm/bugs.h +@@ -1,17 +1,11 @@ + /* SPDX-License-Identifier: GPL-2.0 */ + /* +- * This is included by init/main.c to check for architecture-dependent bugs. +- * + * Copyright (C) 2007 Maciej W. Rozycki +- * +- * Needs: +- * void check_bugs(void); + */ + #ifndef _ASM_BUGS_H + #define _ASM_BUGS_H + + #include +-#include + #include + + #include +@@ -31,17 +25,6 @@ static inline void check_bugs_early(void) + #endif + } + +-static inline void check_bugs(void) +-{ +- unsigned int cpu = smp_processor_id(); +- +- cpu_data[cpu].udelay_val = loops_per_jiffy; +- check_bugs32(); +-#ifdef CONFIG_64BIT +- check_bugs64(); +-#endif +-} +- + static inline int r4k_daddiu_bug(void) + { + #ifdef CONFIG_64BIT +diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c +index d91b772214b5d..1c4114f8f9aa1 100644 +--- a/arch/mips/kernel/setup.c ++++ b/arch/mips/kernel/setup.c +@@ -11,6 +11,8 @@ + * Copyright (C) 2000, 2001, 2002, 2007 Maciej W. Rozycki + */ + #include ++#include ++#include + #include + #include + #include +@@ -812,3 +814,14 @@ static int __init setnocoherentio(char *str) + } + early_param("nocoherentio", setnocoherentio); + #endif ++ ++void __init arch_cpu_finalize_init(void) ++{ ++ unsigned int cpu = smp_processor_id(); ++ ++ cpu_data[cpu].udelay_val = loops_per_jiffy; ++ check_bugs32(); ++ ++ if (IS_ENABLED(CONFIG_CPU_R4X00_BUGS64)) ++ check_bugs64(); ++} +diff --git a/arch/parisc/include/asm/bugs.h b/arch/parisc/include/asm/bugs.h +deleted file mode 100644 +index 0a7f9db6bd1c7..0000000000000 +--- a/arch/parisc/include/asm/bugs.h ++++ /dev/null +@@ -1,20 +0,0 @@ +-/* SPDX-License-Identifier: GPL-2.0 */ +-/* +- * include/asm-parisc/bugs.h +- * +- * Copyright (C) 1999 Mike Shaver +- */ +- +-/* +- * This is included by init/main.c to check for architecture-dependent bugs. +- * +- * Needs: +- * void check_bugs(void); +- */ +- +-#include +- +-static inline void check_bugs(void) +-{ +-// identify_cpu(&boot_cpu_data); +-} +diff --git a/arch/powerpc/include/asm/bugs.h b/arch/powerpc/include/asm/bugs.h +deleted file mode 100644 +index 01b8f6ca4dbbc..0000000000000 +--- a/arch/powerpc/include/asm/bugs.h ++++ /dev/null +@@ -1,15 +0,0 @@ +-/* SPDX-License-Identifier: GPL-2.0-or-later */ +-#ifndef _ASM_POWERPC_BUGS_H +-#define _ASM_POWERPC_BUGS_H +- +-/* +- */ +- +-/* +- * This file is included by 'init/main.c' to check for +- * architecture-dependent bugs. +- */ +- +-static inline void check_bugs(void) { } +- +-#endif /* _ASM_POWERPC_BUGS_H */ +diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig +index f356ee674d89b..671897a680cae 100644 +--- a/arch/sh/Kconfig ++++ b/arch/sh/Kconfig +@@ -2,6 +2,7 @@ + config SUPERH + def_bool y + select ARCH_HAS_BINFMT_FLAT if !MMU ++ select ARCH_HAS_CPU_FINALIZE_INIT + select ARCH_HAS_PTE_SPECIAL + select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST + select ARCH_MIGHT_HAVE_PC_PARPORT +diff --git a/arch/sh/include/asm/bugs.h b/arch/sh/include/asm/bugs.h +deleted file mode 100644 +index 030df56bfdb20..0000000000000 +--- a/arch/sh/include/asm/bugs.h ++++ /dev/null +@@ -1,78 +0,0 @@ +-/* SPDX-License-Identifier: GPL-2.0 */ +-#ifndef __ASM_SH_BUGS_H +-#define __ASM_SH_BUGS_H +- +-/* +- * This is included by init/main.c to check for architecture-dependent bugs. +- * +- * Needs: +- * void check_bugs(void); +- */ +- +-/* +- * I don't know of any Super-H bugs yet. +- */ +- +-#include +- +-extern void select_idle_routine(void); +- +-static void __init check_bugs(void) +-{ +- extern unsigned long loops_per_jiffy; +- char *p = &init_utsname()->machine[2]; /* "sh" */ +- +- select_idle_routine(); +- +- current_cpu_data.loops_per_jiffy = loops_per_jiffy; +- +- switch (current_cpu_data.family) { +- case CPU_FAMILY_SH2: +- *p++ = '2'; +- break; +- case CPU_FAMILY_SH2A: +- *p++ = '2'; +- *p++ = 'a'; +- break; +- case CPU_FAMILY_SH3: +- *p++ = '3'; +- break; +- case CPU_FAMILY_SH4: +- *p++ = '4'; +- break; +- case CPU_FAMILY_SH4A: +- *p++ = '4'; +- *p++ = 'a'; +- break; +- case CPU_FAMILY_SH4AL_DSP: +- *p++ = '4'; +- *p++ = 'a'; +- *p++ = 'l'; +- *p++ = '-'; +- *p++ = 'd'; +- *p++ = 's'; +- *p++ = 'p'; +- break; +- case CPU_FAMILY_SH5: +- *p++ = '6'; +- *p++ = '4'; +- break; +- case CPU_FAMILY_UNKNOWN: +- /* +- * Specifically use CPU_FAMILY_UNKNOWN rather than +- * default:, so we're able to have the compiler whine +- * about unhandled enumerations. +- */ +- break; +- } +- +- printk("CPU: %s\n", get_cpu_subtype(¤t_cpu_data)); +- +-#ifndef __LITTLE_ENDIAN__ +- /* 'eb' means 'Endian Big' */ +- *p++ = 'e'; +- *p++ = 'b'; +-#endif +- *p = '\0'; +-} +-#endif /* __ASM_SH_BUGS_H */ +diff --git a/arch/sh/include/asm/processor.h b/arch/sh/include/asm/processor.h +index 6fbf8c80e4981..386786b1594ab 100644 +--- a/arch/sh/include/asm/processor.h ++++ b/arch/sh/include/asm/processor.h +@@ -173,6 +173,8 @@ extern unsigned int instruction_size(unsigned int insn); + #define instruction_size(insn) (4) + #endif + ++void select_idle_routine(void); ++ + #endif /* __ASSEMBLY__ */ + + #ifdef CONFIG_SUPERH32 +diff --git a/arch/sh/kernel/idle.c b/arch/sh/kernel/idle.c +index c20fc5487e051..bcb8eabd76185 100644 +--- a/arch/sh/kernel/idle.c ++++ b/arch/sh/kernel/idle.c +@@ -15,6 +15,7 @@ + #include + #include + #include ++#include + #include + #include + +diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c +index c25ee383cb83a..2221e057e6b41 100644 +--- a/arch/sh/kernel/setup.c ++++ b/arch/sh/kernel/setup.c +@@ -43,6 +43,7 @@ + #include + #include + #include ++#include + #include + + /* +@@ -362,3 +363,57 @@ int test_mode_pin(int pin) + { + return sh_mv.mv_mode_pins() & pin; + } ++ ++void __init arch_cpu_finalize_init(void) ++{ ++ char *p = &init_utsname()->machine[2]; /* "sh" */ ++ ++ select_idle_routine(); ++ ++ current_cpu_data.loops_per_jiffy = loops_per_jiffy; ++ ++ switch (current_cpu_data.family) { ++ case CPU_FAMILY_SH2: ++ *p++ = '2'; ++ break; ++ case CPU_FAMILY_SH2A: ++ *p++ = '2'; ++ *p++ = 'a'; ++ break; ++ case CPU_FAMILY_SH3: ++ *p++ = '3'; ++ break; ++ case CPU_FAMILY_SH4: ++ *p++ = '4'; ++ break; ++ case CPU_FAMILY_SH4A: ++ *p++ = '4'; ++ *p++ = 'a'; ++ break; ++ case CPU_FAMILY_SH4AL_DSP: ++ *p++ = '4'; ++ *p++ = 'a'; ++ *p++ = 'l'; ++ *p++ = '-'; ++ *p++ = 'd'; ++ *p++ = 's'; ++ *p++ = 'p'; ++ break; ++ case CPU_FAMILY_UNKNOWN: ++ /* ++ * Specifically use CPU_FAMILY_UNKNOWN rather than ++ * default:, so we're able to have the compiler whine ++ * about unhandled enumerations. ++ */ ++ break; ++ } ++ ++ pr_info("CPU: %s\n", get_cpu_subtype(¤t_cpu_data)); ++ ++#ifndef __LITTLE_ENDIAN__ ++ /* 'eb' means 'Endian Big' */ ++ *p++ = 'e'; ++ *p++ = 'b'; ++#endif ++ *p = '\0'; ++} +diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig +index 8cb5bb020b4b6..881f6a8491486 100644 +--- a/arch/sparc/Kconfig ++++ b/arch/sparc/Kconfig +@@ -52,6 +52,7 @@ config SPARC + config SPARC32 + def_bool !64BIT + select ARCH_32BIT_OFF_T ++ select ARCH_HAS_CPU_FINALIZE_INIT if !SMP + select ARCH_HAS_SYNC_DMA_FOR_CPU + select GENERIC_ATOMIC64 + select CLZ_TAB +diff --git a/arch/sparc/include/asm/bugs.h b/arch/sparc/include/asm/bugs.h +deleted file mode 100644 +index 02fa369b9c21f..0000000000000 +--- a/arch/sparc/include/asm/bugs.h ++++ /dev/null +@@ -1,18 +0,0 @@ +-/* SPDX-License-Identifier: GPL-2.0 */ +-/* include/asm/bugs.h: Sparc probes for various bugs. +- * +- * Copyright (C) 1996, 2007 David S. Miller (davem@davemloft.net) +- */ +- +-#ifdef CONFIG_SPARC32 +-#include +-#endif +- +-extern unsigned long loops_per_jiffy; +- +-static void __init check_bugs(void) +-{ +-#if defined(CONFIG_SPARC32) && !defined(CONFIG_SMP) +- cpu_data(0).udelay_val = loops_per_jiffy; +-#endif +-} +diff --git a/arch/sparc/kernel/setup_32.c b/arch/sparc/kernel/setup_32.c +index afe1592a6d085..4373c1d64ab85 100644 +--- a/arch/sparc/kernel/setup_32.c ++++ b/arch/sparc/kernel/setup_32.c +@@ -422,3 +422,10 @@ static int __init topology_init(void) + } + + subsys_initcall(topology_init); ++ ++#if defined(CONFIG_SPARC32) && !defined(CONFIG_SMP) ++void __init arch_cpu_finalize_init(void) ++{ ++ cpu_data(0).udelay_val = loops_per_jiffy; ++} ++#endif +diff --git a/arch/um/Kconfig b/arch/um/Kconfig +index c56d3526a3bd7..468a5d63ef269 100644 +--- a/arch/um/Kconfig ++++ b/arch/um/Kconfig +@@ -5,6 +5,7 @@ menu "UML-specific options" + config UML + bool + default y ++ select ARCH_HAS_CPU_FINALIZE_INIT + select ARCH_HAS_KCOV + select ARCH_NO_PREEMPT + select HAVE_ARCH_AUDITSYSCALL +diff --git a/arch/um/include/asm/bugs.h b/arch/um/include/asm/bugs.h +deleted file mode 100644 +index 4473942a08397..0000000000000 +--- a/arch/um/include/asm/bugs.h ++++ /dev/null +@@ -1,7 +0,0 @@ +-/* SPDX-License-Identifier: GPL-2.0 */ +-#ifndef __UM_BUGS_H +-#define __UM_BUGS_H +- +-void check_bugs(void); +- +-#endif +diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c +index 640c8e178502e..004ef4ebb57d4 100644 +--- a/arch/um/kernel/um_arch.c ++++ b/arch/um/kernel/um_arch.c +@@ -3,6 +3,7 @@ + * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) + */ + ++#include + #include + #include + #include +@@ -353,7 +354,7 @@ void __init setup_arch(char **cmdline_p) + setup_hostinfo(host_info, sizeof host_info); + } + +-void __init check_bugs(void) ++void __init arch_cpu_finalize_init(void) + { + arch_check_bugs(); + os_check_bugs(); +diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig +index 6002252692af4..df0a3a1b08ae0 100644 +--- a/arch/x86/Kconfig ++++ b/arch/x86/Kconfig +@@ -60,6 +60,7 @@ config X86 + select ARCH_CLOCKSOURCE_DATA + select ARCH_CLOCKSOURCE_INIT + select ARCH_HAS_ACPI_TABLE_UPGRADE if ACPI ++ select ARCH_HAS_CPU_FINALIZE_INIT + select ARCH_HAS_DEBUG_VIRTUAL + select ARCH_HAS_DEVMEM_IS_ALLOWED + select ARCH_HAS_ELF_RANDOMIZE +@@ -2500,6 +2501,25 @@ config ARCH_ENABLE_SPLIT_PMD_PTLOCK + def_bool y + depends on X86_64 || X86_PAE + ++config GDS_FORCE_MITIGATION ++ bool "Force GDS Mitigation" ++ depends on CPU_SUP_INTEL ++ default n ++ help ++ Gather Data Sampling (GDS) is a hardware vulnerability which allows ++ unprivileged speculative access to data which was previously stored in ++ vector registers. ++ ++ This option is equivalent to setting gather_data_sampling=force on the ++ command line. The microcode mitigation is used if present, otherwise ++ AVX is disabled as a mitigation. On affected systems that are missing ++ the microcode any userspace code that unconditionally uses AVX will ++ break with this option set. ++ ++ Setting this option on systems not vulnerable to GDS has no effect. ++ ++ If in doubt, say N. ++ + config ARCH_ENABLE_HUGEPAGE_MIGRATION + def_bool y + depends on X86_64 && HUGETLB_PAGE && MIGRATION +diff --git a/arch/x86/include/asm/bugs.h b/arch/x86/include/asm/bugs.h +index 794eb2129bc6b..6554ddb2ad49e 100644 +--- a/arch/x86/include/asm/bugs.h ++++ b/arch/x86/include/asm/bugs.h +@@ -4,8 +4,6 @@ + + #include + +-extern void check_bugs(void); +- + #if defined(CONFIG_CPU_SUP_INTEL) + void check_mpx_erratum(struct cpuinfo_x86 *c); + #else +diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h +index 619c1f80a2abe..4466a47b76080 100644 +--- a/arch/x86/include/asm/cpufeature.h ++++ b/arch/x86/include/asm/cpufeature.h +@@ -30,6 +30,8 @@ enum cpuid_leafs + CPUID_7_ECX, + CPUID_8000_0007_EBX, + CPUID_7_EDX, ++ CPUID_8000_001F_EAX, ++ CPUID_8000_0021_EAX, + }; + + #ifdef CONFIG_X86_FEATURE_NAMES +@@ -88,8 +90,10 @@ extern const char * const x86_bug_flags[NBUGINTS*32]; + CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 16, feature_bit) || \ + CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 17, feature_bit) || \ + CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 18, feature_bit) || \ ++ CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 19, feature_bit) || \ ++ CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 20, feature_bit) || \ + REQUIRED_MASK_CHECK || \ +- BUILD_BUG_ON_ZERO(NCAPINTS != 19)) ++ BUILD_BUG_ON_ZERO(NCAPINTS != 21)) + + #define DISABLED_MASK_BIT_SET(feature_bit) \ + ( CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 0, feature_bit) || \ +@@ -111,8 +115,10 @@ extern const char * const x86_bug_flags[NBUGINTS*32]; + CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 16, feature_bit) || \ + CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 17, feature_bit) || \ + CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 18, feature_bit) || \ ++ CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 19, feature_bit) || \ ++ CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 20, feature_bit) || \ + DISABLED_MASK_CHECK || \ +- BUILD_BUG_ON_ZERO(NCAPINTS != 19)) ++ BUILD_BUG_ON_ZERO(NCAPINTS != 21)) + + #define cpu_has(c, bit) \ + (__builtin_constant_p(bit) && REQUIRED_MASK_BIT_SET(bit) ? 1 : \ +diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h +index 3e360dc07bae0..f42286e9a2b16 100644 +--- a/arch/x86/include/asm/cpufeatures.h ++++ b/arch/x86/include/asm/cpufeatures.h +@@ -13,8 +13,8 @@ + /* + * Defines x86 CPU feature bits + */ +-#define NCAPINTS 19 /* N 32-bit words worth of info */ +-#define NBUGINTS 1 /* N 32-bit bug flags */ ++#define NCAPINTS 21 /* N 32-bit words worth of info */ ++#define NBUGINTS 2 /* N 32-bit bug flags */ + + /* + * Note: If the comment begins with a quoted string, that string is used +@@ -96,7 +96,7 @@ + #define X86_FEATURE_SYSCALL32 ( 3*32+14) /* "" syscall in IA32 userspace */ + #define X86_FEATURE_SYSENTER32 ( 3*32+15) /* "" sysenter in IA32 userspace */ + #define X86_FEATURE_REP_GOOD ( 3*32+16) /* REP microcode works well */ +-#define X86_FEATURE_SME_COHERENT ( 3*32+17) /* "" AMD hardware-enforced cache coherency */ ++/* FREE! ( 3*32+17) */ + #define X86_FEATURE_LFENCE_RDTSC ( 3*32+18) /* "" LFENCE synchronizes RDTSC */ + #define X86_FEATURE_ACC_POWER ( 3*32+19) /* AMD Accumulated Power Mechanism */ + #define X86_FEATURE_NOPL ( 3*32+20) /* The NOPL (0F 1F) instructions */ +@@ -201,7 +201,7 @@ + #define X86_FEATURE_INVPCID_SINGLE ( 7*32+ 7) /* Effectively INVPCID && CR4.PCIDE=1 */ + #define X86_FEATURE_HW_PSTATE ( 7*32+ 8) /* AMD HW-PState */ + #define X86_FEATURE_PROC_FEEDBACK ( 7*32+ 9) /* AMD ProcFeedbackInterface */ +-#define X86_FEATURE_SME ( 7*32+10) /* AMD Secure Memory Encryption */ ++/* FREE! ( 7*32+10) */ + #define X86_FEATURE_PTI ( 7*32+11) /* Kernel Page Table Isolation enabled */ + #define X86_FEATURE_KERNEL_IBRS ( 7*32+12) /* "" Set/clear IBRS on kernel entry/exit */ + #define X86_FEATURE_RSB_VMEXIT ( 7*32+13) /* "" Fill RSB on VM-Exit */ +@@ -211,7 +211,7 @@ + #define X86_FEATURE_SSBD ( 7*32+17) /* Speculative Store Bypass Disable */ + #define X86_FEATURE_MBA ( 7*32+18) /* Memory Bandwidth Allocation */ + #define X86_FEATURE_RSB_CTXSW ( 7*32+19) /* "" Fill RSB on context switches */ +-#define X86_FEATURE_SEV ( 7*32+20) /* AMD Secure Encrypted Virtualization */ ++/* FREE! ( 7*32+20) */ + #define X86_FEATURE_USE_IBPB ( 7*32+21) /* "" Indirect Branch Prediction Barrier enabled */ + #define X86_FEATURE_USE_IBRS_FW ( 7*32+22) /* "" Use IBRS during runtime firmware calls */ + #define X86_FEATURE_SPEC_STORE_BYPASS_DISABLE ( 7*32+23) /* "" Disable Speculative Store Bypass. */ +@@ -375,6 +375,13 @@ + #define X86_FEATURE_ARCH_CAPABILITIES (18*32+29) /* IA32_ARCH_CAPABILITIES MSR (Intel) */ + #define X86_FEATURE_SPEC_CTRL_SSBD (18*32+31) /* "" Speculative Store Bypass Disable */ + ++/* AMD-defined memory encryption features, CPUID level 0x8000001f (EAX), word 19 */ ++#define X86_FEATURE_SME (19*32+ 0) /* AMD Secure Memory Encryption */ ++#define X86_FEATURE_SEV (19*32+ 1) /* AMD Secure Encrypted Virtualization */ ++#define X86_FEATURE_VM_PAGE_FLUSH (19*32+ 2) /* "" VM Page Flush MSR is supported */ ++#define X86_FEATURE_SEV_ES (19*32+ 3) /* AMD Secure Encrypted Virtualization - Encrypted State */ ++#define X86_FEATURE_SME_COHERENT (19*32+10) /* "" AMD hardware-enforced cache coherency */ ++ + /* + * BUG word(s) + */ +@@ -415,5 +422,6 @@ + #define X86_BUG_RETBLEED X86_BUG(26) /* CPU is affected by RETBleed */ + #define X86_BUG_EIBRS_PBRSB X86_BUG(27) /* EIBRS is vulnerable to Post Barrier RSB Predictions */ + #define X86_BUG_MMIO_UNKNOWN X86_BUG(28) /* CPU is too old and its MMIO Stale Data status is unknown */ ++#define X86_BUG_GDS X86_BUG(29) /* CPU is affected by Gather Data Sampling */ + + #endif /* _ASM_X86_CPUFEATURES_H */ +diff --git a/arch/x86/include/asm/disabled-features.h b/arch/x86/include/asm/disabled-features.h +index a5ea841cc6d22..8453260f6d9f9 100644 +--- a/arch/x86/include/asm/disabled-features.h ++++ b/arch/x86/include/asm/disabled-features.h +@@ -84,6 +84,8 @@ + #define DISABLED_MASK16 (DISABLE_PKU|DISABLE_OSPKE|DISABLE_LA57|DISABLE_UMIP) + #define DISABLED_MASK17 0 + #define DISABLED_MASK18 0 +-#define DISABLED_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS != 19) ++#define DISABLED_MASK19 0 ++#define DISABLED_MASK20 0 ++#define DISABLED_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS != 21) + + #endif /* _ASM_X86_DISABLED_FEATURES_H */ +diff --git a/arch/x86/include/asm/fpu/internal.h b/arch/x86/include/asm/fpu/internal.h +index 5ed702e2c55f4..330841bad6167 100644 +--- a/arch/x86/include/asm/fpu/internal.h ++++ b/arch/x86/include/asm/fpu/internal.h +@@ -41,7 +41,7 @@ extern int dump_fpu(struct pt_regs *ptregs, struct user_i387_struct *fpstate); + extern void fpu__init_cpu(void); + extern void fpu__init_system_xstate(void); + extern void fpu__init_cpu_xstate(void); +-extern void fpu__init_system(struct cpuinfo_x86 *c); ++extern void fpu__init_system(void); + extern void fpu__init_check_bugs(void); + extern void fpu__resume_cpu(void); + extern u64 fpu__get_supported_xfeatures_mask(void); +diff --git a/arch/x86/include/asm/mem_encrypt.h b/arch/x86/include/asm/mem_encrypt.h +index 848ce43b9040d..190c5ca537e9e 100644 +--- a/arch/x86/include/asm/mem_encrypt.h ++++ b/arch/x86/include/asm/mem_encrypt.h +@@ -77,6 +77,8 @@ early_set_memory_decrypted(unsigned long vaddr, unsigned long size) { return 0; + static inline int __init + early_set_memory_encrypted(unsigned long vaddr, unsigned long size) { return 0; } + ++static inline void mem_encrypt_init(void) { } ++ + #define __bss_decrypted + + #endif /* CONFIG_AMD_MEM_ENCRYPT */ +diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h +index f3fa903c5b297..7137256f2c31d 100644 +--- a/arch/x86/include/asm/msr-index.h ++++ b/arch/x86/include/asm/msr-index.h +@@ -147,6 +147,15 @@ + * Not susceptible to Post-Barrier + * Return Stack Buffer Predictions. + */ ++#define ARCH_CAP_GDS_CTRL BIT(25) /* ++ * CPU is vulnerable to Gather ++ * Data Sampling (GDS) and ++ * has controls for mitigation. ++ */ ++#define ARCH_CAP_GDS_NO BIT(26) /* ++ * CPU is not vulnerable to Gather ++ * Data Sampling (GDS). ++ */ + + #define MSR_IA32_FLUSH_CMD 0x0000010b + #define L1D_FLUSH BIT(0) /* +@@ -165,6 +174,8 @@ + #define MSR_IA32_MCU_OPT_CTRL 0x00000123 + #define RNGDS_MITG_DIS BIT(0) + #define FB_CLEAR_DIS BIT(3) /* CPU Fill buffer clear disable */ ++#define GDS_MITG_DIS BIT(4) /* Disable GDS mitigation */ ++#define GDS_MITG_LOCKED BIT(5) /* GDS mitigation locked */ + + #define MSR_IA32_SYSENTER_CS 0x00000174 + #define MSR_IA32_SYSENTER_ESP 0x00000175 +@@ -484,6 +495,7 @@ + #define MSR_AMD64_ICIBSEXTDCTL 0xc001103c + #define MSR_AMD64_IBSOPDATA4 0xc001103d + #define MSR_AMD64_IBS_REG_COUNT_MAX 8 /* includes MSR_AMD64_IBSBRTARGET */ ++#define MSR_AMD64_VM_PAGE_FLUSH 0xc001011e + #define MSR_AMD64_SEV 0xc0010131 + #define MSR_AMD64_SEV_ENABLED_BIT 0 + #define MSR_AMD64_SEV_ENABLED BIT_ULL(MSR_AMD64_SEV_ENABLED_BIT) +diff --git a/arch/x86/include/asm/required-features.h b/arch/x86/include/asm/required-features.h +index 6847d85400a8b..fb3d81347e333 100644 +--- a/arch/x86/include/asm/required-features.h ++++ b/arch/x86/include/asm/required-features.h +@@ -101,6 +101,8 @@ + #define REQUIRED_MASK16 0 + #define REQUIRED_MASK17 0 + #define REQUIRED_MASK18 0 +-#define REQUIRED_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS != 19) ++#define REQUIRED_MASK19 0 ++#define REQUIRED_MASK20 0 ++#define REQUIRED_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS != 21) + + #endif /* _ASM_X86_REQUIRED_FEATURES_H */ +diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c +index 3f182c06b305c..11f09df72f51a 100644 +--- a/arch/x86/kernel/cpu/amd.c ++++ b/arch/x86/kernel/cpu/amd.c +@@ -663,7 +663,7 @@ static void early_detect_mem_encrypt(struct cpuinfo_x86 *c) + * If BIOS has not enabled SME then don't advertise the + * SME feature (set in scattered.c). + * For SEV: If BIOS has not enabled SEV then don't advertise the +- * SEV feature (set in scattered.c). ++ * SEV and SEV_ES feature (set in scattered.c). + * + * In all cases, since support for SME and SEV requires long mode, + * don't advertise the feature under CONFIG_X86_32. +@@ -694,6 +694,7 @@ clear_all: + setup_clear_cpu_cap(X86_FEATURE_SME); + clear_sev: + setup_clear_cpu_cap(X86_FEATURE_SEV); ++ setup_clear_cpu_cap(X86_FEATURE_SEV_ES); + } + } + +diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c +index 75ca28bb267c4..48ae44cf77951 100644 +--- a/arch/x86/kernel/cpu/bugs.c ++++ b/arch/x86/kernel/cpu/bugs.c +@@ -9,7 +9,6 @@ + * - Andrew D. Balsa (code cleanup). + */ + #include +-#include + #include + #include + #include +@@ -25,9 +24,7 @@ + #include + #include + #include +-#include + #include +-#include + #include + #include + #include +@@ -47,6 +44,7 @@ static void __init md_clear_select_mitigation(void); + static void __init taa_select_mitigation(void); + static void __init mmio_select_mitigation(void); + static void __init srbds_select_mitigation(void); ++static void __init gds_select_mitigation(void); + + /* The base value of the SPEC_CTRL MSR without task-specific bits set */ + u64 x86_spec_ctrl_base; +@@ -115,21 +113,8 @@ EXPORT_SYMBOL_GPL(mds_idle_clear); + DEFINE_STATIC_KEY_FALSE(mmio_stale_data_clear); + EXPORT_SYMBOL_GPL(mmio_stale_data_clear); + +-void __init check_bugs(void) ++void __init cpu_select_mitigations(void) + { +- identify_boot_cpu(); +- +- /* +- * identify_boot_cpu() initialized SMT support information, let the +- * core code know. +- */ +- cpu_smt_check_topology(); +- +- if (!IS_ENABLED(CONFIG_SMP)) { +- pr_info("CPU: "); +- print_cpu_info(&boot_cpu_data); +- } +- + /* + * Read the SPEC_CTRL MSR to account for reserved bits which may + * have unknown values. AMD64_LS_CFG MSR is cached in the early AMD +@@ -165,39 +150,7 @@ void __init check_bugs(void) + l1tf_select_mitigation(); + md_clear_select_mitigation(); + srbds_select_mitigation(); +- +- arch_smt_update(); +- +-#ifdef CONFIG_X86_32 +- /* +- * Check whether we are able to run this kernel safely on SMP. +- * +- * - i386 is no longer supported. +- * - In order to run on anything without a TSC, we need to be +- * compiled for a i486. +- */ +- if (boot_cpu_data.x86 < 4) +- panic("Kernel requires i486+ for 'invlpg' and other features"); +- +- init_utsname()->machine[1] = +- '0' + (boot_cpu_data.x86 > 6 ? 6 : boot_cpu_data.x86); +- alternative_instructions(); +- +- fpu__init_check_bugs(); +-#else /* CONFIG_X86_64 */ +- alternative_instructions(); +- +- /* +- * Make sure the first 2MB area is not mapped by huge pages +- * There are typically fixed size MTRRs in there and overlapping +- * MTRRs into large pages causes slow downs. +- * +- * Right now we don't do that with gbpages because there seems +- * very little benefit for that case. +- */ +- if (!direct_gbpages) +- set_memory_4k((unsigned long)__va(0), 1); +-#endif ++ gds_select_mitigation(); + } + + /* +@@ -648,6 +601,149 @@ static int __init srbds_parse_cmdline(char *str) + } + early_param("srbds", srbds_parse_cmdline); + ++#undef pr_fmt ++#define pr_fmt(fmt) "GDS: " fmt ++ ++enum gds_mitigations { ++ GDS_MITIGATION_OFF, ++ GDS_MITIGATION_UCODE_NEEDED, ++ GDS_MITIGATION_FORCE, ++ GDS_MITIGATION_FULL, ++ GDS_MITIGATION_FULL_LOCKED, ++ GDS_MITIGATION_HYPERVISOR, ++}; ++ ++#if IS_ENABLED(CONFIG_GDS_FORCE_MITIGATION) ++static enum gds_mitigations gds_mitigation __ro_after_init = GDS_MITIGATION_FORCE; ++#else ++static enum gds_mitigations gds_mitigation __ro_after_init = GDS_MITIGATION_FULL; ++#endif ++ ++static const char * const gds_strings[] = { ++ [GDS_MITIGATION_OFF] = "Vulnerable", ++ [GDS_MITIGATION_UCODE_NEEDED] = "Vulnerable: No microcode", ++ [GDS_MITIGATION_FORCE] = "Mitigation: AVX disabled, no microcode", ++ [GDS_MITIGATION_FULL] = "Mitigation: Microcode", ++ [GDS_MITIGATION_FULL_LOCKED] = "Mitigation: Microcode (locked)", ++ [GDS_MITIGATION_HYPERVISOR] = "Unknown: Dependent on hypervisor status", ++}; ++ ++bool gds_ucode_mitigated(void) ++{ ++ return (gds_mitigation == GDS_MITIGATION_FULL || ++ gds_mitigation == GDS_MITIGATION_FULL_LOCKED); ++} ++EXPORT_SYMBOL_GPL(gds_ucode_mitigated); ++ ++void update_gds_msr(void) ++{ ++ u64 mcu_ctrl_after; ++ u64 mcu_ctrl; ++ ++ switch (gds_mitigation) { ++ case GDS_MITIGATION_OFF: ++ rdmsrl(MSR_IA32_MCU_OPT_CTRL, mcu_ctrl); ++ mcu_ctrl |= GDS_MITG_DIS; ++ break; ++ case GDS_MITIGATION_FULL_LOCKED: ++ /* ++ * The LOCKED state comes from the boot CPU. APs might not have ++ * the same state. Make sure the mitigation is enabled on all ++ * CPUs. ++ */ ++ case GDS_MITIGATION_FULL: ++ rdmsrl(MSR_IA32_MCU_OPT_CTRL, mcu_ctrl); ++ mcu_ctrl &= ~GDS_MITG_DIS; ++ break; ++ case GDS_MITIGATION_FORCE: ++ case GDS_MITIGATION_UCODE_NEEDED: ++ case GDS_MITIGATION_HYPERVISOR: ++ return; ++ }; ++ ++ wrmsrl(MSR_IA32_MCU_OPT_CTRL, mcu_ctrl); ++ ++ /* ++ * Check to make sure that the WRMSR value was not ignored. Writes to ++ * GDS_MITG_DIS will be ignored if this processor is locked but the boot ++ * processor was not. ++ */ ++ rdmsrl(MSR_IA32_MCU_OPT_CTRL, mcu_ctrl_after); ++ WARN_ON_ONCE(mcu_ctrl != mcu_ctrl_after); ++} ++ ++static void __init gds_select_mitigation(void) ++{ ++ u64 mcu_ctrl; ++ ++ if (!boot_cpu_has_bug(X86_BUG_GDS)) ++ return; ++ ++ if (boot_cpu_has(X86_FEATURE_HYPERVISOR)) { ++ gds_mitigation = GDS_MITIGATION_HYPERVISOR; ++ goto out; ++ } ++ ++ if (cpu_mitigations_off()) ++ gds_mitigation = GDS_MITIGATION_OFF; ++ /* Will verify below that mitigation _can_ be disabled */ ++ ++ /* No microcode */ ++ if (!(x86_read_arch_cap_msr() & ARCH_CAP_GDS_CTRL)) { ++ if (gds_mitigation == GDS_MITIGATION_FORCE) { ++ /* ++ * This only needs to be done on the boot CPU so do it ++ * here rather than in update_gds_msr() ++ */ ++ setup_clear_cpu_cap(X86_FEATURE_AVX); ++ pr_warn("Microcode update needed! Disabling AVX as mitigation.\n"); ++ } else { ++ gds_mitigation = GDS_MITIGATION_UCODE_NEEDED; ++ } ++ goto out; ++ } ++ ++ /* Microcode has mitigation, use it */ ++ if (gds_mitigation == GDS_MITIGATION_FORCE) ++ gds_mitigation = GDS_MITIGATION_FULL; ++ ++ rdmsrl(MSR_IA32_MCU_OPT_CTRL, mcu_ctrl); ++ if (mcu_ctrl & GDS_MITG_LOCKED) { ++ if (gds_mitigation == GDS_MITIGATION_OFF) ++ pr_warn("Mitigation locked. Disable failed.\n"); ++ ++ /* ++ * The mitigation is selected from the boot CPU. All other CPUs ++ * _should_ have the same state. If the boot CPU isn't locked ++ * but others are then update_gds_msr() will WARN() of the state ++ * mismatch. If the boot CPU is locked update_gds_msr() will ++ * ensure the other CPUs have the mitigation enabled. ++ */ ++ gds_mitigation = GDS_MITIGATION_FULL_LOCKED; ++ } ++ ++ update_gds_msr(); ++out: ++ pr_info("%s\n", gds_strings[gds_mitigation]); ++} ++ ++static int __init gds_parse_cmdline(char *str) ++{ ++ if (!str) ++ return -EINVAL; ++ ++ if (!boot_cpu_has_bug(X86_BUG_GDS)) ++ return 0; ++ ++ if (!strcmp(str, "off")) ++ gds_mitigation = GDS_MITIGATION_OFF; ++ else if (!strcmp(str, "force")) ++ gds_mitigation = GDS_MITIGATION_FORCE; ++ ++ return 0; ++} ++early_param("gather_data_sampling", gds_parse_cmdline); ++ + #undef pr_fmt + #define pr_fmt(fmt) "Spectre V1 : " fmt + +@@ -2207,6 +2303,11 @@ static ssize_t retbleed_show_state(char *buf) + return sprintf(buf, "%s\n", retbleed_strings[retbleed_mitigation]); + } + ++static ssize_t gds_show_state(char *buf) ++{ ++ return sysfs_emit(buf, "%s\n", gds_strings[gds_mitigation]); ++} ++ + static ssize_t cpu_show_common(struct device *dev, struct device_attribute *attr, + char *buf, unsigned int bug) + { +@@ -2256,6 +2357,9 @@ static ssize_t cpu_show_common(struct device *dev, struct device_attribute *attr + case X86_BUG_RETBLEED: + return retbleed_show_state(buf); + ++ case X86_BUG_GDS: ++ return gds_show_state(buf); ++ + default: + break; + } +@@ -2320,4 +2424,9 @@ ssize_t cpu_show_retbleed(struct device *dev, struct device_attribute *attr, cha + { + return cpu_show_common(dev, attr, buf, X86_BUG_RETBLEED); + } ++ ++ssize_t cpu_show_gds(struct device *dev, struct device_attribute *attr, char *buf) ++{ ++ return cpu_show_common(dev, attr, buf, X86_BUG_GDS); ++} + #endif +diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c +index c8ccf5bfd5341..fcfe891c1e8e5 100644 +--- a/arch/x86/kernel/cpu/common.c ++++ b/arch/x86/kernel/cpu/common.c +@@ -17,11 +17,16 @@ + #include + #include + #include ++#include + #include ++#include + #include + #include + + #include ++#include ++ ++#include + #include + #include + #include +@@ -57,6 +62,7 @@ + #ifdef CONFIG_X86_LOCAL_APIC + #include + #endif ++#include + + #include "cpu.h" + +@@ -961,6 +967,12 @@ void get_cpu_cap(struct cpuinfo_x86 *c) + if (c->extended_cpuid_level >= 0x8000000a) + c->x86_capability[CPUID_8000_000A_EDX] = cpuid_edx(0x8000000a); + ++ if (c->extended_cpuid_level >= 0x8000001f) ++ c->x86_capability[CPUID_8000_001F_EAX] = cpuid_eax(0x8000001f); ++ ++ if (c->extended_cpuid_level >= 0x80000021) ++ c->x86_capability[CPUID_8000_0021_EAX] = cpuid_eax(0x80000021); ++ + init_scattered_cpuid_features(c); + init_speculation_control(c); + init_cqm(c); +@@ -1123,6 +1135,12 @@ static const __initconst struct x86_cpu_id cpu_vuln_whitelist[] = { + #define MMIO_SBDS BIT(2) + /* CPU is affected by RETbleed, speculating where you would not expect it */ + #define RETBLEED BIT(3) ++/* CPU is affected by SMT (cross-thread) return predictions */ ++#define SMT_RSB BIT(4) ++/* CPU is affected by SRSO */ ++#define SRSO BIT(5) ++/* CPU is affected by GDS */ ++#define GDS BIT(6) + + static const struct x86_cpu_id cpu_vuln_blacklist[] __initconst = { + VULNBL_INTEL_STEPPINGS(IVYBRIDGE, X86_STEPPING_ANY, SRBDS), +@@ -1135,19 +1153,21 @@ static const struct x86_cpu_id cpu_vuln_blacklist[] __initconst = { + VULNBL_INTEL_STEPPINGS(BROADWELL_X, X86_STEPPING_ANY, MMIO), + VULNBL_INTEL_STEPPINGS(BROADWELL, X86_STEPPING_ANY, SRBDS), + VULNBL_INTEL_STEPPINGS(SKYLAKE_L, X86_STEPPING_ANY, SRBDS | MMIO | RETBLEED), +- VULNBL_INTEL_STEPPINGS(SKYLAKE_X, X86_STEPPING_ANY, MMIO | RETBLEED), ++ VULNBL_INTEL_STEPPINGS(SKYLAKE_X, X86_STEPPING_ANY, MMIO | RETBLEED | GDS), + VULNBL_INTEL_STEPPINGS(SKYLAKE, X86_STEPPING_ANY, SRBDS | MMIO | RETBLEED), +- VULNBL_INTEL_STEPPINGS(KABYLAKE_L, X86_STEPPING_ANY, SRBDS | MMIO | RETBLEED), +- VULNBL_INTEL_STEPPINGS(KABYLAKE, X86_STEPPING_ANY, SRBDS | MMIO | RETBLEED), ++ VULNBL_INTEL_STEPPINGS(KABYLAKE_L, X86_STEPPING_ANY, SRBDS | MMIO | RETBLEED | GDS), ++ VULNBL_INTEL_STEPPINGS(KABYLAKE, X86_STEPPING_ANY, SRBDS | MMIO | RETBLEED | GDS), + VULNBL_INTEL_STEPPINGS(CANNONLAKE_L, X86_STEPPING_ANY, RETBLEED), +- VULNBL_INTEL_STEPPINGS(ICELAKE_L, X86_STEPPING_ANY, MMIO | MMIO_SBDS | RETBLEED), +- VULNBL_INTEL_STEPPINGS(ICELAKE_D, X86_STEPPING_ANY, MMIO), +- VULNBL_INTEL_STEPPINGS(ICELAKE_X, X86_STEPPING_ANY, MMIO), +- VULNBL_INTEL_STEPPINGS(COMETLAKE, X86_STEPPING_ANY, MMIO | MMIO_SBDS | RETBLEED), ++ VULNBL_INTEL_STEPPINGS(ICELAKE_L, X86_STEPPING_ANY, MMIO | MMIO_SBDS | RETBLEED | GDS), ++ VULNBL_INTEL_STEPPINGS(ICELAKE_D, X86_STEPPING_ANY, MMIO | GDS), ++ VULNBL_INTEL_STEPPINGS(ICELAKE_X, X86_STEPPING_ANY, MMIO | GDS), ++ VULNBL_INTEL_STEPPINGS(COMETLAKE, X86_STEPPING_ANY, MMIO | MMIO_SBDS | RETBLEED | GDS), + VULNBL_INTEL_STEPPINGS(COMETLAKE_L, X86_STEPPINGS(0x0, 0x0), MMIO | RETBLEED), +- VULNBL_INTEL_STEPPINGS(COMETLAKE_L, X86_STEPPING_ANY, MMIO | MMIO_SBDS | RETBLEED), ++ VULNBL_INTEL_STEPPINGS(COMETLAKE_L, X86_STEPPING_ANY, MMIO | MMIO_SBDS | RETBLEED | GDS), ++ VULNBL_INTEL_STEPPINGS(TIGERLAKE_L, X86_STEPPING_ANY, GDS), ++ VULNBL_INTEL_STEPPINGS(TIGERLAKE, X86_STEPPING_ANY, GDS), + VULNBL_INTEL_STEPPINGS(LAKEFIELD, X86_STEPPING_ANY, MMIO | MMIO_SBDS | RETBLEED), +- VULNBL_INTEL_STEPPINGS(ROCKETLAKE, X86_STEPPING_ANY, MMIO | RETBLEED), ++ VULNBL_INTEL_STEPPINGS(ROCKETLAKE, X86_STEPPING_ANY, MMIO | RETBLEED | GDS), + VULNBL_INTEL_STEPPINGS(ATOM_TREMONT, X86_STEPPING_ANY, MMIO | MMIO_SBDS), + VULNBL_INTEL_STEPPINGS(ATOM_TREMONT_D, X86_STEPPING_ANY, MMIO), + VULNBL_INTEL_STEPPINGS(ATOM_TREMONT_L, X86_STEPPING_ANY, MMIO | MMIO_SBDS), +@@ -1273,6 +1293,16 @@ static void __init cpu_set_bug_bits(struct cpuinfo_x86 *c) + !(ia32_cap & ARCH_CAP_PBRSB_NO)) + setup_force_cpu_bug(X86_BUG_EIBRS_PBRSB); + ++ /* ++ * Check if CPU is vulnerable to GDS. If running in a virtual machine on ++ * an affected processor, the VMM may have disabled the use of GATHER by ++ * disabling AVX2. The only way to do this in HW is to clear XCR0[2], ++ * which means that AVX will be disabled. ++ */ ++ if (cpu_matches(cpu_vuln_blacklist, GDS) && !(ia32_cap & ARCH_CAP_GDS_NO) && ++ boot_cpu_has(X86_FEATURE_AVX)) ++ setup_force_cpu_bug(X86_BUG_GDS); ++ + if (cpu_matches(cpu_vuln_whitelist, NO_MELTDOWN)) + return; + +@@ -1358,8 +1388,6 @@ static void __init early_identify_cpu(struct cpuinfo_x86 *c) + + cpu_set_bug_bits(c); + +- fpu__init_system(c); +- + #ifdef CONFIG_X86_32 + /* + * Regardless of whether PCID is enumerated, the SDM says +@@ -1751,6 +1779,8 @@ void identify_secondary_cpu(struct cpuinfo_x86 *c) + validate_apic_and_package_id(c); + x86_spec_ctrl_setup_ap(); + update_srbds_msr(); ++ if (boot_cpu_has_bug(X86_BUG_GDS)) ++ update_gds_msr(); + } + + static __init int setup_noclflush(char *arg) +@@ -2049,8 +2079,6 @@ void cpu_init(void) + clear_all_debug_regs(); + dbg_restore_debug_regs(); + +- fpu__init_cpu(); +- + if (is_uv_system()) + uv_cpu_init(); + +@@ -2108,8 +2136,6 @@ void cpu_init(void) + clear_all_debug_regs(); + dbg_restore_debug_regs(); + +- fpu__init_cpu(); +- + load_fixmap_gdt(cpu); + } + #endif +@@ -2156,3 +2182,69 @@ void arch_smt_update(void) + /* Check whether IPI broadcasting can be enabled */ + apic_smt_update(); + } ++ ++void __init arch_cpu_finalize_init(void) ++{ ++ identify_boot_cpu(); ++ ++ /* ++ * identify_boot_cpu() initialized SMT support information, let the ++ * core code know. ++ */ ++ cpu_smt_check_topology(); ++ ++ if (!IS_ENABLED(CONFIG_SMP)) { ++ pr_info("CPU: "); ++ print_cpu_info(&boot_cpu_data); ++ } ++ ++ cpu_select_mitigations(); ++ ++ arch_smt_update(); ++ ++ if (IS_ENABLED(CONFIG_X86_32)) { ++ /* ++ * Check whether this is a real i386 which is not longer ++ * supported and fixup the utsname. ++ */ ++ if (boot_cpu_data.x86 < 4) ++ panic("Kernel requires i486+ for 'invlpg' and other features"); ++ ++ init_utsname()->machine[1] = ++ '0' + (boot_cpu_data.x86 > 6 ? 6 : boot_cpu_data.x86); ++ } ++ ++ /* ++ * Must be before alternatives because it might set or clear ++ * feature bits. ++ */ ++ fpu__init_system(); ++ fpu__init_cpu(); ++ ++ alternative_instructions(); ++ ++ if (IS_ENABLED(CONFIG_X86_64)) { ++ /* ++ * Make sure the first 2MB area is not mapped by huge pages ++ * There are typically fixed size MTRRs in there and overlapping ++ * MTRRs into large pages causes slow downs. ++ * ++ * Right now we don't do that with gbpages because there seems ++ * very little benefit for that case. ++ */ ++ if (!direct_gbpages) ++ set_memory_4k((unsigned long)__va(0), 1); ++ } else { ++ fpu__init_check_bugs(); ++ } ++ ++ /* ++ * This needs to be called before any devices perform DMA ++ * operations that might use the SWIOTLB bounce buffers. It will ++ * mark the bounce buffers as decrypted so that their usage will ++ * not cause "plain-text" data to be decrypted when accessed. It ++ * must be called after late_time_init() so that Hyper-V x86/x64 ++ * hypercalls work when the SWIOTLB bounce buffers are decrypted. ++ */ ++ mem_encrypt_init(); ++} +diff --git a/arch/x86/kernel/cpu/cpu.h b/arch/x86/kernel/cpu/cpu.h +index 4d04c127c4a79..8a64520b53104 100644 +--- a/arch/x86/kernel/cpu/cpu.h ++++ b/arch/x86/kernel/cpu/cpu.h +@@ -76,9 +76,11 @@ extern void detect_ht(struct cpuinfo_x86 *c); + extern void check_null_seg_clears_base(struct cpuinfo_x86 *c); + + unsigned int aperfmperf_get_khz(int cpu); ++void cpu_select_mitigations(void); + + extern void x86_spec_ctrl_setup_ap(void); + extern void update_srbds_msr(void); ++extern void update_gds_msr(void); + + extern u64 x86_read_arch_cap_msr(void); + +diff --git a/arch/x86/kernel/cpu/scattered.c b/arch/x86/kernel/cpu/scattered.c +index a03e309a0ac5f..37f716eaf0e6d 100644 +--- a/arch/x86/kernel/cpu/scattered.c ++++ b/arch/x86/kernel/cpu/scattered.c +@@ -40,9 +40,6 @@ static const struct cpuid_bit cpuid_bits[] = { + { X86_FEATURE_CPB, CPUID_EDX, 9, 0x80000007, 0 }, + { X86_FEATURE_PROC_FEEDBACK, CPUID_EDX, 11, 0x80000007, 0 }, + { X86_FEATURE_MBA, CPUID_EBX, 6, 0x80000008, 0 }, +- { X86_FEATURE_SME, CPUID_EAX, 0, 0x8000001f, 0 }, +- { X86_FEATURE_SEV, CPUID_EAX, 1, 0x8000001f, 0 }, +- { X86_FEATURE_SME_COHERENT, CPUID_EAX, 10, 0x8000001f, 0 }, + { 0, 0, 0, 0, 0 } + }; + +diff --git a/arch/x86/kernel/fpu/init.c b/arch/x86/kernel/fpu/init.c +index 17d092eb1934c..5e710ad6a3c0a 100644 +--- a/arch/x86/kernel/fpu/init.c ++++ b/arch/x86/kernel/fpu/init.c +@@ -50,7 +50,7 @@ void fpu__init_cpu(void) + fpu__init_cpu_xstate(); + } + +-static bool fpu__probe_without_cpuid(void) ++static bool __init fpu__probe_without_cpuid(void) + { + unsigned long cr0; + u16 fsw, fcw; +@@ -68,7 +68,7 @@ static bool fpu__probe_without_cpuid(void) + return fsw == 0 && (fcw & 0x103f) == 0x003f; + } + +-static void fpu__init_system_early_generic(struct cpuinfo_x86 *c) ++static void __init fpu__init_system_early_generic(void) + { + if (!boot_cpu_has(X86_FEATURE_CPUID) && + !test_bit(X86_FEATURE_FPU, (unsigned long *)cpu_caps_cleared)) { +@@ -290,10 +290,10 @@ static void __init fpu__init_parse_early_param(void) + * Called on the boot CPU once per system bootup, to set up the initial + * FPU state that is later cloned into all processes: + */ +-void __init fpu__init_system(struct cpuinfo_x86 *c) ++void __init fpu__init_system(void) + { + fpu__init_parse_early_param(); +- fpu__init_system_early_generic(c); ++ fpu__init_system_early_generic(); + + /* + * The FPU has to be operational for some of the +diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c +index 45e5ecb43393b..d6a8efff9c617 100644 +--- a/arch/x86/kernel/smpboot.c ++++ b/arch/x86/kernel/smpboot.c +@@ -235,6 +235,7 @@ static void notrace start_secondary(void *unused) + #endif + load_current_idt(); + cpu_init(); ++ fpu__init_cpu(); + rcu_cpu_starting(raw_smp_processor_id()); + x86_cpuinit.early_percpu_clock_init(); + preempt_disable(); +diff --git a/arch/x86/kvm/cpuid.h b/arch/x86/kvm/cpuid.h +index 7dec43b2c4205..defae8082789f 100644 +--- a/arch/x86/kvm/cpuid.h ++++ b/arch/x86/kvm/cpuid.h +@@ -53,6 +53,7 @@ static const struct cpuid_reg reverse_cpuid[] = { + [CPUID_7_ECX] = { 7, 0, CPUID_ECX}, + [CPUID_8000_0007_EBX] = {0x80000007, 0, CPUID_EBX}, + [CPUID_7_EDX] = { 7, 0, CPUID_EDX}, ++ [CPUID_8000_0021_EAX] = {0x80000021, 0, CPUID_EAX}, + }; + + static __always_inline struct cpuid_reg x86_feature_cpuid(unsigned x86_feature) +diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c +index d152afdfa8b4f..2ee3da99bc1d7 100644 +--- a/arch/x86/kvm/x86.c ++++ b/arch/x86/kvm/x86.c +@@ -226,6 +226,8 @@ struct kvm_stats_debugfs_item debugfs_entries[] = { + + u64 __read_mostly host_xcr0; + ++extern bool gds_ucode_mitigated(void); ++ + struct kmem_cache *x86_fpu_cache; + EXPORT_SYMBOL_GPL(x86_fpu_cache); + +@@ -1409,6 +1411,9 @@ static u64 kvm_get_arch_capabilities(void) + /* Guests don't need to know "Fill buffer clear control" exists */ + data &= ~ARCH_CAP_FB_CLEAR_CTRL; + ++ if (!boot_cpu_has_bug(X86_BUG_GDS) || gds_ucode_mitigated()) ++ data |= ARCH_CAP_GDS_NO; ++ + return data; + } + +diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c +index 38e6798ce44fc..086b274fa60f6 100644 +--- a/arch/x86/mm/init.c ++++ b/arch/x86/mm/init.c +@@ -7,6 +7,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -26,6 +27,7 @@ + #include + #include + #include ++#include + + /* + * We need to define the tracepoints somewhere, and tlb.c +@@ -735,9 +737,12 @@ void __init poking_init(void) + spinlock_t *ptl; + pte_t *ptep; + +- poking_mm = copy_init_mm(); ++ poking_mm = mm_alloc(); + BUG_ON(!poking_mm); + ++ /* Xen PV guests need the PGD to be pinned. */ ++ paravirt_arch_dup_mmap(NULL, poking_mm); ++ + /* + * Randomize the poking address, but make sure that the following page + * will be mapped at the same PMD. We need 2 pages, so find space for 3, +diff --git a/arch/x86/xen/smp_pv.c b/arch/x86/xen/smp_pv.c +index 928fbe63c96f8..3a0a27d94c05d 100644 +--- a/arch/x86/xen/smp_pv.c ++++ b/arch/x86/xen/smp_pv.c +@@ -28,6 +28,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -61,6 +62,7 @@ static void cpu_bringup(void) + + cr4_init(); + cpu_init(); ++ fpu__init_cpu(); + touch_softlockup_watchdog(); + preempt_disable(); + +diff --git a/arch/xtensa/include/asm/bugs.h b/arch/xtensa/include/asm/bugs.h +deleted file mode 100644 +index 69b29d1982494..0000000000000 +--- a/arch/xtensa/include/asm/bugs.h ++++ /dev/null +@@ -1,18 +0,0 @@ +-/* +- * include/asm-xtensa/bugs.h +- * +- * This is included by init/main.c to check for architecture-dependent bugs. +- * +- * Xtensa processors don't have any bugs. :) +- * +- * This file is subject to the terms and conditions of the GNU General +- * Public License. See the file "COPYING" in the main directory of +- * this archive for more details. +- */ +- +-#ifndef _XTENSA_BUGS_H +-#define _XTENSA_BUGS_H +- +-static void check_bugs(void) { } +- +-#endif /* _XTENSA_BUGS_H */ +diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c +index 980e9a76e1723..5e0c1fd27720e 100644 +--- a/drivers/base/cpu.c ++++ b/drivers/base/cpu.c +@@ -581,6 +581,12 @@ ssize_t __weak cpu_show_retbleed(struct device *dev, + return sysfs_emit(buf, "Not affected\n"); + } + ++ssize_t __weak cpu_show_gds(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ return sysfs_emit(buf, "Not affected\n"); ++} ++ + static DEVICE_ATTR(meltdown, 0444, cpu_show_meltdown, NULL); + static DEVICE_ATTR(spectre_v1, 0444, cpu_show_spectre_v1, NULL); + static DEVICE_ATTR(spectre_v2, 0444, cpu_show_spectre_v2, NULL); +@@ -592,6 +598,7 @@ static DEVICE_ATTR(itlb_multihit, 0444, cpu_show_itlb_multihit, NULL); + static DEVICE_ATTR(srbds, 0444, cpu_show_srbds, NULL); + static DEVICE_ATTR(mmio_stale_data, 0444, cpu_show_mmio_stale_data, NULL); + static DEVICE_ATTR(retbleed, 0444, cpu_show_retbleed, NULL); ++static DEVICE_ATTR(gather_data_sampling, 0444, cpu_show_gds, NULL); + + static struct attribute *cpu_root_vulnerabilities_attrs[] = { + &dev_attr_meltdown.attr, +@@ -605,6 +612,7 @@ static struct attribute *cpu_root_vulnerabilities_attrs[] = { + &dev_attr_srbds.attr, + &dev_attr_mmio_stale_data.attr, + &dev_attr_retbleed.attr, ++ &dev_attr_gather_data_sampling.attr, + NULL + }; + +diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c +index a3078755939e3..c3eadac893d88 100644 +--- a/drivers/net/xen-netback/netback.c ++++ b/drivers/net/xen-netback/netback.c +@@ -389,7 +389,7 @@ static void xenvif_get_requests(struct xenvif_queue *queue, + struct gnttab_map_grant_ref *gop = queue->tx_map_ops + *map_ops; + struct xen_netif_tx_request *txp = first; + +- nr_slots = shinfo->nr_frags + 1; ++ nr_slots = shinfo->nr_frags + frag_overflow + 1; + + copy_count(skb) = 0; + XENVIF_TX_CB(skb)->split_mask = 0; +@@ -455,8 +455,8 @@ static void xenvif_get_requests(struct xenvif_queue *queue, + } + } + +- for (shinfo->nr_frags = 0; shinfo->nr_frags < nr_slots; +- shinfo->nr_frags++, gop++) { ++ for (shinfo->nr_frags = 0; nr_slots > 0 && shinfo->nr_frags < MAX_SKB_FRAGS; ++ shinfo->nr_frags++, gop++, nr_slots--) { + index = pending_index(queue->pending_cons++); + pending_idx = queue->pending_ring[index]; + xenvif_tx_create_map_op(queue, pending_idx, txp, +@@ -469,12 +469,12 @@ static void xenvif_get_requests(struct xenvif_queue *queue, + txp++; + } + +- if (frag_overflow) { ++ if (nr_slots > 0) { + + shinfo = skb_shinfo(nskb); + frags = shinfo->frags; + +- for (shinfo->nr_frags = 0; shinfo->nr_frags < frag_overflow; ++ for (shinfo->nr_frags = 0; shinfo->nr_frags < nr_slots; + shinfo->nr_frags++, txp++, gop++) { + index = pending_index(queue->pending_cons++); + pending_idx = queue->pending_ring[index]; +@@ -485,6 +485,11 @@ static void xenvif_get_requests(struct xenvif_queue *queue, + } + + skb_shinfo(skb)->frag_list = nskb; ++ } else if (nskb) { ++ /* A frag_list skb was allocated but it is no longer needed ++ * because enough slots were converted to copy ops above. ++ */ ++ kfree_skb(nskb); + } + + (*copy_ops) = cop - queue->tx_copy_ops; +diff --git a/include/asm-generic/bugs.h b/include/asm-generic/bugs.h +deleted file mode 100644 +index 69021830f078d..0000000000000 +--- a/include/asm-generic/bugs.h ++++ /dev/null +@@ -1,11 +0,0 @@ +-/* SPDX-License-Identifier: GPL-2.0 */ +-#ifndef __ASM_GENERIC_BUGS_H +-#define __ASM_GENERIC_BUGS_H +-/* +- * This file is included by 'init/main.c' to check for +- * architecture-dependent bugs. +- */ +- +-static inline void check_bugs(void) { } +- +-#endif /* __ASM_GENERIC_BUGS_H */ +diff --git a/include/linux/cpu.h b/include/linux/cpu.h +index b42e9c4134475..782491dd19998 100644 +--- a/include/linux/cpu.h ++++ b/include/linux/cpu.h +@@ -193,6 +193,12 @@ void arch_cpu_idle_enter(void); + void arch_cpu_idle_exit(void); + void arch_cpu_idle_dead(void); + ++#ifdef CONFIG_ARCH_HAS_CPU_FINALIZE_INIT ++void arch_cpu_finalize_init(void); ++#else ++static inline void arch_cpu_finalize_init(void) { } ++#endif ++ + int cpu_report_state(int cpu); + int cpu_check_up_prepare(int cpu); + void cpu_set_state_online(int cpu); +diff --git a/include/linux/sched/task.h b/include/linux/sched/task.h +index 6f33a07858cf6..853ab403e77b8 100644 +--- a/include/linux/sched/task.h ++++ b/include/linux/sched/task.h +@@ -53,6 +53,7 @@ extern void sched_dead(struct task_struct *p); + void __noreturn do_task_dead(void); + void __noreturn make_task_dead(int signr); + ++extern void mm_cache_init(void); + extern void proc_caches_init(void); + + extern void fork_init(void); +@@ -93,7 +94,6 @@ extern long _do_fork(struct kernel_clone_args *kargs); + extern bool legacy_clone_args_valid(const struct kernel_clone_args *kargs); + extern long do_fork(unsigned long, unsigned long, unsigned long, int __user *, int __user *); + struct task_struct *fork_idle(int); +-struct mm_struct *copy_init_mm(void); + extern pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags); + extern long kernel_wait4(pid_t, int __user *, int, struct rusage *); + +diff --git a/init/main.c b/init/main.c +index a17a111d93362..1db844b388103 100644 +--- a/init/main.c ++++ b/init/main.c +@@ -93,10 +93,8 @@ + #include + #include + #include +-#include + + #include +-#include + #include + #include + #include +@@ -504,8 +502,6 @@ void __init __weak thread_stack_cache_init(void) + } + #endif + +-void __init __weak mem_encrypt_init(void) { } +- + void __init __weak poking_init(void) { } + + void __init __weak pgtable_cache_init(void) { } +@@ -567,6 +563,7 @@ static void __init mm_init(void) + init_espfix_bsp(); + /* Should be run after espfix64 is set up. */ + pti_init(); ++ mm_cache_init(); + } + + void __init __weak arch_call_rest_init(void) +@@ -627,7 +624,7 @@ asmlinkage __visible void __init start_kernel(void) + sort_main_extable(); + trap_init(); + mm_init(); +- ++ poking_init(); + ftrace_init(); + + /* trace_printk can be enabled here */ +@@ -721,14 +718,6 @@ asmlinkage __visible void __init start_kernel(void) + */ + locking_selftest(); + +- /* +- * This needs to be called before any devices perform DMA +- * operations that might use the SWIOTLB bounce buffers. It will +- * mark the bounce buffers as decrypted so that their usage will +- * not cause "plain-text" data to be decrypted when accessed. +- */ +- mem_encrypt_init(); +- + #ifdef CONFIG_BLK_DEV_INITRD + if (initrd_start && !initrd_below_start_ok && + page_to_pfn(virt_to_page((void *)initrd_start)) < min_low_pfn) { +@@ -745,6 +734,9 @@ asmlinkage __visible void __init start_kernel(void) + late_time_init(); + sched_clock_init(); + calibrate_delay(); ++ ++ arch_cpu_finalize_init(); ++ + pid_idr_init(); + anon_vma_init(); + #ifdef CONFIG_X86 +@@ -771,9 +763,6 @@ asmlinkage __visible void __init start_kernel(void) + taskstats_init_early(); + delayacct_init(); + +- poking_init(); +- check_bugs(); +- + acpi_subsystem_init(); + arch_post_acpi_subsys_init(); + sfi_init_late(); +diff --git a/kernel/fork.c b/kernel/fork.c +index 5b4a19682207a..39134effb2bff 100644 +--- a/kernel/fork.c ++++ b/kernel/fork.c +@@ -2335,11 +2335,6 @@ struct task_struct *fork_idle(int cpu) + return task; + } + +-struct mm_struct *copy_init_mm(void) +-{ +- return dup_mm(NULL, &init_mm); +-} +- + /* + * Ok, this is the main fork-routine. + * +@@ -2710,10 +2705,27 @@ static void sighand_ctor(void *data) + init_waitqueue_head(&sighand->signalfd_wqh); + } + +-void __init proc_caches_init(void) ++void __init mm_cache_init(void) + { + unsigned int mm_size; + ++ /* ++ * The mm_cpumask is located at the end of mm_struct, and is ++ * dynamically sized based on the maximum CPU number this system ++ * can have, taking hotplug into account (nr_cpu_ids). ++ */ ++ mm_size = sizeof(struct mm_struct) + cpumask_size(); ++ ++ mm_cachep = kmem_cache_create_usercopy("mm_struct", ++ mm_size, ARCH_MIN_MMSTRUCT_ALIGN, ++ SLAB_HWCACHE_ALIGN|SLAB_PANIC|SLAB_ACCOUNT, ++ offsetof(struct mm_struct, saved_auxv), ++ sizeof_field(struct mm_struct, saved_auxv), ++ NULL); ++} ++ ++void __init proc_caches_init(void) ++{ + sighand_cachep = kmem_cache_create("sighand_cache", + sizeof(struct sighand_struct), 0, + SLAB_HWCACHE_ALIGN|SLAB_PANIC|SLAB_TYPESAFE_BY_RCU| +@@ -2731,19 +2743,6 @@ void __init proc_caches_init(void) + SLAB_HWCACHE_ALIGN|SLAB_PANIC|SLAB_ACCOUNT, + NULL); + +- /* +- * The mm_cpumask is located at the end of mm_struct, and is +- * dynamically sized based on the maximum CPU number this system +- * can have, taking hotplug into account (nr_cpu_ids). +- */ +- mm_size = sizeof(struct mm_struct) + cpumask_size(); +- +- mm_cachep = kmem_cache_create_usercopy("mm_struct", +- mm_size, ARCH_MIN_MMSTRUCT_ALIGN, +- SLAB_HWCACHE_ALIGN|SLAB_PANIC|SLAB_ACCOUNT, +- offsetof(struct mm_struct, saved_auxv), +- sizeof_field(struct mm_struct, saved_auxv), +- NULL); + vm_area_cachep = KMEM_CACHE(vm_area_struct, SLAB_PANIC|SLAB_ACCOUNT); + mmap_init(); + nsproxy_cache_init(); +diff --git a/tools/arch/x86/include/asm/cpufeatures.h b/tools/arch/x86/include/asm/cpufeatures.h +index 3efaf338d3257..eea52cb0e6ab1 100644 +--- a/tools/arch/x86/include/asm/cpufeatures.h ++++ b/tools/arch/x86/include/asm/cpufeatures.h +@@ -13,8 +13,8 @@ + /* + * Defines x86 CPU feature bits + */ +-#define NCAPINTS 19 /* N 32-bit words worth of info */ +-#define NBUGINTS 1 /* N 32-bit bug flags */ ++#define NCAPINTS 20 /* N 32-bit words worth of info */ ++#define NBUGINTS 2 /* N 32-bit bug flags */ + + /* + * Note: If the comment begins with a quoted string, that string is used +@@ -96,6 +96,7 @@ + #define X86_FEATURE_SYSCALL32 ( 3*32+14) /* "" syscall in IA32 userspace */ + #define X86_FEATURE_SYSENTER32 ( 3*32+15) /* "" sysenter in IA32 userspace */ + #define X86_FEATURE_REP_GOOD ( 3*32+16) /* REP microcode works well */ ++/* FREE! ( 3*32+17) */ + #define X86_FEATURE_LFENCE_RDTSC ( 3*32+18) /* "" LFENCE synchronizes RDTSC */ + #define X86_FEATURE_ACC_POWER ( 3*32+19) /* AMD Accumulated Power Mechanism */ + #define X86_FEATURE_NOPL ( 3*32+20) /* The NOPL (0F 1F) instructions */ +@@ -199,7 +200,7 @@ + #define X86_FEATURE_INVPCID_SINGLE ( 7*32+ 7) /* Effectively INVPCID && CR4.PCIDE=1 */ + #define X86_FEATURE_HW_PSTATE ( 7*32+ 8) /* AMD HW-PState */ + #define X86_FEATURE_PROC_FEEDBACK ( 7*32+ 9) /* AMD ProcFeedbackInterface */ +-#define X86_FEATURE_SME ( 7*32+10) /* AMD Secure Memory Encryption */ ++/* FREE! ( 7*32+10) */ + #define X86_FEATURE_PTI ( 7*32+11) /* Kernel Page Table Isolation enabled */ + #define X86_FEATURE_RETPOLINE ( 7*32+12) /* "" Generic Retpoline mitigation for Spectre variant 2 */ + #define X86_FEATURE_RETPOLINE_LFENCE ( 7*32+13) /* "" Use LFENCEs for Spectre variant 2 */ +@@ -209,7 +210,7 @@ + #define X86_FEATURE_SSBD ( 7*32+17) /* Speculative Store Bypass Disable */ + #define X86_FEATURE_MBA ( 7*32+18) /* Memory Bandwidth Allocation */ + #define X86_FEATURE_RSB_CTXSW ( 7*32+19) /* "" Fill RSB on context switches */ +-#define X86_FEATURE_SEV ( 7*32+20) /* AMD Secure Encrypted Virtualization */ ++/* FREE! ( 7*32+20) */ + #define X86_FEATURE_USE_IBPB ( 7*32+21) /* "" Indirect Branch Prediction Barrier enabled */ + #define X86_FEATURE_USE_IBRS_FW ( 7*32+22) /* "" Use IBRS during runtime firmware calls */ + #define X86_FEATURE_SPEC_STORE_BYPASS_DISABLE ( 7*32+23) /* "" Disable Speculative Store Bypass. */ +@@ -287,6 +288,7 @@ + #define X86_FEATURE_RSB_VMEXIT_LITE (11*32+17) /* "" Fill RSB on VM-Exit when EIBRS is enabled */ + + /* Intel-defined CPU features, CPUID level 0x00000007:1 (EAX), word 12 */ ++#define X86_FEATURE_AVX_VNNI (12*32+ 4) /* AVX VNNI instructions */ + #define X86_FEATURE_AVX512_BF16 (12*32+ 5) /* AVX512 BFLOAT16 instructions */ + + /* AMD-defined CPU features, CPUID level 0x80000008 (EBX), word 13 */ +@@ -328,6 +330,7 @@ + #define X86_FEATURE_AVIC (15*32+13) /* Virtual Interrupt Controller */ + #define X86_FEATURE_V_VMSAVE_VMLOAD (15*32+15) /* Virtual VMSAVE VMLOAD */ + #define X86_FEATURE_VGIF (15*32+16) /* Virtual GIF */ ++#define X86_FEATURE_SVME_ADDR_CHK (15*32+28) /* "" SVME addr check */ + + /* Intel-defined CPU features, CPUID level 0x00000007:0 (ECX), word 16 */ + #define X86_FEATURE_AVX512VBMI (16*32+ 1) /* AVX512 Vector Bit Manipulation instructions*/ +@@ -367,6 +370,13 @@ + #define X86_FEATURE_ARCH_CAPABILITIES (18*32+29) /* IA32_ARCH_CAPABILITIES MSR (Intel) */ + #define X86_FEATURE_SPEC_CTRL_SSBD (18*32+31) /* "" Speculative Store Bypass Disable */ + ++/* AMD-defined memory encryption features, CPUID level 0x8000001f (EAX), word 19 */ ++#define X86_FEATURE_SME (19*32+ 0) /* AMD Secure Memory Encryption */ ++#define X86_FEATURE_SEV (19*32+ 1) /* AMD Secure Encrypted Virtualization */ ++#define X86_FEATURE_VM_PAGE_FLUSH (19*32+ 2) /* "" VM Page Flush MSR is supported */ ++#define X86_FEATURE_SEV_ES (19*32+ 3) /* AMD Secure Encrypted Virtualization - Encrypted State */ ++#define X86_FEATURE_SME_COHERENT (19*32+10) /* "" AMD hardware-enforced cache coherency */ ++ + /* + * BUG word(s) + */ +diff --git a/tools/arch/x86/include/asm/disabled-features.h b/tools/arch/x86/include/asm/disabled-features.h +index a5ea841cc6d22..f0f935f8d9174 100644 +--- a/tools/arch/x86/include/asm/disabled-features.h ++++ b/tools/arch/x86/include/asm/disabled-features.h +@@ -84,6 +84,7 @@ + #define DISABLED_MASK16 (DISABLE_PKU|DISABLE_OSPKE|DISABLE_LA57|DISABLE_UMIP) + #define DISABLED_MASK17 0 + #define DISABLED_MASK18 0 +-#define DISABLED_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS != 19) ++#define DISABLED_MASK19 0 ++#define DISABLED_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS != 20) + + #endif /* _ASM_X86_DISABLED_FEATURES_H */ +diff --git a/tools/arch/x86/include/asm/required-features.h b/tools/arch/x86/include/asm/required-features.h +index 6847d85400a8b..fa5700097f647 100644 +--- a/tools/arch/x86/include/asm/required-features.h ++++ b/tools/arch/x86/include/asm/required-features.h +@@ -101,6 +101,7 @@ + #define REQUIRED_MASK16 0 + #define REQUIRED_MASK17 0 + #define REQUIRED_MASK18 0 +-#define REQUIRED_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS != 19) ++#define REQUIRED_MASK19 0 ++#define REQUIRED_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS != 20) + + #endif /* _ASM_X86_REQUIRED_FEATURES_H */ diff --git a/patch/kernel/archive/odroidxu4-5.4/patch-5.4.252-253.patch b/patch/kernel/archive/odroidxu4-5.4/patch-5.4.252-253.patch new file mode 100644 index 000000000000..b4bef8ffae19 --- /dev/null +++ b/patch/kernel/archive/odroidxu4-5.4/patch-5.4.252-253.patch @@ -0,0 +1,5694 @@ +diff --git a/Documentation/admin-guide/security-bugs.rst b/Documentation/admin-guide/security-bugs.rst +index dcd6c93c7aacb..521acda367aee 100644 +--- a/Documentation/admin-guide/security-bugs.rst ++++ b/Documentation/admin-guide/security-bugs.rst +@@ -56,31 +56,28 @@ information submitted to the security list and any followup discussions + of the report are treated confidentially even after the embargo has been + lifted, in perpetuity. + +-Coordination +------------- +- +-Fixes for sensitive bugs, such as those that might lead to privilege +-escalations, may need to be coordinated with the private +- mailing list so that distribution vendors +-are well prepared to issue a fixed kernel upon public disclosure of the +-upstream fix. Distros will need some time to test the proposed patch and +-will generally request at least a few days of embargo, and vendor update +-publication prefers to happen Tuesday through Thursday. When appropriate, +-the security team can assist with this coordination, or the reporter can +-include linux-distros from the start. In this case, remember to prefix +-the email Subject line with "[vs]" as described in the linux-distros wiki: +- ++Coordination with other groups ++------------------------------ ++ ++The kernel security team strongly recommends that reporters of potential ++security issues NEVER contact the "linux-distros" mailing list until ++AFTER discussing it with the kernel security team. Do not Cc: both ++lists at once. You may contact the linux-distros mailing list after a ++fix has been agreed on and you fully understand the requirements that ++doing so will impose on you and the kernel community. ++ ++The different lists have different goals and the linux-distros rules do ++not contribute to actually fixing any potential security problems. + + CVE assignment + -------------- + +-The security team does not normally assign CVEs, nor do we require them +-for reports or fixes, as this can needlessly complicate the process and +-may delay the bug handling. If a reporter wishes to have a CVE identifier +-assigned ahead of public disclosure, they will need to contact the private +-linux-distros list, described above. When such a CVE identifier is known +-before a patch is provided, it is desirable to mention it in the commit +-message if the reporter agrees. ++The security team does not assign CVEs, nor do we require them for ++reports or fixes, as this can needlessly complicate the process and may ++delay the bug handling. If a reporter wishes to have a CVE identifier ++assigned, they should find one by themselves, for example by contacting ++MITRE directly. However under no circumstances will a patch inclusion ++be delayed to wait for a CVE identifier to arrive. + + Non-disclosure agreements + ------------------------- +diff --git a/Makefile b/Makefile +index be75dc3ae8de0..a0e3daefb01d9 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,7 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0 + VERSION = 5 + PATCHLEVEL = 4 +-SUBLEVEL = 252 ++SUBLEVEL = 253 + EXTRAVERSION = + NAME = Kleptomaniac Octopus + +diff --git a/arch/arm/boot/dts/imx35.dtsi b/arch/arm/boot/dts/imx35.dtsi +index 9cbdc1a15cda2..d326b18333d15 100644 +--- a/arch/arm/boot/dts/imx35.dtsi ++++ b/arch/arm/boot/dts/imx35.dtsi +@@ -59,7 +59,7 @@ + interrupt-parent = <&avic>; + ranges; + +- L2: l2-cache@30000000 { ++ L2: cache-controller@30000000 { + compatible = "arm,l210-cache"; + reg = <0x30000000 0x1000>; + cache-unified; +diff --git a/arch/arm/boot/dts/imx6qdl.dtsi b/arch/arm/boot/dts/imx6qdl.dtsi +index e9955ef12e02d..bb02923bc2e5b 100644 +--- a/arch/arm/boot/dts/imx6qdl.dtsi ++++ b/arch/arm/boot/dts/imx6qdl.dtsi +@@ -45,6 +45,10 @@ + spi1 = &ecspi2; + spi2 = &ecspi3; + spi3 = &ecspi4; ++ usb0 = &usbotg; ++ usb1 = &usbh1; ++ usb2 = &usbh2; ++ usb3 = &usbh3; + usbphy0 = &usbphy1; + usbphy1 = &usbphy2; + }; +@@ -255,7 +259,7 @@ + interrupt-parent = <&intc>; + }; + +- L2: l2-cache@a02000 { ++ L2: cache-controller@a02000 { + compatible = "arm,pl310-cache"; + reg = <0x00a02000 0x1000>; + interrupts = <0 92 IRQ_TYPE_LEVEL_HIGH>; +diff --git a/arch/arm/boot/dts/imx6sl.dtsi b/arch/arm/boot/dts/imx6sl.dtsi +index 852f66944c7d4..3cf1da06e7f04 100644 +--- a/arch/arm/boot/dts/imx6sl.dtsi ++++ b/arch/arm/boot/dts/imx6sl.dtsi +@@ -39,6 +39,9 @@ + spi1 = &ecspi2; + spi2 = &ecspi3; + spi3 = &ecspi4; ++ usb0 = &usbotg1; ++ usb1 = &usbotg2; ++ usb2 = &usbh; + usbphy0 = &usbphy1; + usbphy1 = &usbphy2; + }; +@@ -136,7 +139,7 @@ + interrupt-parent = <&intc>; + }; + +- L2: l2-cache@a02000 { ++ L2: cache-controller@a02000 { + compatible = "arm,pl310-cache"; + reg = <0x00a02000 0x1000>; + interrupts = <0 92 IRQ_TYPE_LEVEL_HIGH>; +diff --git a/arch/arm/boot/dts/imx6sll.dtsi b/arch/arm/boot/dts/imx6sll.dtsi +index 39500b84673b9..ad3deb82a50ac 100644 +--- a/arch/arm/boot/dts/imx6sll.dtsi ++++ b/arch/arm/boot/dts/imx6sll.dtsi +@@ -36,6 +36,8 @@ + spi1 = &ecspi2; + spi3 = &ecspi3; + spi4 = &ecspi4; ++ usb0 = &usbotg1; ++ usb1 = &usbotg2; + usbphy0 = &usbphy1; + usbphy1 = &usbphy2; + }; +@@ -49,20 +51,18 @@ + device_type = "cpu"; + reg = <0>; + next-level-cache = <&L2>; +- operating-points = < ++ operating-points = + /* kHz uV */ +- 996000 1275000 +- 792000 1175000 +- 396000 1075000 +- 198000 975000 +- >; +- fsl,soc-operating-points = < ++ <996000 1275000>, ++ <792000 1175000>, ++ <396000 1075000>, ++ <198000 975000>; ++ fsl,soc-operating-points = + /* ARM kHz SOC-PU uV */ +- 996000 1175000 +- 792000 1175000 +- 396000 1175000 +- 198000 1175000 +- >; ++ <996000 1175000>, ++ <792000 1175000>, ++ <396000 1175000>, ++ <198000 1175000>; + clock-latency = <61036>; /* two CLK32 periods */ + #cooling-cells = <2>; + clocks = <&clks IMX6SLL_CLK_ARM>, +@@ -137,7 +137,7 @@ + interrupt-parent = <&intc>; + }; + +- L2: l2-cache@a02000 { ++ L2: cache-controller@a02000 { + compatible = "arm,pl310-cache"; + reg = <0x00a02000 0x1000>; + interrupts = ; +@@ -272,7 +272,7 @@ + status = "disabled"; + }; + +- ssi1: ssi-controller@2028000 { ++ ssi1: ssi@2028000 { + compatible = "fsl,imx6sl-ssi", "fsl,imx51-ssi"; + reg = <0x02028000 0x4000>; + interrupts = ; +@@ -285,7 +285,7 @@ + status = "disabled"; + }; + +- ssi2: ssi-controller@202c000 { ++ ssi2: ssi@202c000 { + compatible = "fsl,imx6sl-ssi", "fsl,imx51-ssi"; + reg = <0x0202c000 0x4000>; + interrupts = ; +@@ -298,7 +298,7 @@ + status = "disabled"; + }; + +- ssi3: ssi-controller@2030000 { ++ ssi3: ssi@2030000 { + compatible = "fsl,imx6sl-ssi", "fsl,imx51-ssi"; + reg = <0x02030000 0x4000>; + interrupts = ; +@@ -550,7 +550,7 @@ + reg = <0x020ca000 0x1000>; + interrupts = ; + clocks = <&clks IMX6SLL_CLK_USBPHY2>; +- phy-reg_3p0-supply = <®_3p0>; ++ phy-3p0-supply = <®_3p0>; + fsl,anatop = <&anatop>; + }; + +diff --git a/arch/arm/boot/dts/imx6sx.dtsi b/arch/arm/boot/dts/imx6sx.dtsi +index b3e24d8bd2994..790cc88c8b1ae 100644 +--- a/arch/arm/boot/dts/imx6sx.dtsi ++++ b/arch/arm/boot/dts/imx6sx.dtsi +@@ -49,6 +49,9 @@ + spi2 = &ecspi3; + spi3 = &ecspi4; + spi4 = &ecspi5; ++ usb0 = &usbotg1; ++ usb1 = &usbotg2; ++ usb2 = &usbh; + usbphy0 = &usbphy1; + usbphy1 = &usbphy2; + }; +@@ -187,7 +190,7 @@ + interrupt-parent = <&intc>; + }; + +- L2: l2-cache@a02000 { ++ L2: cache-controller@a02000 { + compatible = "arm,pl310-cache"; + reg = <0x00a02000 0x1000>; + interrupts = ; +diff --git a/arch/arm/boot/dts/imx6ul.dtsi b/arch/arm/boot/dts/imx6ul.dtsi +index ae0722b93b9d7..05390cc2a3b3b 100644 +--- a/arch/arm/boot/dts/imx6ul.dtsi ++++ b/arch/arm/boot/dts/imx6ul.dtsi +@@ -47,6 +47,8 @@ + spi1 = &ecspi2; + spi2 = &ecspi3; + spi3 = &ecspi4; ++ usb0 = &usbotg1; ++ usb1 = &usbotg2; + usbphy0 = &usbphy1; + usbphy1 = &usbphy2; + }; +diff --git a/arch/arm/boot/dts/imx7d.dtsi b/arch/arm/boot/dts/imx7d.dtsi +index 9c8dd32cc035f..8b65ca8b5f30f 100644 +--- a/arch/arm/boot/dts/imx7d.dtsi ++++ b/arch/arm/boot/dts/imx7d.dtsi +@@ -7,6 +7,12 @@ + #include + + / { ++ aliases { ++ usb0 = &usbotg1; ++ usb1 = &usbotg2; ++ usb2 = &usbh; ++ }; ++ + cpus { + cpu0: cpu@0 { + clock-frequency = <996000000>; +diff --git a/arch/arm/boot/dts/imx7s.dtsi b/arch/arm/boot/dts/imx7s.dtsi +index 1ef076b64de26..e5151a7849d6b 100644 +--- a/arch/arm/boot/dts/imx7s.dtsi ++++ b/arch/arm/boot/dts/imx7s.dtsi +@@ -47,6 +47,8 @@ + spi1 = &ecspi2; + spi2 = &ecspi3; + spi3 = &ecspi4; ++ usb0 = &usbotg1; ++ usb1 = &usbh; + }; + + cpus { +diff --git a/arch/arm64/boot/dts/altera/socfpga_stratix10_socdk.dts b/arch/arm64/boot/dts/altera/socfpga_stratix10_socdk.dts +index 2c8c2b322c727..33f1fb9fd161f 100644 +--- a/arch/arm64/boot/dts/altera/socfpga_stratix10_socdk.dts ++++ b/arch/arm64/boot/dts/altera/socfpga_stratix10_socdk.dts +@@ -129,7 +129,7 @@ + status = "okay"; + clock-frequency = <100000>; + i2c-sda-falling-time-ns = <890>; /* hcnt */ +- i2c-sdl-falling-time-ns = <890>; /* lcnt */ ++ i2c-scl-falling-time-ns = <890>; /* lcnt */ + + adc@14 { + compatible = "lltc,ltc2497"; +diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h +index f0165df489a38..892fc0ceccb85 100644 +--- a/arch/arm64/include/asm/cputype.h ++++ b/arch/arm64/include/asm/cputype.h +@@ -41,7 +41,7 @@ + (((midr) & MIDR_IMPLEMENTOR_MASK) >> MIDR_IMPLEMENTOR_SHIFT) + + #define MIDR_CPU_MODEL(imp, partnum) \ +- (((imp) << MIDR_IMPLEMENTOR_SHIFT) | \ ++ ((_AT(u32, imp) << MIDR_IMPLEMENTOR_SHIFT) | \ + (0xf << MIDR_ARCHITECTURE_SHIFT) | \ + ((partnum) << MIDR_PARTNUM_SHIFT)) + +@@ -59,6 +59,7 @@ + #define ARM_CPU_IMP_NVIDIA 0x4E + #define ARM_CPU_IMP_FUJITSU 0x46 + #define ARM_CPU_IMP_HISI 0x48 ++#define ARM_CPU_IMP_AMPERE 0xC0 + + #define ARM_CPU_PART_AEM_V8 0xD0F + #define ARM_CPU_PART_FOUNDATION 0xD00 +@@ -101,6 +102,8 @@ + + #define HISI_CPU_PART_TSV110 0xD01 + ++#define AMPERE_CPU_PART_AMPERE1 0xAC3 ++ + #define MIDR_CORTEX_A53 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A53) + #define MIDR_CORTEX_A57 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A57) + #define MIDR_CORTEX_A72 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A72) +@@ -131,6 +134,7 @@ + #define MIDR_NVIDIA_CARMEL MIDR_CPU_MODEL(ARM_CPU_IMP_NVIDIA, NVIDIA_CPU_PART_CARMEL) + #define MIDR_FUJITSU_A64FX MIDR_CPU_MODEL(ARM_CPU_IMP_FUJITSU, FUJITSU_CPU_PART_A64FX) + #define MIDR_HISI_TSV110 MIDR_CPU_MODEL(ARM_CPU_IMP_HISI, HISI_CPU_PART_TSV110) ++#define MIDR_AMPERE1 MIDR_CPU_MODEL(ARM_CPU_IMP_AMPERE, AMPERE_CPU_PART_AMPERE1) + + /* Fujitsu Erratum 010001 affects A64FX 1.0 and 1.1, (v0r0 and v1r0) */ + #define MIDR_FUJITSU_ERRATUM_010001 MIDR_FUJITSU_A64FX +diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c +index b18f307a3c599..342cba2ae9820 100644 +--- a/arch/arm64/kernel/cpu_errata.c ++++ b/arch/arm64/kernel/cpu_errata.c +@@ -1145,6 +1145,10 @@ u8 spectre_bhb_loop_affected(int scope) + MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N1), + {}, + }; ++ static const struct midr_range spectre_bhb_k11_list[] = { ++ MIDR_ALL_VERSIONS(MIDR_AMPERE1), ++ {}, ++ }; + static const struct midr_range spectre_bhb_k8_list[] = { + MIDR_ALL_VERSIONS(MIDR_CORTEX_A72), + MIDR_ALL_VERSIONS(MIDR_CORTEX_A57), +@@ -1155,6 +1159,8 @@ u8 spectre_bhb_loop_affected(int scope) + k = 32; + else if (is_midr_in_range_list(read_cpuid_id(), spectre_bhb_k24_list)) + k = 24; ++ else if (is_midr_in_range_list(read_cpuid_id(), spectre_bhb_k11_list)) ++ k = 11; + else if (is_midr_in_range_list(read_cpuid_id(), spectre_bhb_k8_list)) + k = 8; + +diff --git a/arch/powerpc/include/asm/word-at-a-time.h b/arch/powerpc/include/asm/word-at-a-time.h +index f3f4710d4ff52..99129b0cd8b8a 100644 +--- a/arch/powerpc/include/asm/word-at-a-time.h ++++ b/arch/powerpc/include/asm/word-at-a-time.h +@@ -34,7 +34,7 @@ static inline long find_zero(unsigned long mask) + return leading_zero_bits >> 3; + } + +-static inline bool has_zero(unsigned long val, unsigned long *data, const struct word_at_a_time *c) ++static inline unsigned long has_zero(unsigned long val, unsigned long *data, const struct word_at_a_time *c) + { + unsigned long rhs = val | c->low_bits; + *data = rhs; +diff --git a/arch/powerpc/mm/init_64.c b/arch/powerpc/mm/init_64.c +index e4fb5ab41e2d3..cfb97fabd5320 100644 +--- a/arch/powerpc/mm/init_64.c ++++ b/arch/powerpc/mm/init_64.c +@@ -279,8 +279,7 @@ void __ref vmemmap_free(unsigned long start, unsigned long end, + start = _ALIGN_DOWN(start, page_size); + if (altmap) { + alt_start = altmap->base_pfn; +- alt_end = altmap->base_pfn + altmap->reserve + +- altmap->free + altmap->alloc + altmap->align; ++ alt_end = altmap->base_pfn + altmap->reserve + altmap->free; + } + + pr_debug("vmemmap_free %lx...%lx\n", start, end); +diff --git a/arch/s390/kernel/sthyi.c b/arch/s390/kernel/sthyi.c +index 888cc2f166db7..ce6084e28d904 100644 +--- a/arch/s390/kernel/sthyi.c ++++ b/arch/s390/kernel/sthyi.c +@@ -460,9 +460,9 @@ static int sthyi_update_cache(u64 *rc) + * + * Fills the destination with system information returned by the STHYI + * instruction. The data is generated by emulation or execution of STHYI, +- * if available. The return value is the condition code that would be +- * returned, the rc parameter is the return code which is passed in +- * register R2 + 1. ++ * if available. The return value is either a negative error value or ++ * the condition code that would be returned, the rc parameter is the ++ * return code which is passed in register R2 + 1. + */ + int sthyi_fill(void *dst, u64 *rc) + { +diff --git a/arch/s390/kvm/intercept.c b/arch/s390/kvm/intercept.c +index a389fa85cca2d..5450d43d26ea5 100644 +--- a/arch/s390/kvm/intercept.c ++++ b/arch/s390/kvm/intercept.c +@@ -360,8 +360,8 @@ static int handle_partial_execution(struct kvm_vcpu *vcpu) + */ + int handle_sthyi(struct kvm_vcpu *vcpu) + { +- int reg1, reg2, r = 0; +- u64 code, addr, cc = 0, rc = 0; ++ int reg1, reg2, cc = 0, r = 0; ++ u64 code, addr, rc = 0; + struct sthyi_sctns *sctns = NULL; + + if (!test_kvm_facility(vcpu->kvm, 74)) +@@ -392,7 +392,10 @@ int handle_sthyi(struct kvm_vcpu *vcpu) + return -ENOMEM; + + cc = sthyi_fill(sctns, &rc); +- ++ if (cc < 0) { ++ free_page((unsigned long)sctns); ++ return cc; ++ } + out: + if (!cc) { + r = write_guest(vcpu, addr, reg2, sctns, PAGE_SIZE); +diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c +index 5909e8fa4013f..6937aedc0a03b 100644 +--- a/drivers/acpi/processor_perflib.c ++++ b/drivers/acpi/processor_perflib.c +@@ -56,6 +56,8 @@ static int acpi_processor_get_platform_limit(struct acpi_processor *pr) + { + acpi_status status = 0; + unsigned long long ppc = 0; ++ s32 qos_value; ++ int index; + int ret; + + if (!pr) +@@ -75,17 +77,30 @@ static int acpi_processor_get_platform_limit(struct acpi_processor *pr) + return -ENODEV; + } + ++ index = ppc; ++ ++ if (pr->performance_platform_limit == index || ++ ppc >= pr->performance->state_count) ++ return 0; ++ + pr_debug("CPU %d: _PPC is %d - frequency %s limited\n", pr->id, +- (int)ppc, ppc ? "" : "not"); ++ index, index ? "is" : "is not"); + +- pr->performance_platform_limit = (int)ppc; ++ pr->performance_platform_limit = index; + +- if (ppc >= pr->performance->state_count || +- unlikely(!freq_qos_request_active(&pr->perflib_req))) ++ if (unlikely(!freq_qos_request_active(&pr->perflib_req))) + return 0; + +- ret = freq_qos_update_request(&pr->perflib_req, +- pr->performance->states[ppc].core_frequency * 1000); ++ /* ++ * If _PPC returns 0, it means that all of the available states can be ++ * used ("no limit"). ++ */ ++ if (index == 0) ++ qos_value = FREQ_QOS_MAX_DEFAULT_VALUE; ++ else ++ qos_value = pr->performance->states[index].core_frequency * 1000; ++ ++ ret = freq_qos_update_request(&pr->perflib_req, qos_value); + if (ret < 0) { + pr_warn("Failed to update perflib freq constraint: CPU%d (%d)\n", + pr->id, ret); +@@ -168,9 +183,16 @@ void acpi_processor_ppc_init(struct cpufreq_policy *policy) + if (!pr) + continue; + ++ /* ++ * Reset performance_platform_limit in case there is a stale ++ * value in it, so as to make it match the "no limit" QoS value ++ * below. ++ */ ++ pr->performance_platform_limit = 0; ++ + ret = freq_qos_add_request(&policy->constraints, +- &pr->perflib_req, +- FREQ_QOS_MAX, INT_MAX); ++ &pr->perflib_req, FREQ_QOS_MAX, ++ FREQ_QOS_MAX_DEFAULT_VALUE); + if (ret < 0) + pr_err("Failed to add freq constraint for CPU%d (%d)\n", + cpu, ret); +diff --git a/drivers/ata/pata_ns87415.c b/drivers/ata/pata_ns87415.c +index 4b2ba813dcaba..491853b9f0856 100644 +--- a/drivers/ata/pata_ns87415.c ++++ b/drivers/ata/pata_ns87415.c +@@ -261,7 +261,7 @@ static u8 ns87560_check_status(struct ata_port *ap) + * LOCKING: + * Inherited from caller. + */ +-void ns87560_tf_read(struct ata_port *ap, struct ata_taskfile *tf) ++static void ns87560_tf_read(struct ata_port *ap, struct ata_taskfile *tf) + { + struct ata_ioports *ioaddr = &ap->ioaddr; + +diff --git a/drivers/base/core.c b/drivers/base/core.c +index f8e157ede44f8..6fb31f4894526 100644 +--- a/drivers/base/core.c ++++ b/drivers/base/core.c +@@ -3399,6 +3399,50 @@ define_dev_printk_level(_dev_info, KERN_INFO); + + #endif + ++/** ++ * dev_err_probe - probe error check and log helper ++ * @dev: the pointer to the struct device ++ * @err: error value to test ++ * @fmt: printf-style format string ++ * @...: arguments as specified in the format string ++ * ++ * This helper implements common pattern present in probe functions for error ++ * checking: print debug or error message depending if the error value is ++ * -EPROBE_DEFER and propagate error upwards. ++ * It replaces code sequence:: ++ * if (err != -EPROBE_DEFER) ++ * dev_err(dev, ...); ++ * else ++ * dev_dbg(dev, ...); ++ * return err; ++ * ++ * with:: ++ * ++ * return dev_err_probe(dev, err, ...); ++ * ++ * Returns @err. ++ * ++ */ ++int dev_err_probe(const struct device *dev, int err, const char *fmt, ...) ++{ ++ struct va_format vaf; ++ va_list args; ++ ++ va_start(args, fmt); ++ vaf.fmt = fmt; ++ vaf.va = &args; ++ ++ if (err != -EPROBE_DEFER) ++ dev_err(dev, "error %pe: %pV", ERR_PTR(err), &vaf); ++ else ++ dev_dbg(dev, "error %pe: %pV", ERR_PTR(err), &vaf); ++ ++ va_end(args); ++ ++ return err; ++} ++EXPORT_SYMBOL_GPL(dev_err_probe); ++ + static inline bool fwnode_is_primary(struct fwnode_handle *fwnode) + { + return fwnode && !IS_ERR(fwnode->secondary); +diff --git a/drivers/base/power/power.h b/drivers/base/power/power.h +index 39a06a0cfdaa8..310abe7251fc3 100644 +--- a/drivers/base/power/power.h ++++ b/drivers/base/power/power.h +@@ -25,8 +25,11 @@ extern u64 pm_runtime_active_time(struct device *dev); + + #define WAKE_IRQ_DEDICATED_ALLOCATED BIT(0) + #define WAKE_IRQ_DEDICATED_MANAGED BIT(1) ++#define WAKE_IRQ_DEDICATED_REVERSE BIT(2) + #define WAKE_IRQ_DEDICATED_MASK (WAKE_IRQ_DEDICATED_ALLOCATED | \ +- WAKE_IRQ_DEDICATED_MANAGED) ++ WAKE_IRQ_DEDICATED_MANAGED | \ ++ WAKE_IRQ_DEDICATED_REVERSE) ++#define WAKE_IRQ_DEDICATED_ENABLED BIT(3) + + struct wake_irq { + struct device *dev; +@@ -39,7 +42,8 @@ extern void dev_pm_arm_wake_irq(struct wake_irq *wirq); + extern void dev_pm_disarm_wake_irq(struct wake_irq *wirq); + extern void dev_pm_enable_wake_irq_check(struct device *dev, + bool can_change_status); +-extern void dev_pm_disable_wake_irq_check(struct device *dev); ++extern void dev_pm_disable_wake_irq_check(struct device *dev, bool cond_disable); ++extern void dev_pm_enable_wake_irq_complete(struct device *dev); + + #ifdef CONFIG_PM_SLEEP + +diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c +index 9ee58bf49d133..d5c2d86fbecd4 100644 +--- a/drivers/base/power/runtime.c ++++ b/drivers/base/power/runtime.c +@@ -659,6 +659,8 @@ static int rpm_suspend(struct device *dev, int rpmflags) + if (retval) + goto fail; + ++ dev_pm_enable_wake_irq_complete(dev); ++ + no_callback: + __update_runtime_status(dev, RPM_SUSPENDED); + pm_runtime_deactivate_timer(dev); +@@ -704,7 +706,7 @@ static int rpm_suspend(struct device *dev, int rpmflags) + return retval; + + fail: +- dev_pm_disable_wake_irq_check(dev); ++ dev_pm_disable_wake_irq_check(dev, true); + __update_runtime_status(dev, RPM_ACTIVE); + dev->power.deferred_resume = false; + wake_up_all(&dev->power.wait_queue); +@@ -887,7 +889,7 @@ static int rpm_resume(struct device *dev, int rpmflags) + + callback = RPM_GET_CALLBACK(dev, runtime_resume); + +- dev_pm_disable_wake_irq_check(dev); ++ dev_pm_disable_wake_irq_check(dev, false); + retval = rpm_callback(callback, dev); + if (retval) { + __update_runtime_status(dev, RPM_SUSPENDED); +diff --git a/drivers/base/power/wakeirq.c b/drivers/base/power/wakeirq.c +index 5ce77d1ef9fc3..46654adf00a10 100644 +--- a/drivers/base/power/wakeirq.c ++++ b/drivers/base/power/wakeirq.c +@@ -145,24 +145,7 @@ static irqreturn_t handle_threaded_wake_irq(int irq, void *_wirq) + return IRQ_HANDLED; + } + +-/** +- * dev_pm_set_dedicated_wake_irq - Request a dedicated wake-up interrupt +- * @dev: Device entry +- * @irq: Device wake-up interrupt +- * +- * Unless your hardware has separate wake-up interrupts in addition +- * to the device IO interrupts, you don't need this. +- * +- * Sets up a threaded interrupt handler for a device that has +- * a dedicated wake-up interrupt in addition to the device IO +- * interrupt. +- * +- * The interrupt starts disabled, and needs to be managed for +- * the device by the bus code or the device driver using +- * dev_pm_enable_wake_irq() and dev_pm_disable_wake_irq() +- * functions. +- */ +-int dev_pm_set_dedicated_wake_irq(struct device *dev, int irq) ++static int __dev_pm_set_dedicated_wake_irq(struct device *dev, int irq, unsigned int flag) + { + struct wake_irq *wirq; + int err; +@@ -200,7 +183,7 @@ int dev_pm_set_dedicated_wake_irq(struct device *dev, int irq) + if (err) + goto err_free_irq; + +- wirq->status = WAKE_IRQ_DEDICATED_ALLOCATED; ++ wirq->status = WAKE_IRQ_DEDICATED_ALLOCATED | flag; + + return err; + +@@ -213,8 +196,57 @@ err_free: + + return err; + } ++ ++ ++/** ++ * dev_pm_set_dedicated_wake_irq - Request a dedicated wake-up interrupt ++ * @dev: Device entry ++ * @irq: Device wake-up interrupt ++ * ++ * Unless your hardware has separate wake-up interrupts in addition ++ * to the device IO interrupts, you don't need this. ++ * ++ * Sets up a threaded interrupt handler for a device that has ++ * a dedicated wake-up interrupt in addition to the device IO ++ * interrupt. ++ * ++ * The interrupt starts disabled, and needs to be managed for ++ * the device by the bus code or the device driver using ++ * dev_pm_enable_wake_irq*() and dev_pm_disable_wake_irq*() ++ * functions. ++ */ ++int dev_pm_set_dedicated_wake_irq(struct device *dev, int irq) ++{ ++ return __dev_pm_set_dedicated_wake_irq(dev, irq, 0); ++} + EXPORT_SYMBOL_GPL(dev_pm_set_dedicated_wake_irq); + ++/** ++ * dev_pm_set_dedicated_wake_irq_reverse - Request a dedicated wake-up interrupt ++ * with reverse enable ordering ++ * @dev: Device entry ++ * @irq: Device wake-up interrupt ++ * ++ * Unless your hardware has separate wake-up interrupts in addition ++ * to the device IO interrupts, you don't need this. ++ * ++ * Sets up a threaded interrupt handler for a device that has a dedicated ++ * wake-up interrupt in addition to the device IO interrupt. It sets ++ * the status of WAKE_IRQ_DEDICATED_REVERSE to tell rpm_suspend() ++ * to enable dedicated wake-up interrupt after running the runtime suspend ++ * callback for @dev. ++ * ++ * The interrupt starts disabled, and needs to be managed for ++ * the device by the bus code or the device driver using ++ * dev_pm_enable_wake_irq*() and dev_pm_disable_wake_irq*() ++ * functions. ++ */ ++int dev_pm_set_dedicated_wake_irq_reverse(struct device *dev, int irq) ++{ ++ return __dev_pm_set_dedicated_wake_irq(dev, irq, WAKE_IRQ_DEDICATED_REVERSE); ++} ++EXPORT_SYMBOL_GPL(dev_pm_set_dedicated_wake_irq_reverse); ++ + /** + * dev_pm_enable_wake_irq - Enable device wake-up interrupt + * @dev: Device +@@ -285,25 +317,56 @@ void dev_pm_enable_wake_irq_check(struct device *dev, + return; + + enable: +- enable_irq(wirq->irq); ++ if (!can_change_status || !(wirq->status & WAKE_IRQ_DEDICATED_REVERSE)) { ++ enable_irq(wirq->irq); ++ wirq->status |= WAKE_IRQ_DEDICATED_ENABLED; ++ } + } + + /** + * dev_pm_disable_wake_irq_check - Checks and disables wake-up interrupt + * @dev: Device ++ * @cond_disable: if set, also check WAKE_IRQ_DEDICATED_REVERSE + * + * Disables wake-up interrupt conditionally based on status. + * Should be only called from rpm_suspend() and rpm_resume() path. + */ +-void dev_pm_disable_wake_irq_check(struct device *dev) ++void dev_pm_disable_wake_irq_check(struct device *dev, bool cond_disable) + { + struct wake_irq *wirq = dev->power.wakeirq; + + if (!wirq || !((wirq->status & WAKE_IRQ_DEDICATED_MASK))) + return; + +- if (wirq->status & WAKE_IRQ_DEDICATED_MANAGED) ++ if (cond_disable && (wirq->status & WAKE_IRQ_DEDICATED_REVERSE)) ++ return; ++ ++ if (wirq->status & WAKE_IRQ_DEDICATED_MANAGED) { ++ wirq->status &= ~WAKE_IRQ_DEDICATED_ENABLED; + disable_irq_nosync(wirq->irq); ++ } ++} ++ ++/** ++ * dev_pm_enable_wake_irq_complete - enable wake IRQ not enabled before ++ * @dev: Device using the wake IRQ ++ * ++ * Enable wake IRQ conditionally based on status, mainly used if want to ++ * enable wake IRQ after running ->runtime_suspend() which depends on ++ * WAKE_IRQ_DEDICATED_REVERSE. ++ * ++ * Should be only called from rpm_suspend() path. ++ */ ++void dev_pm_enable_wake_irq_complete(struct device *dev) ++{ ++ struct wake_irq *wirq = dev->power.wakeirq; ++ ++ if (!wirq || !(wirq->status & WAKE_IRQ_DEDICATED_MASK)) ++ return; ++ ++ if (wirq->status & WAKE_IRQ_DEDICATED_MANAGED && ++ wirq->status & WAKE_IRQ_DEDICATED_REVERSE) ++ enable_irq(wirq->irq); + } + + /** +@@ -320,7 +383,7 @@ void dev_pm_arm_wake_irq(struct wake_irq *wirq) + + if (device_may_wakeup(wirq->dev)) { + if (wirq->status & WAKE_IRQ_DEDICATED_ALLOCATED && +- !pm_runtime_status_suspended(wirq->dev)) ++ !(wirq->status & WAKE_IRQ_DEDICATED_ENABLED)) + enable_irq(wirq->irq); + + enable_irq_wake(wirq->irq); +@@ -343,7 +406,7 @@ void dev_pm_disarm_wake_irq(struct wake_irq *wirq) + disable_irq_wake(wirq->irq); + + if (wirq->status & WAKE_IRQ_DEDICATED_ALLOCATED && +- !pm_runtime_status_suspended(wirq->dev)) ++ !(wirq->status & WAKE_IRQ_DEDICATED_ENABLED)) + disable_irq_nosync(wirq->irq); + } + } +diff --git a/drivers/block/loop.c b/drivers/block/loop.c +index b8f57b1c2864b..d8821c9cb1700 100644 +--- a/drivers/block/loop.c ++++ b/drivers/block/loop.c +@@ -2037,7 +2037,7 @@ static int loop_add(struct loop_device **l, int i) + lo->tag_set.queue_depth = 128; + lo->tag_set.numa_node = NUMA_NO_NODE; + lo->tag_set.cmd_size = sizeof(struct loop_cmd); +- lo->tag_set.flags = BLK_MQ_F_SHOULD_MERGE; ++ lo->tag_set.flags = BLK_MQ_F_SHOULD_MERGE | BLK_MQ_F_NO_SCHED; + lo->tag_set.driver_data = lo; + + err = blk_mq_alloc_tag_set(&lo->tag_set); +diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c +index cb0660304e480..ef47d1d58ac3a 100644 +--- a/drivers/char/tpm/tpm_tis_core.c ++++ b/drivers/char/tpm/tpm_tis_core.c +@@ -266,6 +266,7 @@ static int tpm_tis_recv(struct tpm_chip *chip, u8 *buf, size_t count) + int size = 0; + int status; + u32 expected; ++ int rc; + + if (count < TPM_HEADER_SIZE) { + size = -EIO; +@@ -285,8 +286,13 @@ static int tpm_tis_recv(struct tpm_chip *chip, u8 *buf, size_t count) + goto out; + } + +- size += recv_data(chip, &buf[TPM_HEADER_SIZE], +- expected - TPM_HEADER_SIZE); ++ rc = recv_data(chip, &buf[TPM_HEADER_SIZE], ++ expected - TPM_HEADER_SIZE); ++ if (rc < 0) { ++ size = rc; ++ goto out; ++ } ++ size += rc; + if (size < expected) { + dev_err(&chip->dev, "Unable to read remainder of result\n"); + size = -ETIME; +diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c +index 88fe803a044d5..06302eaa3e942 100644 +--- a/drivers/cpufreq/intel_pstate.c ++++ b/drivers/cpufreq/intel_pstate.c +@@ -442,20 +442,6 @@ static void intel_pstate_init_acpi_perf_limits(struct cpufreq_policy *policy) + (u32) cpu->acpi_perf_data.states[i].control); + } + +- /* +- * The _PSS table doesn't contain whole turbo frequency range. +- * This just contains +1 MHZ above the max non turbo frequency, +- * with control value corresponding to max turbo ratio. But +- * when cpufreq set policy is called, it will call with this +- * max frequency, which will cause a reduced performance as +- * this driver uses real max turbo frequency as the max +- * frequency. So correct this frequency in _PSS table to +- * correct max turbo frequency based on the turbo state. +- * Also need to convert to MHz as _PSS freq is in MHz. +- */ +- if (!global.turbo_disabled) +- cpu->acpi_perf_data.states[0].core_frequency = +- policy->cpuinfo.max_freq / 1000; + cpu->valid_pss_table = true; + pr_debug("_PPC limits will be enforced\n"); + +diff --git a/drivers/gpio/gpio-tps68470.c b/drivers/gpio/gpio-tps68470.c +index aff6e504c6668..9704cff9b4aa3 100644 +--- a/drivers/gpio/gpio-tps68470.c ++++ b/drivers/gpio/gpio-tps68470.c +@@ -91,13 +91,13 @@ static int tps68470_gpio_output(struct gpio_chip *gc, unsigned int offset, + struct tps68470_gpio_data *tps68470_gpio = gpiochip_get_data(gc); + struct regmap *regmap = tps68470_gpio->tps68470_regmap; + ++ /* Set the initial value */ ++ tps68470_gpio_set(gc, offset, value); ++ + /* rest are always outputs */ + if (offset >= TPS68470_N_REGULAR_GPIO) + return 0; + +- /* Set the initial value */ +- tps68470_gpio_set(gc, offset, value); +- + return regmap_update_bits(regmap, TPS68470_GPIO_CTL_REG_A(offset), + TPS68470_GPIO_MODE_MASK, + TPS68470_GPIO_MODE_OUT_CMOS); +diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c +index 593b8d83179c9..65c2c5361e5fc 100644 +--- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c ++++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c +@@ -71,7 +71,7 @@ static void a5xx_submit_in_rb(struct msm_gpu *gpu, struct msm_gem_submit *submit + * since we've already mapped it once in + * submit_reloc() + */ +- if (WARN_ON(!ptr)) ++ if (WARN_ON(IS_ERR_OR_NULL(ptr))) + return; + + for (i = 0; i < dwords; i++) { +diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.h b/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.h +index 68cccfa2870a3..9c8eb1ae4acfc 100644 +--- a/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.h ++++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.h +@@ -200,7 +200,7 @@ static const struct a6xx_shader_block { + SHADER(A6XX_SP_LB_3_DATA, 0x800), + SHADER(A6XX_SP_LB_4_DATA, 0x800), + SHADER(A6XX_SP_LB_5_DATA, 0x200), +- SHADER(A6XX_SP_CB_BINDLESS_DATA, 0x2000), ++ SHADER(A6XX_SP_CB_BINDLESS_DATA, 0x800), + SHADER(A6XX_SP_CB_LEGACY_DATA, 0x280), + SHADER(A6XX_SP_UAV_DATA, 0x80), + SHADER(A6XX_SP_INST_TAG, 0x80), +diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.h +index cf4b9b5964c6c..cd6c3518ba021 100644 +--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.h ++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.h +@@ -14,19 +14,6 @@ + + #define DPU_PERF_DEFAULT_MAX_CORE_CLK_RATE 412500000 + +-/** +- * enum dpu_core_perf_data_bus_id - data bus identifier +- * @DPU_CORE_PERF_DATA_BUS_ID_MNOC: DPU/MNOC data bus +- * @DPU_CORE_PERF_DATA_BUS_ID_LLCC: MNOC/LLCC data bus +- * @DPU_CORE_PERF_DATA_BUS_ID_EBI: LLCC/EBI data bus +- */ +-enum dpu_core_perf_data_bus_id { +- DPU_CORE_PERF_DATA_BUS_ID_MNOC, +- DPU_CORE_PERF_DATA_BUS_ID_LLCC, +- DPU_CORE_PERF_DATA_BUS_ID_EBI, +- DPU_CORE_PERF_DATA_BUS_ID_MAX, +-}; +- + /** + * struct dpu_core_perf_params - definition of performance parameters + * @max_per_pipe_ib: maximum instantaneous bandwidth request +diff --git a/drivers/hwmon/nct7802.c b/drivers/hwmon/nct7802.c +index 2e97e56c72c74..5cdc60717006b 100644 +--- a/drivers/hwmon/nct7802.c ++++ b/drivers/hwmon/nct7802.c +@@ -708,7 +708,7 @@ static umode_t nct7802_temp_is_visible(struct kobject *kobj, + if (index >= 38 && index < 46 && !(reg & 0x01)) /* PECI 0 */ + return 0; + +- if (index >= 0x46 && (!(reg & 0x02))) /* PECI 1 */ ++ if (index >= 46 && !(reg & 0x02)) /* PECI 1 */ + return 0; + + return attr->mode; +diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c +index 02caf9a439cf1..395d8a99b12e4 100644 +--- a/drivers/infiniband/hw/mlx4/qp.c ++++ b/drivers/infiniband/hw/mlx4/qp.c +@@ -556,15 +556,15 @@ static int set_qp_rss(struct mlx4_ib_dev *dev, struct mlx4_ib_rss *rss_ctx, + return (-EOPNOTSUPP); + } + +- if (ucmd->rx_hash_fields_mask & ~(MLX4_IB_RX_HASH_SRC_IPV4 | +- MLX4_IB_RX_HASH_DST_IPV4 | +- MLX4_IB_RX_HASH_SRC_IPV6 | +- MLX4_IB_RX_HASH_DST_IPV6 | +- MLX4_IB_RX_HASH_SRC_PORT_TCP | +- MLX4_IB_RX_HASH_DST_PORT_TCP | +- MLX4_IB_RX_HASH_SRC_PORT_UDP | +- MLX4_IB_RX_HASH_DST_PORT_UDP | +- MLX4_IB_RX_HASH_INNER)) { ++ if (ucmd->rx_hash_fields_mask & ~(u64)(MLX4_IB_RX_HASH_SRC_IPV4 | ++ MLX4_IB_RX_HASH_DST_IPV4 | ++ MLX4_IB_RX_HASH_SRC_IPV6 | ++ MLX4_IB_RX_HASH_DST_IPV6 | ++ MLX4_IB_RX_HASH_SRC_PORT_TCP | ++ MLX4_IB_RX_HASH_DST_PORT_TCP | ++ MLX4_IB_RX_HASH_SRC_PORT_UDP | ++ MLX4_IB_RX_HASH_DST_PORT_UDP | ++ MLX4_IB_RX_HASH_INNER)) { + pr_debug("RX Hash fields_mask has unsupported mask (0x%llx)\n", + ucmd->rx_hash_fields_mask); + return (-EOPNOTSUPP); +diff --git a/drivers/irqchip/irq-bcm6345-l1.c b/drivers/irqchip/irq-bcm6345-l1.c +index 1bd0621c4ce2a..4827a11832478 100644 +--- a/drivers/irqchip/irq-bcm6345-l1.c ++++ b/drivers/irqchip/irq-bcm6345-l1.c +@@ -82,6 +82,7 @@ struct bcm6345_l1_chip { + }; + + struct bcm6345_l1_cpu { ++ struct bcm6345_l1_chip *intc; + void __iomem *map_base; + unsigned int parent_irq; + u32 enable_cache[]; +@@ -115,17 +116,11 @@ static inline unsigned int cpu_for_irq(struct bcm6345_l1_chip *intc, + + static void bcm6345_l1_irq_handle(struct irq_desc *desc) + { +- struct bcm6345_l1_chip *intc = irq_desc_get_handler_data(desc); +- struct bcm6345_l1_cpu *cpu; ++ struct bcm6345_l1_cpu *cpu = irq_desc_get_handler_data(desc); ++ struct bcm6345_l1_chip *intc = cpu->intc; + struct irq_chip *chip = irq_desc_get_chip(desc); + unsigned int idx; + +-#ifdef CONFIG_SMP +- cpu = intc->cpus[cpu_logical_map(smp_processor_id())]; +-#else +- cpu = intc->cpus[0]; +-#endif +- + chained_irq_enter(chip, desc); + + for (idx = 0; idx < intc->n_words; idx++) { +@@ -257,6 +252,7 @@ static int __init bcm6345_l1_init_one(struct device_node *dn, + if (!cpu) + return -ENOMEM; + ++ cpu->intc = intc; + cpu->map_base = ioremap(res.start, sz); + if (!cpu->map_base) + return -ENOMEM; +@@ -272,7 +268,7 @@ static int __init bcm6345_l1_init_one(struct device_node *dn, + return -EINVAL; + } + irq_set_chained_handler_and_data(cpu->parent_irq, +- bcm6345_l1_irq_handle, intc); ++ bcm6345_l1_irq_handle, cpu); + + return 0; + } +diff --git a/drivers/isdn/hardware/mISDN/hfcpci.c b/drivers/isdn/hardware/mISDN/hfcpci.c +index 41ff2e3dc8430..0a683a66fc612 100644 +--- a/drivers/isdn/hardware/mISDN/hfcpci.c ++++ b/drivers/isdn/hardware/mISDN/hfcpci.c +@@ -839,7 +839,7 @@ hfcpci_fill_fifo(struct bchannel *bch) + *z1t = cpu_to_le16(new_z1); /* now send data */ + if (bch->tx_idx < bch->tx_skb->len) + return; +- dev_kfree_skb(bch->tx_skb); ++ dev_kfree_skb_any(bch->tx_skb); + if (get_next_bframe(bch)) + goto next_t_frame; + return; +@@ -895,7 +895,7 @@ hfcpci_fill_fifo(struct bchannel *bch) + } + bz->za[new_f1].z1 = cpu_to_le16(new_z1); /* for next buffer */ + bz->f1 = new_f1; /* next frame */ +- dev_kfree_skb(bch->tx_skb); ++ dev_kfree_skb_any(bch->tx_skb); + get_next_bframe(bch); + } + +@@ -1119,7 +1119,7 @@ tx_birq(struct bchannel *bch) + if (bch->tx_skb && bch->tx_idx < bch->tx_skb->len) + hfcpci_fill_fifo(bch); + else { +- dev_kfree_skb(bch->tx_skb); ++ dev_kfree_skb_any(bch->tx_skb); + if (get_next_bframe(bch)) + hfcpci_fill_fifo(bch); + } +@@ -2272,7 +2272,7 @@ _hfcpci_softirq(struct device *dev, void *unused) + return 0; + + if (hc->hw.int_m2 & HFCPCI_IRQ_ENABLE) { +- spin_lock(&hc->lock); ++ spin_lock_irq(&hc->lock); + bch = Sel_BCS(hc, hc->hw.bswapped ? 2 : 1); + if (bch && bch->state == ISDN_P_B_RAW) { /* B1 rx&tx */ + main_rec_hfcpci(bch); +@@ -2283,7 +2283,7 @@ _hfcpci_softirq(struct device *dev, void *unused) + main_rec_hfcpci(bch); + tx_birq(bch); + } +- spin_unlock(&hc->lock); ++ spin_unlock_irq(&hc->lock); + } + return 0; + } +diff --git a/drivers/md/bcache/alloc.c b/drivers/md/bcache/alloc.c +index a1df0d95151c6..5310e1f4a2826 100644 +--- a/drivers/md/bcache/alloc.c ++++ b/drivers/md/bcache/alloc.c +@@ -49,7 +49,7 @@ + * + * bch_bucket_alloc() allocates a single bucket from a specific cache. + * +- * bch_bucket_alloc_set() allocates one or more buckets from different caches ++ * bch_bucket_alloc_set() allocates one bucket from different caches + * out of a cache set. + * + * free_some_buckets() drives all the processes described above. It's called +@@ -488,34 +488,29 @@ void bch_bucket_free(struct cache_set *c, struct bkey *k) + } + + int __bch_bucket_alloc_set(struct cache_set *c, unsigned int reserve, +- struct bkey *k, int n, bool wait) ++ struct bkey *k, bool wait) + { +- int i; ++ struct cache *ca; ++ long b; + + /* No allocation if CACHE_SET_IO_DISABLE bit is set */ + if (unlikely(test_bit(CACHE_SET_IO_DISABLE, &c->flags))) + return -1; + + lockdep_assert_held(&c->bucket_lock); +- BUG_ON(!n || n > c->caches_loaded || n > MAX_CACHES_PER_SET); + + bkey_init(k); + +- /* sort by free space/prio of oldest data in caches */ +- +- for (i = 0; i < n; i++) { +- struct cache *ca = c->cache_by_alloc[i]; +- long b = bch_bucket_alloc(ca, reserve, wait); ++ ca = c->cache_by_alloc[0]; ++ b = bch_bucket_alloc(ca, reserve, wait); ++ if (b == -1) ++ goto err; + +- if (b == -1) +- goto err; ++ k->ptr[0] = MAKE_PTR(ca->buckets[b].gen, ++ bucket_to_sector(c, b), ++ ca->sb.nr_this_dev); + +- k->ptr[i] = MAKE_PTR(ca->buckets[b].gen, +- bucket_to_sector(c, b), +- ca->sb.nr_this_dev); +- +- SET_KEY_PTRS(k, i + 1); +- } ++ SET_KEY_PTRS(k, 1); + + return 0; + err: +@@ -525,12 +520,12 @@ err: + } + + int bch_bucket_alloc_set(struct cache_set *c, unsigned int reserve, +- struct bkey *k, int n, bool wait) ++ struct bkey *k, bool wait) + { + int ret; + + mutex_lock(&c->bucket_lock); +- ret = __bch_bucket_alloc_set(c, reserve, k, n, wait); ++ ret = __bch_bucket_alloc_set(c, reserve, k, wait); + mutex_unlock(&c->bucket_lock); + return ret; + } +@@ -638,7 +633,7 @@ bool bch_alloc_sectors(struct cache_set *c, + + spin_unlock(&c->data_bucket_lock); + +- if (bch_bucket_alloc_set(c, watermark, &alloc.key, 1, wait)) ++ if (bch_bucket_alloc_set(c, watermark, &alloc.key, wait)) + return false; + + spin_lock(&c->data_bucket_lock); +diff --git a/drivers/md/bcache/bcache.h b/drivers/md/bcache/bcache.h +index 36de6f7ddf221..1dd9298cb0e02 100644 +--- a/drivers/md/bcache/bcache.h ++++ b/drivers/md/bcache/bcache.h +@@ -970,9 +970,9 @@ void bch_bucket_free(struct cache_set *c, struct bkey *k); + + long bch_bucket_alloc(struct cache *ca, unsigned int reserve, bool wait); + int __bch_bucket_alloc_set(struct cache_set *c, unsigned int reserve, +- struct bkey *k, int n, bool wait); ++ struct bkey *k, bool wait); + int bch_bucket_alloc_set(struct cache_set *c, unsigned int reserve, +- struct bkey *k, int n, bool wait); ++ struct bkey *k, bool wait); + bool bch_alloc_sectors(struct cache_set *c, struct bkey *k, + unsigned int sectors, unsigned int write_point, + unsigned int write_prio, bool wait); +diff --git a/drivers/md/bcache/btree.c b/drivers/md/bcache/btree.c +index b7fea84d19ad9..cc0c1f2bba45c 100644 +--- a/drivers/md/bcache/btree.c ++++ b/drivers/md/bcache/btree.c +@@ -1137,11 +1137,13 @@ struct btree *__bch_btree_node_alloc(struct cache_set *c, struct btree_op *op, + struct btree *parent) + { + BKEY_PADDED(key) k; +- struct btree *b = ERR_PTR(-EAGAIN); ++ struct btree *b; + + mutex_lock(&c->bucket_lock); + retry: +- if (__bch_bucket_alloc_set(c, RESERVE_BTREE, &k.key, 1, wait)) ++ /* return ERR_PTR(-EAGAIN) when it fails */ ++ b = ERR_PTR(-EAGAIN); ++ if (__bch_bucket_alloc_set(c, RESERVE_BTREE, &k.key, wait)) + goto err; + + bkey_put(c, &k.key); +diff --git a/drivers/md/bcache/super.c b/drivers/md/bcache/super.c +index 70e46e0d2f1ac..6afaa5e852837 100644 +--- a/drivers/md/bcache/super.c ++++ b/drivers/md/bcache/super.c +@@ -428,7 +428,7 @@ static int __uuid_write(struct cache_set *c) + closure_init_stack(&cl); + lockdep_assert_held(&bch_register_lock); + +- if (bch_bucket_alloc_set(c, RESERVE_BTREE, &k.key, 1, true)) ++ if (bch_bucket_alloc_set(c, RESERVE_BTREE, &k.key, true)) + return 1; + + SET_KEY_SIZE(&k.key, c->sb.bucket_size); +diff --git a/drivers/md/dm-cache-policy-smq.c b/drivers/md/dm-cache-policy-smq.c +index b61aac00ff409..859073193f5b4 100644 +--- a/drivers/md/dm-cache-policy-smq.c ++++ b/drivers/md/dm-cache-policy-smq.c +@@ -854,7 +854,13 @@ struct smq_policy { + + struct background_tracker *bg_work; + +- bool migrations_allowed; ++ bool migrations_allowed:1; ++ ++ /* ++ * If this is set the policy will try and clean the whole cache ++ * even if the device is not idle. ++ */ ++ bool cleaner:1; + }; + + /*----------------------------------------------------------------*/ +@@ -1133,7 +1139,7 @@ static bool clean_target_met(struct smq_policy *mq, bool idle) + * Cache entries may not be populated. So we cannot rely on the + * size of the clean queue. + */ +- if (idle) { ++ if (idle || mq->cleaner) { + /* + * We'd like to clean everything. + */ +@@ -1716,11 +1722,9 @@ static void calc_hotspot_params(sector_t origin_size, + *hotspot_block_size /= 2u; + } + +-static struct dm_cache_policy *__smq_create(dm_cblock_t cache_size, +- sector_t origin_size, +- sector_t cache_block_size, +- bool mimic_mq, +- bool migrations_allowed) ++static struct dm_cache_policy * ++__smq_create(dm_cblock_t cache_size, sector_t origin_size, sector_t cache_block_size, ++ bool mimic_mq, bool migrations_allowed, bool cleaner) + { + unsigned i; + unsigned nr_sentinels_per_queue = 2u * NR_CACHE_LEVELS; +@@ -1807,6 +1811,7 @@ static struct dm_cache_policy *__smq_create(dm_cblock_t cache_size, + goto bad_btracker; + + mq->migrations_allowed = migrations_allowed; ++ mq->cleaner = cleaner; + + return &mq->policy; + +@@ -1830,21 +1835,24 @@ static struct dm_cache_policy *smq_create(dm_cblock_t cache_size, + sector_t origin_size, + sector_t cache_block_size) + { +- return __smq_create(cache_size, origin_size, cache_block_size, false, true); ++ return __smq_create(cache_size, origin_size, cache_block_size, ++ false, true, false); + } + + static struct dm_cache_policy *mq_create(dm_cblock_t cache_size, + sector_t origin_size, + sector_t cache_block_size) + { +- return __smq_create(cache_size, origin_size, cache_block_size, true, true); ++ return __smq_create(cache_size, origin_size, cache_block_size, ++ true, true, false); + } + + static struct dm_cache_policy *cleaner_create(dm_cblock_t cache_size, + sector_t origin_size, + sector_t cache_block_size) + { +- return __smq_create(cache_size, origin_size, cache_block_size, false, false); ++ return __smq_create(cache_size, origin_size, cache_block_size, ++ false, false, true); + } + + /*----------------------------------------------------------------*/ +diff --git a/drivers/md/dm-raid.c b/drivers/md/dm-raid.c +index 882e83d51ef43..9f05ae2b90191 100644 +--- a/drivers/md/dm-raid.c ++++ b/drivers/md/dm-raid.c +@@ -3284,15 +3284,19 @@ static int raid_ctr(struct dm_target *ti, unsigned int argc, char **argv) + /* Try to adjust the raid4/5/6 stripe cache size to the stripe size */ + if (rs_is_raid456(rs)) { + r = rs_set_raid456_stripe_cache(rs); +- if (r) ++ if (r) { ++ mddev_unlock(&rs->md); + goto bad_stripe_cache; ++ } + } + + /* Now do an early reshape check */ + if (test_bit(RT_FLAG_RESHAPE_RS, &rs->runtime_flags)) { + r = rs_check_reshape(rs); +- if (r) ++ if (r) { ++ mddev_unlock(&rs->md); + goto bad_check_reshape; ++ } + + /* Restore new, ctr requested layout to perform check */ + rs_config_restore(rs, &rs_layout); +@@ -3301,6 +3305,7 @@ static int raid_ctr(struct dm_target *ti, unsigned int argc, char **argv) + r = rs->md.pers->check_reshape(&rs->md); + if (r) { + ti->error = "Reshape check failed"; ++ mddev_unlock(&rs->md); + goto bad_check_reshape; + } + } +diff --git a/drivers/mtd/nand/raw/meson_nand.c b/drivers/mtd/nand/raw/meson_nand.c +index 8339c020c1a13..29f3d39138e84 100644 +--- a/drivers/mtd/nand/raw/meson_nand.c ++++ b/drivers/mtd/nand/raw/meson_nand.c +@@ -1177,7 +1177,6 @@ static int meson_nand_attach_chip(struct nand_chip *nand) + struct meson_nfc *nfc = nand_get_controller_data(nand); + struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand); + struct mtd_info *mtd = nand_to_mtd(nand); +- int nsectors = mtd->writesize / 1024; + int ret; + + if (!mtd->name) { +@@ -1195,7 +1194,7 @@ static int meson_nand_attach_chip(struct nand_chip *nand) + nand->options |= NAND_NO_SUBPAGE_WRITE; + + ret = nand_ecc_choose_conf(nand, nfc->data->ecc_caps, +- mtd->oobsize - 2 * nsectors); ++ mtd->oobsize - 2); + if (ret) { + dev_err(nfc->dev, "failed to ECC init\n"); + return -EINVAL; +diff --git a/drivers/mtd/nand/raw/omap_elm.c b/drivers/mtd/nand/raw/omap_elm.c +index 6e0e31eab7cce..c4064f8fd6118 100644 +--- a/drivers/mtd/nand/raw/omap_elm.c ++++ b/drivers/mtd/nand/raw/omap_elm.c +@@ -174,17 +174,17 @@ static void elm_load_syndrome(struct elm_info *info, + switch (info->bch_type) { + case BCH8_ECC: + /* syndrome fragment 0 = ecc[9-12B] */ +- val = cpu_to_be32(*(u32 *) &ecc[9]); ++ val = (__force u32)cpu_to_be32(*(u32 *)&ecc[9]); + elm_write_reg(info, offset, val); + + /* syndrome fragment 1 = ecc[5-8B] */ + offset += 4; +- val = cpu_to_be32(*(u32 *) &ecc[5]); ++ val = (__force u32)cpu_to_be32(*(u32 *)&ecc[5]); + elm_write_reg(info, offset, val); + + /* syndrome fragment 2 = ecc[1-4B] */ + offset += 4; +- val = cpu_to_be32(*(u32 *) &ecc[1]); ++ val = (__force u32)cpu_to_be32(*(u32 *)&ecc[1]); + elm_write_reg(info, offset, val); + + /* syndrome fragment 3 = ecc[0B] */ +@@ -194,35 +194,35 @@ static void elm_load_syndrome(struct elm_info *info, + break; + case BCH4_ECC: + /* syndrome fragment 0 = ecc[20-52b] bits */ +- val = (cpu_to_be32(*(u32 *) &ecc[3]) >> 4) | ++ val = ((__force u32)cpu_to_be32(*(u32 *)&ecc[3]) >> 4) | + ((ecc[2] & 0xf) << 28); + elm_write_reg(info, offset, val); + + /* syndrome fragment 1 = ecc[0-20b] bits */ + offset += 4; +- val = cpu_to_be32(*(u32 *) &ecc[0]) >> 12; ++ val = (__force u32)cpu_to_be32(*(u32 *)&ecc[0]) >> 12; + elm_write_reg(info, offset, val); + break; + case BCH16_ECC: +- val = cpu_to_be32(*(u32 *) &ecc[22]); ++ val = (__force u32)cpu_to_be32(*(u32 *)&ecc[22]); + elm_write_reg(info, offset, val); + offset += 4; +- val = cpu_to_be32(*(u32 *) &ecc[18]); ++ val = (__force u32)cpu_to_be32(*(u32 *)&ecc[18]); + elm_write_reg(info, offset, val); + offset += 4; +- val = cpu_to_be32(*(u32 *) &ecc[14]); ++ val = (__force u32)cpu_to_be32(*(u32 *)&ecc[14]); + elm_write_reg(info, offset, val); + offset += 4; +- val = cpu_to_be32(*(u32 *) &ecc[10]); ++ val = (__force u32)cpu_to_be32(*(u32 *)&ecc[10]); + elm_write_reg(info, offset, val); + offset += 4; +- val = cpu_to_be32(*(u32 *) &ecc[6]); ++ val = (__force u32)cpu_to_be32(*(u32 *)&ecc[6]); + elm_write_reg(info, offset, val); + offset += 4; +- val = cpu_to_be32(*(u32 *) &ecc[2]); ++ val = (__force u32)cpu_to_be32(*(u32 *)&ecc[2]); + elm_write_reg(info, offset, val); + offset += 4; +- val = cpu_to_be32(*(u32 *) &ecc[0]) >> 16; ++ val = (__force u32)cpu_to_be32(*(u32 *)&ecc[0]) >> 16; + elm_write_reg(info, offset, val); + break; + default: +diff --git a/drivers/mtd/nand/spi/toshiba.c b/drivers/mtd/nand/spi/toshiba.c +index 1cb3760ff779f..b3ed6b42a76f6 100644 +--- a/drivers/mtd/nand/spi/toshiba.c ++++ b/drivers/mtd/nand/spi/toshiba.c +@@ -60,7 +60,7 @@ static int tc58cxgxsx_ecc_get_status(struct spinand_device *spinand, + { + struct nand_device *nand = spinand_to_nand(spinand); + u8 mbf = 0; +- struct spi_mem_op op = SPINAND_GET_FEATURE_OP(0x30, &mbf); ++ struct spi_mem_op op = SPINAND_GET_FEATURE_OP(0x30, spinand->scratchbuf); + + switch (status & STATUS_ECC_MASK) { + case STATUS_ECC_NO_BITFLIPS: +@@ -79,7 +79,7 @@ static int tc58cxgxsx_ecc_get_status(struct spinand_device *spinand, + if (spi_mem_exec_op(spinand->spimem, &op)) + return nand->eccreq.strength; + +- mbf >>= 4; ++ mbf = *(spinand->scratchbuf) >> 4; + + if (WARN_ON(mbf > nand->eccreq.strength || !mbf)) + return nand->eccreq.strength; +diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c +index cdb9efae6032d..dcaefb47d1f2d 100644 +--- a/drivers/net/bonding/bond_main.c ++++ b/drivers/net/bonding/bond_main.c +@@ -1153,6 +1153,11 @@ static void bond_setup_by_slave(struct net_device *bond_dev, + + memcpy(bond_dev->broadcast, slave_dev->broadcast, + slave_dev->addr_len); ++ ++ if (slave_dev->flags & IFF_POINTOPOINT) { ++ bond_dev->flags &= ~(IFF_BROADCAST | IFF_MULTICAST); ++ bond_dev->flags |= (IFF_POINTOPOINT | IFF_NOARP); ++ } + } + + /* On bonding slaves other than the currently active slave, suppress +diff --git a/drivers/net/can/usb/gs_usb.c b/drivers/net/can/usb/gs_usb.c +index abd2a57b18cbb..de5e5385fc110 100644 +--- a/drivers/net/can/usb/gs_usb.c ++++ b/drivers/net/can/usb/gs_usb.c +@@ -732,6 +732,8 @@ static int gs_can_close(struct net_device *netdev) + usb_kill_anchored_urbs(&dev->tx_submitted); + atomic_set(&dev->active_tx_urbs, 0); + ++ dev->can.state = CAN_STATE_STOPPED; ++ + /* reset the device */ + rc = gs_cmd_reset(dev); + if (rc < 0) +diff --git a/drivers/net/ethernet/atheros/atl1e/atl1e_main.c b/drivers/net/ethernet/atheros/atl1e/atl1e_main.c +index 4f7b65825c159..6bdd79a057190 100644 +--- a/drivers/net/ethernet/atheros/atl1e/atl1e_main.c ++++ b/drivers/net/ethernet/atheros/atl1e/atl1e_main.c +@@ -1638,8 +1638,11 @@ static int atl1e_tso_csum(struct atl1e_adapter *adapter, + real_len = (((unsigned char *)ip_hdr(skb) - skb->data) + + ntohs(ip_hdr(skb)->tot_len)); + +- if (real_len < skb->len) +- pskb_trim(skb, real_len); ++ if (real_len < skb->len) { ++ err = pskb_trim(skb, real_len); ++ if (err) ++ return err; ++ } + + hdr_len = (skb_transport_offset(skb) + tcp_hdrlen(skb)); + if (unlikely(skb->len == hdr_len)) { +diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c +index f1cce7636722e..a7a3e2ee06768 100644 +--- a/drivers/net/ethernet/emulex/benet/be_main.c ++++ b/drivers/net/ethernet/emulex/benet/be_main.c +@@ -1140,7 +1140,8 @@ static struct sk_buff *be_lancer_xmit_workarounds(struct be_adapter *adapter, + (lancer_chip(adapter) || BE3_chip(adapter) || + skb_vlan_tag_present(skb)) && is_ipv4_pkt(skb)) { + ip = (struct iphdr *)ip_hdr(skb); +- pskb_trim(skb, eth_hdr_len + ntohs(ip->tot_len)); ++ if (unlikely(pskb_trim(skb, eth_hdr_len + ntohs(ip->tot_len)))) ++ goto tx_drop; + } + + /* If vlan tag is already inlined in the packet, skip HW VLAN +diff --git a/drivers/net/ethernet/intel/i40e/i40e_debugfs.c b/drivers/net/ethernet/intel/i40e/i40e_debugfs.c +index 276f04c0e51d6..31f60657f5321 100644 +--- a/drivers/net/ethernet/intel/i40e/i40e_debugfs.c ++++ b/drivers/net/ethernet/intel/i40e/i40e_debugfs.c +@@ -1755,7 +1755,7 @@ void i40e_dbg_pf_exit(struct i40e_pf *pf) + void i40e_dbg_init(void) + { + i40e_dbg_root = debugfs_create_dir(i40e_driver_name, NULL); +- if (!i40e_dbg_root) ++ if (IS_ERR(i40e_dbg_root)) + pr_info("init of debugfs failed\n"); + } + +diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +index a864b91065e33..567bb7792f8fe 100644 +--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c ++++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +@@ -8423,7 +8423,7 @@ static void ixgbe_atr(struct ixgbe_ring *ring, + struct ixgbe_adapter *adapter = q_vector->adapter; + + if (unlikely(skb_tail_pointer(skb) < hdr.network + +- VXLAN_HEADROOM)) ++ vxlan_headroom(0))) + return; + + /* verify the port is recognized as VXLAN */ +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_rxtx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_rxtx.c +index 0dd17514caae8..d212706f1bdea 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_rxtx.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_rxtx.c +@@ -121,7 +121,9 @@ static int mlx5e_ipsec_remove_trailer(struct sk_buff *skb, struct xfrm_state *x) + + trailer_len = alen + plen + 2; + +- pskb_trim(skb, skb->len - trailer_len); ++ ret = pskb_trim(skb, skb->len - trailer_len); ++ if (unlikely(ret)) ++ return ret; + if (skb->protocol == htons(ETH_P_IP)) { + ipv4hdr->tot_len = htons(ntohs(ipv4hdr->tot_len) - trailer_len); + ip_send_check(ipv4hdr); +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_cmd.c b/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_cmd.c +index 64f6f529f6eb1..45b90c7698787 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_cmd.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_cmd.c +@@ -423,11 +423,12 @@ int mlx5dr_cmd_create_reformat_ctx(struct mlx5_core_dev *mdev, + + err = mlx5_cmd_exec(mdev, in, inlen, out, sizeof(out)); + if (err) +- return err; ++ goto err_free_in; + + *reformat_id = MLX5_GET(alloc_packet_reformat_context_out, out, packet_reformat_id); +- kvfree(in); + ++err_free_in: ++ kvfree(in); + return err; + } + +diff --git a/drivers/net/ethernet/xilinx/ll_temac_main.c b/drivers/net/ethernet/xilinx/ll_temac_main.c +index a109438f4a78e..86edc95919146 100644 +--- a/drivers/net/ethernet/xilinx/ll_temac_main.c ++++ b/drivers/net/ethernet/xilinx/ll_temac_main.c +@@ -1481,15 +1481,15 @@ static int temac_probe(struct platform_device *pdev) + } + + /* Error handle returned DMA RX and TX interrupts */ +- if (lp->rx_irq < 0) { +- if (lp->rx_irq != -EPROBE_DEFER) +- dev_err(&pdev->dev, "could not get DMA RX irq\n"); +- return lp->rx_irq; ++ if (lp->rx_irq <= 0) { ++ rc = lp->rx_irq ?: -EINVAL; ++ return dev_err_probe(&pdev->dev, rc, ++ "could not get DMA RX irq\n"); + } +- if (lp->tx_irq < 0) { +- if (lp->tx_irq != -EPROBE_DEFER) +- dev_err(&pdev->dev, "could not get DMA TX irq\n"); +- return lp->tx_irq; ++ if (lp->tx_irq <= 0) { ++ rc = lp->tx_irq ?: -EINVAL; ++ return dev_err_probe(&pdev->dev, rc, ++ "could not get DMA TX irq\n"); + } + + if (temac_np) { +diff --git a/drivers/net/tap.c b/drivers/net/tap.c +index 574c17aa4b09a..c299faaf4b2d5 100644 +--- a/drivers/net/tap.c ++++ b/drivers/net/tap.c +@@ -525,7 +525,7 @@ static int tap_open(struct inode *inode, struct file *file) + q->sock.state = SS_CONNECTED; + q->sock.file = file; + q->sock.ops = &tap_socket_ops; +- sock_init_data_uid(&q->sock, &q->sk, inode->i_uid); ++ sock_init_data_uid(&q->sock, &q->sk, current_fsuid()); + q->sk.sk_write_space = tap_sock_write_space; + q->sk.sk_destruct = tap_sock_destruct; + q->flags = IFF_VNET_HDR | IFF_NO_PI | IFF_TAP; +diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c +index 227d97b4dc224..5c72e9ac4804d 100644 +--- a/drivers/net/team/team.c ++++ b/drivers/net/team/team.c +@@ -2129,6 +2129,15 @@ static void team_setup_by_port(struct net_device *dev, + dev->mtu = port_dev->mtu; + memcpy(dev->broadcast, port_dev->broadcast, port_dev->addr_len); + eth_hw_addr_inherit(dev, port_dev); ++ ++ if (port_dev->flags & IFF_POINTOPOINT) { ++ dev->flags &= ~(IFF_BROADCAST | IFF_MULTICAST); ++ dev->flags |= (IFF_POINTOPOINT | IFF_NOARP); ++ } else if ((port_dev->flags & (IFF_BROADCAST | IFF_MULTICAST)) == ++ (IFF_BROADCAST | IFF_MULTICAST)) { ++ dev->flags |= (IFF_BROADCAST | IFF_MULTICAST); ++ dev->flags &= ~(IFF_POINTOPOINT | IFF_NOARP); ++ } + } + + static int team_dev_type_check_change(struct net_device *dev, +diff --git a/drivers/net/tun.c b/drivers/net/tun.c +index a4e44f98fbc33..309a0dd16bdc1 100644 +--- a/drivers/net/tun.c ++++ b/drivers/net/tun.c +@@ -3534,7 +3534,7 @@ static int tun_chr_open(struct inode *inode, struct file * file) + tfile->socket.file = file; + tfile->socket.ops = &tun_socket_ops; + +- sock_init_data_uid(&tfile->socket, &tfile->sk, inode->i_uid); ++ sock_init_data_uid(&tfile->socket, &tfile->sk, current_fsuid()); + + tfile->sk.sk_write_space = tun_sock_write_space; + tfile->sk.sk_sndbuf = INT_MAX; +diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c +index e457fa8c0ca5d..08800f2a7e458 100644 +--- a/drivers/net/usb/cdc_ether.c ++++ b/drivers/net/usb/cdc_ether.c +@@ -605,9 +605,23 @@ static const struct usb_device_id products[] = { + .match_flags = USB_DEVICE_ID_MATCH_INT_INFO + | USB_DEVICE_ID_MATCH_DEVICE, + .idVendor = 0x04DD, ++ .idProduct = 0x8005, /* A-300 */ ++ ZAURUS_FAKE_INTERFACE, ++ .driver_info = 0, ++}, { ++ .match_flags = USB_DEVICE_ID_MATCH_INT_INFO ++ | USB_DEVICE_ID_MATCH_DEVICE, ++ .idVendor = 0x04DD, + .idProduct = 0x8006, /* B-500/SL-5600 */ + ZAURUS_MASTER_INTERFACE, + .driver_info = 0, ++}, { ++ .match_flags = USB_DEVICE_ID_MATCH_INT_INFO ++ | USB_DEVICE_ID_MATCH_DEVICE, ++ .idVendor = 0x04DD, ++ .idProduct = 0x8006, /* B-500/SL-5600 */ ++ ZAURUS_FAKE_INTERFACE, ++ .driver_info = 0, + }, { + .match_flags = USB_DEVICE_ID_MATCH_INT_INFO + | USB_DEVICE_ID_MATCH_DEVICE, +@@ -615,6 +629,13 @@ static const struct usb_device_id products[] = { + .idProduct = 0x8007, /* C-700 */ + ZAURUS_MASTER_INTERFACE, + .driver_info = 0, ++}, { ++ .match_flags = USB_DEVICE_ID_MATCH_INT_INFO ++ | USB_DEVICE_ID_MATCH_DEVICE, ++ .idVendor = 0x04DD, ++ .idProduct = 0x8007, /* C-700 */ ++ ZAURUS_FAKE_INTERFACE, ++ .driver_info = 0, + }, { + .match_flags = USB_DEVICE_ID_MATCH_INT_INFO + | USB_DEVICE_ID_MATCH_DEVICE, +diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c +index 7af8c3a8f3f17..bc37e268a15e7 100644 +--- a/drivers/net/usb/usbnet.c ++++ b/drivers/net/usb/usbnet.c +@@ -1756,6 +1756,10 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod) + } else if (!info->in || !info->out) + status = usbnet_get_endpoints (dev, udev); + else { ++ u8 ep_addrs[3] = { ++ info->in + USB_DIR_IN, info->out + USB_DIR_OUT, 0 ++ }; ++ + dev->in = usb_rcvbulkpipe (xdev, info->in); + dev->out = usb_sndbulkpipe (xdev, info->out); + if (!(info->flags & FLAG_NO_SETINT)) +@@ -1765,6 +1769,8 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod) + else + status = 0; + ++ if (status == 0 && !usb_check_bulk_endpoints(udev, ep_addrs)) ++ status = -EINVAL; + } + if (status >= 0 && dev->status) + status = init_status (dev, udev); +diff --git a/drivers/net/usb/zaurus.c b/drivers/net/usb/zaurus.c +index 7984f2157d222..df3617c4c44e8 100644 +--- a/drivers/net/usb/zaurus.c ++++ b/drivers/net/usb/zaurus.c +@@ -289,9 +289,23 @@ static const struct usb_device_id products [] = { + .match_flags = USB_DEVICE_ID_MATCH_INT_INFO + | USB_DEVICE_ID_MATCH_DEVICE, + .idVendor = 0x04DD, ++ .idProduct = 0x8005, /* A-300 */ ++ ZAURUS_FAKE_INTERFACE, ++ .driver_info = (unsigned long)&bogus_mdlm_info, ++}, { ++ .match_flags = USB_DEVICE_ID_MATCH_INT_INFO ++ | USB_DEVICE_ID_MATCH_DEVICE, ++ .idVendor = 0x04DD, + .idProduct = 0x8006, /* B-500/SL-5600 */ + ZAURUS_MASTER_INTERFACE, + .driver_info = ZAURUS_PXA_INFO, ++}, { ++ .match_flags = USB_DEVICE_ID_MATCH_INT_INFO ++ | USB_DEVICE_ID_MATCH_DEVICE, ++ .idVendor = 0x04DD, ++ .idProduct = 0x8006, /* B-500/SL-5600 */ ++ ZAURUS_FAKE_INTERFACE, ++ .driver_info = (unsigned long)&bogus_mdlm_info, + }, { + .match_flags = USB_DEVICE_ID_MATCH_INT_INFO + | USB_DEVICE_ID_MATCH_DEVICE, +@@ -299,6 +313,13 @@ static const struct usb_device_id products [] = { + .idProduct = 0x8007, /* C-700 */ + ZAURUS_MASTER_INTERFACE, + .driver_info = ZAURUS_PXA_INFO, ++}, { ++ .match_flags = USB_DEVICE_ID_MATCH_INT_INFO ++ | USB_DEVICE_ID_MATCH_DEVICE, ++ .idVendor = 0x04DD, ++ .idProduct = 0x8007, /* C-700 */ ++ ZAURUS_FAKE_INTERFACE, ++ .driver_info = (unsigned long)&bogus_mdlm_info, + }, { + .match_flags = USB_DEVICE_ID_MATCH_INT_INFO + | USB_DEVICE_ID_MATCH_DEVICE, +diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c +index 7922e833620e8..6e520720beb59 100644 +--- a/drivers/net/virtio_net.c ++++ b/drivers/net/virtio_net.c +@@ -3265,6 +3265,8 @@ static int virtnet_probe(struct virtio_device *vdev) + } + } + ++ _virtnet_set_queues(vi, vi->curr_queue_pairs); ++ + /* serialize netdev register + virtio_device_ready() with ndo_open() */ + rtnl_lock(); + +@@ -3285,8 +3287,6 @@ static int virtnet_probe(struct virtio_device *vdev) + goto free_unregister_netdev; + } + +- virtnet_set_queues(vi, vi->curr_queue_pairs); +- + /* Assume link up if device can't report link status, + otherwise get link status from config. */ + netif_carrier_off(dev); +diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c +index f4869b1836f30..1e3e075454f33 100644 +--- a/drivers/net/vxlan.c ++++ b/drivers/net/vxlan.c +@@ -2550,7 +2550,7 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev, + } + + ndst = &rt->dst; +- skb_tunnel_check_pmtu(skb, ndst, VXLAN_HEADROOM); ++ skb_tunnel_check_pmtu(skb, ndst, vxlan_headroom(flags & VXLAN_F_GPE)); + + tos = ip_tunnel_ecn_encap(tos, old_iph, skb); + ttl = ttl ? : ip4_dst_hoplimit(&rt->dst); +@@ -2590,7 +2590,7 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev, + goto out_unlock; + } + +- skb_tunnel_check_pmtu(skb, ndst, VXLAN6_HEADROOM); ++ skb_tunnel_check_pmtu(skb, ndst, vxlan_headroom((flags & VXLAN_F_GPE) | VXLAN_F_IPV6)); + + tos = ip_tunnel_ecn_encap(tos, old_iph, skb); + ttl = ttl ? : ip6_dst_hoplimit(ndst); +@@ -2908,14 +2908,12 @@ static int vxlan_change_mtu(struct net_device *dev, int new_mtu) + struct vxlan_rdst *dst = &vxlan->default_dst; + struct net_device *lowerdev = __dev_get_by_index(vxlan->net, + dst->remote_ifindex); +- bool use_ipv6 = !!(vxlan->cfg.flags & VXLAN_F_IPV6); + + /* This check is different than dev->max_mtu, because it looks at + * the lowerdev->mtu, rather than the static dev->max_mtu + */ + if (lowerdev) { +- int max_mtu = lowerdev->mtu - +- (use_ipv6 ? VXLAN6_HEADROOM : VXLAN_HEADROOM); ++ int max_mtu = lowerdev->mtu - vxlan_headroom(vxlan->cfg.flags); + if (new_mtu > max_mtu) + return -EINVAL; + } +@@ -3514,11 +3512,11 @@ static void vxlan_config_apply(struct net_device *dev, + struct vxlan_dev *vxlan = netdev_priv(dev); + struct vxlan_rdst *dst = &vxlan->default_dst; + unsigned short needed_headroom = ETH_HLEN; +- bool use_ipv6 = !!(conf->flags & VXLAN_F_IPV6); + int max_mtu = ETH_MAX_MTU; ++ u32 flags = conf->flags; + + if (!changelink) { +- if (conf->flags & VXLAN_F_GPE) ++ if (flags & VXLAN_F_GPE) + vxlan_raw_setup(dev); + else + vxlan_ether_setup(dev); +@@ -3544,8 +3542,7 @@ static void vxlan_config_apply(struct net_device *dev, + + dev->needed_tailroom = lowerdev->needed_tailroom; + +- max_mtu = lowerdev->mtu - (use_ipv6 ? VXLAN6_HEADROOM : +- VXLAN_HEADROOM); ++ max_mtu = lowerdev->mtu - vxlan_headroom(flags); + if (max_mtu < ETH_MIN_MTU) + max_mtu = ETH_MIN_MTU; + +@@ -3556,10 +3553,9 @@ static void vxlan_config_apply(struct net_device *dev, + if (dev->mtu > max_mtu) + dev->mtu = max_mtu; + +- if (use_ipv6 || conf->flags & VXLAN_F_COLLECT_METADATA) +- needed_headroom += VXLAN6_HEADROOM; +- else +- needed_headroom += VXLAN_HEADROOM; ++ if (flags & VXLAN_F_COLLECT_METADATA) ++ flags |= VXLAN_F_IPV6; ++ needed_headroom += vxlan_headroom(flags); + dev->needed_headroom = needed_headroom; + + memcpy(&vxlan->cfg, conf, sizeof(*conf)); +diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c +index d8d27b11b48c4..55270180ae081 100644 +--- a/drivers/pci/pcie/aspm.c ++++ b/drivers/pci/pcie/aspm.c +@@ -200,12 +200,39 @@ static void pcie_clkpm_cap_init(struct pcie_link_state *link, int blacklist) + link->clkpm_disable = blacklist ? 1 : 0; + } + +-static bool pcie_retrain_link(struct pcie_link_state *link) ++static int pcie_wait_for_retrain(struct pci_dev *pdev) + { +- struct pci_dev *parent = link->pdev; + unsigned long end_jiffies; + u16 reg16; + ++ /* Wait for Link Training to be cleared by hardware */ ++ end_jiffies = jiffies + LINK_RETRAIN_TIMEOUT; ++ do { ++ pcie_capability_read_word(pdev, PCI_EXP_LNKSTA, ®16); ++ if (!(reg16 & PCI_EXP_LNKSTA_LT)) ++ return 0; ++ msleep(1); ++ } while (time_before(jiffies, end_jiffies)); ++ ++ return -ETIMEDOUT; ++} ++ ++static int pcie_retrain_link(struct pcie_link_state *link) ++{ ++ struct pci_dev *parent = link->pdev; ++ int rc; ++ u16 reg16; ++ ++ /* ++ * Ensure the updated LNKCTL parameters are used during link ++ * training by checking that there is no ongoing link training to ++ * avoid LTSSM race as recommended in Implementation Note at the ++ * end of PCIe r6.0.1 sec 7.5.3.7. ++ */ ++ rc = pcie_wait_for_retrain(parent); ++ if (rc) ++ return rc; ++ + pcie_capability_read_word(parent, PCI_EXP_LNKCTL, ®16); + reg16 |= PCI_EXP_LNKCTL_RL; + pcie_capability_write_word(parent, PCI_EXP_LNKCTL, reg16); +@@ -219,15 +246,7 @@ static bool pcie_retrain_link(struct pcie_link_state *link) + pcie_capability_write_word(parent, PCI_EXP_LNKCTL, reg16); + } + +- /* Wait for link training end. Break out after waiting for timeout */ +- end_jiffies = jiffies + LINK_RETRAIN_TIMEOUT; +- do { +- pcie_capability_read_word(parent, PCI_EXP_LNKSTA, ®16); +- if (!(reg16 & PCI_EXP_LNKSTA_LT)) +- break; +- msleep(1); +- } while (time_before(jiffies, end_jiffies)); +- return !(reg16 & PCI_EXP_LNKSTA_LT); ++ return pcie_wait_for_retrain(parent); + } + + /* +@@ -296,15 +315,15 @@ static void pcie_aspm_configure_common_clock(struct pcie_link_state *link) + reg16 &= ~PCI_EXP_LNKCTL_CCC; + pcie_capability_write_word(parent, PCI_EXP_LNKCTL, reg16); + +- if (pcie_retrain_link(link)) +- return; ++ if (pcie_retrain_link(link)) { + +- /* Training failed. Restore common clock configurations */ +- pci_err(parent, "ASPM: Could not configure common clock\n"); +- list_for_each_entry(child, &linkbus->devices, bus_list) +- pcie_capability_write_word(child, PCI_EXP_LNKCTL, ++ /* Training failed. Restore common clock configurations */ ++ pci_err(parent, "ASPM: Could not configure common clock\n"); ++ list_for_each_entry(child, &linkbus->devices, bus_list) ++ pcie_capability_write_word(child, PCI_EXP_LNKCTL, + child_reg[PCI_FUNC(child->devfn)]); +- pcie_capability_write_word(parent, PCI_EXP_LNKCTL, parent_reg); ++ pcie_capability_write_word(parent, PCI_EXP_LNKCTL, parent_reg); ++ } + } + + /* Convert L0s latency encoding to ns */ +diff --git a/drivers/phy/hisilicon/phy-hisi-inno-usb2.c b/drivers/phy/hisilicon/phy-hisi-inno-usb2.c +index 9b16f13b5ab29..96162b9a2e53d 100644 +--- a/drivers/phy/hisilicon/phy-hisi-inno-usb2.c ++++ b/drivers/phy/hisilicon/phy-hisi-inno-usb2.c +@@ -155,7 +155,7 @@ static int hisi_inno_phy_probe(struct platform_device *pdev) + phy_set_drvdata(phy, &priv->ports[i]); + i++; + +- if (i > INNO_PHY_PORT_NUM) { ++ if (i >= INNO_PHY_PORT_NUM) { + dev_warn(dev, "Support %d ports in maximum\n", i); + break; + } +diff --git a/drivers/platform/x86/msi-laptop.c b/drivers/platform/x86/msi-laptop.c +index 0e804b6c2d242..dfb4af759aa75 100644 +--- a/drivers/platform/x86/msi-laptop.c ++++ b/drivers/platform/x86/msi-laptop.c +@@ -210,7 +210,7 @@ static ssize_t set_device_state(const char *buf, size_t count, u8 mask) + return -EINVAL; + + if (quirks->ec_read_only) +- return -EOPNOTSUPP; ++ return 0; + + /* read current device state */ + result = ec_read(MSI_STANDARD_EC_COMMAND_ADDRESS, &rdata); +@@ -841,15 +841,15 @@ static bool msi_laptop_i8042_filter(unsigned char data, unsigned char str, + static void msi_init_rfkill(struct work_struct *ignored) + { + if (rfk_wlan) { +- rfkill_set_sw_state(rfk_wlan, !wlan_s); ++ msi_rfkill_set_state(rfk_wlan, !wlan_s); + rfkill_wlan_set(NULL, !wlan_s); + } + if (rfk_bluetooth) { +- rfkill_set_sw_state(rfk_bluetooth, !bluetooth_s); ++ msi_rfkill_set_state(rfk_bluetooth, !bluetooth_s); + rfkill_bluetooth_set(NULL, !bluetooth_s); + } + if (rfk_threeg) { +- rfkill_set_sw_state(rfk_threeg, !threeg_s); ++ msi_rfkill_set_state(rfk_threeg, !threeg_s); + rfkill_threeg_set(NULL, !threeg_s); + } + } +diff --git a/drivers/pwm/pwm-meson.c b/drivers/pwm/pwm-meson.c +index 9fc08d1de34c2..768e6e691c7cc 100644 +--- a/drivers/pwm/pwm-meson.c ++++ b/drivers/pwm/pwm-meson.c +@@ -147,12 +147,13 @@ static int meson_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm) + return err; + } + +- return pwm_set_chip_data(pwm, channel); ++ return 0; + } + + static void meson_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm) + { +- struct meson_pwm_channel *channel = pwm_get_chip_data(pwm); ++ struct meson_pwm *meson = to_meson_pwm(chip); ++ struct meson_pwm_channel *channel = &meson->channels[pwm->hwpwm]; + + if (channel) + clk_disable_unprepare(channel->clk); +@@ -161,9 +162,10 @@ static void meson_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm) + static int meson_pwm_calc(struct meson_pwm *meson, struct pwm_device *pwm, + const struct pwm_state *state) + { +- struct meson_pwm_channel *channel = pwm_get_chip_data(pwm); +- unsigned int duty, period, pre_div, cnt, duty_cnt; +- unsigned long fin_freq = -1; ++ struct meson_pwm_channel *channel = &meson->channels[pwm->hwpwm]; ++ unsigned int pre_div, cnt, duty_cnt; ++ unsigned long fin_freq; ++ u64 duty, period; + + duty = state->duty_cycle; + period = state->period; +@@ -185,19 +187,19 @@ static int meson_pwm_calc(struct meson_pwm *meson, struct pwm_device *pwm, + + dev_dbg(meson->chip.dev, "fin_freq: %lu Hz\n", fin_freq); + +- pre_div = div64_u64(fin_freq * (u64)period, NSEC_PER_SEC * 0xffffLL); ++ pre_div = div64_u64(fin_freq * period, NSEC_PER_SEC * 0xffffLL); + if (pre_div > MISC_CLK_DIV_MASK) { + dev_err(meson->chip.dev, "unable to get period pre_div\n"); + return -EINVAL; + } + +- cnt = div64_u64(fin_freq * (u64)period, NSEC_PER_SEC * (pre_div + 1)); ++ cnt = div64_u64(fin_freq * period, NSEC_PER_SEC * (pre_div + 1)); + if (cnt > 0xffff) { + dev_err(meson->chip.dev, "unable to get period cnt\n"); + return -EINVAL; + } + +- dev_dbg(meson->chip.dev, "period=%u pre_div=%u cnt=%u\n", period, ++ dev_dbg(meson->chip.dev, "period=%llu pre_div=%u cnt=%u\n", period, + pre_div, cnt); + + if (duty == period) { +@@ -210,14 +212,13 @@ static int meson_pwm_calc(struct meson_pwm *meson, struct pwm_device *pwm, + channel->lo = cnt; + } else { + /* Then check is we can have the duty with the same pre_div */ +- duty_cnt = div64_u64(fin_freq * (u64)duty, +- NSEC_PER_SEC * (pre_div + 1)); ++ duty_cnt = div64_u64(fin_freq * duty, NSEC_PER_SEC * (pre_div + 1)); + if (duty_cnt > 0xffff) { + dev_err(meson->chip.dev, "unable to get duty cycle\n"); + return -EINVAL; + } + +- dev_dbg(meson->chip.dev, "duty=%u pre_div=%u duty_cnt=%u\n", ++ dev_dbg(meson->chip.dev, "duty=%llu pre_div=%u duty_cnt=%u\n", + duty, pre_div, duty_cnt); + + channel->pre_div = pre_div; +@@ -230,7 +231,7 @@ static int meson_pwm_calc(struct meson_pwm *meson, struct pwm_device *pwm, + + static void meson_pwm_enable(struct meson_pwm *meson, struct pwm_device *pwm) + { +- struct meson_pwm_channel *channel = pwm_get_chip_data(pwm); ++ struct meson_pwm_channel *channel = &meson->channels[pwm->hwpwm]; + struct meson_pwm_channel_data *channel_data; + unsigned long flags; + u32 value; +@@ -273,8 +274,8 @@ static void meson_pwm_disable(struct meson_pwm *meson, struct pwm_device *pwm) + static int meson_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, + const struct pwm_state *state) + { +- struct meson_pwm_channel *channel = pwm_get_chip_data(pwm); + struct meson_pwm *meson = to_meson_pwm(chip); ++ struct meson_pwm_channel *channel = &meson->channels[pwm->hwpwm]; + int err = 0; + + if (!state) +diff --git a/drivers/s390/block/dasd_ioctl.c b/drivers/s390/block/dasd_ioctl.c +index d7aed832910c4..caab2cd2e0bdc 100644 +--- a/drivers/s390/block/dasd_ioctl.c ++++ b/drivers/s390/block/dasd_ioctl.c +@@ -137,6 +137,7 @@ static int dasd_ioctl_resume(struct dasd_block *block) + spin_unlock_irqrestore(get_ccwdev_lock(base->cdev), flags); + + dasd_schedule_block_bh(block); ++ dasd_schedule_device_bh(base); + return 0; + } + +diff --git a/drivers/s390/scsi/zfcp_fc.c b/drivers/s390/scsi/zfcp_fc.c +index 7285e6ca948ff..459eed7aca66c 100644 +--- a/drivers/s390/scsi/zfcp_fc.c ++++ b/drivers/s390/scsi/zfcp_fc.c +@@ -534,8 +534,7 @@ static void zfcp_fc_adisc_handler(void *data) + + /* re-init to undo drop from zfcp_fc_adisc() */ + port->d_id = ntoh24(adisc_resp->adisc_port_id); +- /* port is good, unblock rport without going through erp */ +- zfcp_scsi_schedule_rport_register(port); ++ /* port is still good, nothing to do */ + out: + atomic_andnot(ZFCP_STATUS_PORT_LINK_TEST, &port->status); + put_device(&port->dev); +@@ -595,9 +594,6 @@ void zfcp_fc_link_test_work(struct work_struct *work) + int retval; + + set_worker_desc("zadisc%16llx", port->wwpn); /* < WORKER_DESC_LEN=24 */ +- get_device(&port->dev); +- port->rport_task = RPORT_DEL; +- zfcp_scsi_rport_work(&port->rport_work); + + /* only issue one test command at one time per port */ + if (atomic_read(&port->status) & ZFCP_STATUS_PORT_LINK_TEST) +diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c +index 30a5ca9c5a8d4..99d4bc2ab5a91 100644 +--- a/drivers/scsi/qla2xxx/qla_os.c ++++ b/drivers/scsi/qla2xxx/qla_os.c +@@ -4831,7 +4831,8 @@ struct scsi_qla_host *qla2x00_create_host(struct scsi_host_template *sht, + } + INIT_DELAYED_WORK(&vha->scan.scan_work, qla_scan_work_fn); + +- sprintf(vha->host_str, "%s_%ld", QLA2XXX_DRIVER_NAME, vha->host_no); ++ snprintf(vha->host_str, sizeof(vha->host_str), "%s_%lu", ++ QLA2XXX_DRIVER_NAME, vha->host_no); + ql_dbg(ql_dbg_init, vha, 0x0041, + "Allocated the host=%p hw=%p vha=%p dev_name=%s", + vha->host, vha->hw, vha, +@@ -4961,7 +4962,7 @@ qla2x00_uevent_emit(struct scsi_qla_host *vha, u32 code) + + switch (code) { + case QLA_UEVENT_CODE_FW_DUMP: +- snprintf(event_string, sizeof(event_string), "FW_DUMP=%ld", ++ snprintf(event_string, sizeof(event_string), "FW_DUMP=%lu", + vha->host_no); + break; + default: +diff --git a/drivers/staging/ks7010/ks_wlan_net.c b/drivers/staging/ks7010/ks_wlan_net.c +index e61bd8e1d246f..b565c26ca72fe 100644 +--- a/drivers/staging/ks7010/ks_wlan_net.c ++++ b/drivers/staging/ks7010/ks_wlan_net.c +@@ -1584,8 +1584,10 @@ static int ks_wlan_set_encode_ext(struct net_device *dev, + commit |= SME_WEP_FLAG; + } + if (enc->key_len) { +- memcpy(&key->key_val[0], &enc->key[0], enc->key_len); +- key->key_len = enc->key_len; ++ int key_len = clamp_val(enc->key_len, 0, IW_ENCODING_TOKEN_MAX); ++ ++ memcpy(&key->key_val[0], &enc->key[0], key_len); ++ key->key_len = key_len; + commit |= (SME_WEP_VAL1 << index); + } + break; +diff --git a/drivers/tty/serial/8250/8250_dwlib.c b/drivers/tty/serial/8250/8250_dwlib.c +index 6d6a78eead3ef..1cf229cca5928 100644 +--- a/drivers/tty/serial/8250/8250_dwlib.c ++++ b/drivers/tty/serial/8250/8250_dwlib.c +@@ -80,7 +80,7 @@ static void dw8250_set_divisor(struct uart_port *p, unsigned int baud, + void dw8250_setup_port(struct uart_port *p) + { + struct uart_8250_port *up = up_to_u8250p(p); +- u32 reg; ++ u32 reg, old_dlf; + + /* + * If the Component Version Register returns zero, we know that +@@ -93,9 +93,11 @@ void dw8250_setup_port(struct uart_port *p) + dev_dbg(p->dev, "Designware UART version %c.%c%c\n", + (reg >> 24) & 0xff, (reg >> 16) & 0xff, (reg >> 8) & 0xff); + ++ /* Preserve value written by firmware or bootloader */ ++ old_dlf = dw8250_readl_ext(p, DW_UART_DLF); + dw8250_writel_ext(p, DW_UART_DLF, ~0U); + reg = dw8250_readl_ext(p, DW_UART_DLF); +- dw8250_writel_ext(p, DW_UART_DLF, 0); ++ dw8250_writel_ext(p, DW_UART_DLF, old_dlf); + + if (reg) { + struct dw8250_port_data *d = p->private_data; +diff --git a/drivers/tty/serial/sifive.c b/drivers/tty/serial/sifive.c +index 7015632c49905..e11756a8788bb 100644 +--- a/drivers/tty/serial/sifive.c ++++ b/drivers/tty/serial/sifive.c +@@ -821,7 +821,7 @@ static void sifive_serial_console_write(struct console *co, const char *s, + local_irq_restore(flags); + } + +-static int __init sifive_serial_console_setup(struct console *co, char *options) ++static int sifive_serial_console_setup(struct console *co, char *options) + { + struct sifive_serial_port *ssp; + int baud = SIFIVE_DEFAULT_BAUD_RATE; +diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c +index 1346c600ebedf..48cda9b7a8f24 100644 +--- a/drivers/usb/core/quirks.c ++++ b/drivers/usb/core/quirks.c +@@ -437,6 +437,10 @@ static const struct usb_device_id usb_quirk_list[] = { + /* novation SoundControl XL */ + { USB_DEVICE(0x1235, 0x0061), .driver_info = USB_QUIRK_RESET_RESUME }, + ++ /* Focusrite Scarlett Solo USB */ ++ { USB_DEVICE(0x1235, 0x8211), .driver_info = ++ USB_QUIRK_DISCONNECT_SUSPEND }, ++ + /* Huawei 4G LTE module */ + { USB_DEVICE(0x12d1, 0x15bb), .driver_info = + USB_QUIRK_DISCONNECT_SUSPEND }, +diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c +index 27b60623c280e..22c1a68e1cc8a 100644 +--- a/drivers/usb/dwc3/core.c ++++ b/drivers/usb/dwc3/core.c +@@ -248,9 +248,9 @@ int dwc3_core_soft_reset(struct dwc3 *dwc) + /* + * We're resetting only the device side because, if we're in host mode, + * XHCI driver will reset the host block. If dwc3 was configured for +- * host-only mode, then we can return early. ++ * host-only mode or current role is host, then we can return early. + */ +- if (dwc->current_dr_role == DWC3_GCTL_PRTCAP_HOST) ++ if (dwc->dr_mode == USB_DR_MODE_HOST || dwc->current_dr_role == DWC3_GCTL_PRTCAP_HOST) + return 0; + + reg = dwc3_readl(dwc->regs, DWC3_DCTL); +@@ -1010,22 +1010,6 @@ static int dwc3_core_init(struct dwc3 *dwc) + dwc3_writel(dwc->regs, DWC3_GUCTL1, reg); + } + +- if (dwc->dr_mode == USB_DR_MODE_HOST || +- dwc->dr_mode == USB_DR_MODE_OTG) { +- reg = dwc3_readl(dwc->regs, DWC3_GUCTL); +- +- /* +- * Enable Auto retry Feature to make the controller operating in +- * Host mode on seeing transaction errors(CRC errors or internal +- * overrun scenerios) on IN transfers to reply to the device +- * with a non-terminating retry ACK (i.e, an ACK transcation +- * packet with Retry=1 & Nump != 0) +- */ +- reg |= DWC3_GUCTL_HSTINAUTORETRY; +- +- dwc3_writel(dwc->regs, DWC3_GUCTL, reg); +- } +- + /* + * Must config both number of packets and max burst settings to enable + * RX and/or TX threshold. +diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h +index f320b989abd21..5d497efd2f117 100644 +--- a/drivers/usb/dwc3/core.h ++++ b/drivers/usb/dwc3/core.h +@@ -246,9 +246,6 @@ + #define DWC3_GCTL_GBLHIBERNATIONEN BIT(1) + #define DWC3_GCTL_DSBLCLKGTNG BIT(0) + +-/* Global User Control Register */ +-#define DWC3_GUCTL_HSTINAUTORETRY BIT(14) +- + /* Global User Control 1 Register */ + #define DWC3_GUCTL1_PARKMODE_DISABLE_SS BIT(17) + #define DWC3_GUCTL1_TX_IPGAP_LINECHECK_DIS BIT(28) +diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c +index 955bf820f4102..8d4f1b13f4157 100644 +--- a/drivers/usb/dwc3/dwc3-pci.c ++++ b/drivers/usb/dwc3/dwc3-pci.c +@@ -171,10 +171,12 @@ static int dwc3_pci_quirks(struct dwc3_pci *dwc) + + /* + * A lot of BYT devices lack ACPI resource entries for +- * the GPIOs, add a fallback mapping to the reference ++ * the GPIOs. If the ACPI entry for the GPIO controller ++ * is present add a fallback mapping to the reference + * design GPIOs which all boards seem to use. + */ +- gpiod_add_lookup_table(&platform_bytcr_gpios); ++ if (acpi_dev_present("INT33FC", NULL, -1)) ++ gpiod_add_lookup_table(&platform_bytcr_gpios); + + /* + * These GPIOs will turn on the USB2 PHY. Note that we have to +diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c +index fc35a7993b7b6..4374dba4e3848 100644 +--- a/drivers/usb/host/ohci-at91.c ++++ b/drivers/usb/host/ohci-at91.c +@@ -645,7 +645,13 @@ ohci_hcd_at91_drv_resume(struct device *dev) + + at91_start_clock(ohci_at91); + +- ohci_resume(hcd, false); ++ /* ++ * According to the comment in ohci_hcd_at91_drv_suspend() ++ * we need to do a reset if the 48Mhz clock was stopped, ++ * that is, if ohci_at91->wakeup is clear. Tell ohci_resume() ++ * to reset in this case by setting its "hibernated" flag. ++ */ ++ ohci_resume(hcd, !ohci_at91->wakeup); + + ohci_at91_port_suspend(ohci_at91->sfr_regmap, 0); + +diff --git a/drivers/usb/host/xhci-mtk.c b/drivers/usb/host/xhci-mtk.c +index 5c0eb35cd007a..c56c6a0d6222c 100644 +--- a/drivers/usb/host/xhci-mtk.c ++++ b/drivers/usb/host/xhci-mtk.c +@@ -540,6 +540,7 @@ static int xhci_mtk_probe(struct platform_device *pdev) + } + + device_init_wakeup(dev, true); ++ dma_set_max_seg_size(dev, UINT_MAX); + + xhci = hcd_to_xhci(hcd); + xhci->main_hcd = hcd; +diff --git a/drivers/usb/host/xhci-tegra.c b/drivers/usb/host/xhci-tegra.c +index d53bdb7d297f8..6087b1fa530f8 100644 +--- a/drivers/usb/host/xhci-tegra.c ++++ b/drivers/usb/host/xhci-tegra.c +@@ -933,15 +933,15 @@ static int tegra_xusb_powerdomain_init(struct device *dev, + int err; + + tegra->genpd_dev_host = dev_pm_domain_attach_by_name(dev, "xusb_host"); +- if (IS_ERR_OR_NULL(tegra->genpd_dev_host)) { +- err = PTR_ERR(tegra->genpd_dev_host) ? : -ENODATA; ++ if (IS_ERR(tegra->genpd_dev_host)) { ++ err = PTR_ERR(tegra->genpd_dev_host); + dev_err(dev, "failed to get host pm-domain: %d\n", err); + return err; + } + + tegra->genpd_dev_ss = dev_pm_domain_attach_by_name(dev, "xusb_ss"); +- if (IS_ERR_OR_NULL(tegra->genpd_dev_ss)) { +- err = PTR_ERR(tegra->genpd_dev_ss) ? : -ENODATA; ++ if (IS_ERR(tegra->genpd_dev_ss)) { ++ err = PTR_ERR(tegra->genpd_dev_ss); + dev_err(dev, "failed to get superspeed pm-domain: %d\n", err); + return err; + } +diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c +index 939bcbb5404fb..7ab6205ad50cf 100644 +--- a/drivers/usb/serial/option.c ++++ b/drivers/usb/serial/option.c +@@ -251,6 +251,7 @@ static void option_instat_callback(struct urb *urb); + #define QUECTEL_PRODUCT_EM061K_LTA 0x0123 + #define QUECTEL_PRODUCT_EM061K_LMS 0x0124 + #define QUECTEL_PRODUCT_EC25 0x0125 ++#define QUECTEL_PRODUCT_EM060K_128 0x0128 + #define QUECTEL_PRODUCT_EG91 0x0191 + #define QUECTEL_PRODUCT_EG95 0x0195 + #define QUECTEL_PRODUCT_BG96 0x0296 +@@ -268,6 +269,7 @@ static void option_instat_callback(struct urb *urb); + #define QUECTEL_PRODUCT_RM520N 0x0801 + #define QUECTEL_PRODUCT_EC200U 0x0901 + #define QUECTEL_PRODUCT_EC200S_CN 0x6002 ++#define QUECTEL_PRODUCT_EC200A 0x6005 + #define QUECTEL_PRODUCT_EM061K_LWW 0x6008 + #define QUECTEL_PRODUCT_EM061K_LCN 0x6009 + #define QUECTEL_PRODUCT_EC200T 0x6026 +@@ -1197,6 +1199,9 @@ static const struct usb_device_id option_ids[] = { + { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM060K, 0xff, 0x00, 0x40) }, + { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM060K, 0xff, 0xff, 0x30) }, + { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM060K, 0xff, 0xff, 0x40) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM060K_128, 0xff, 0xff, 0x30) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM060K_128, 0xff, 0x00, 0x40) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM060K_128, 0xff, 0xff, 0x40) }, + { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM061K_LCN, 0xff, 0xff, 0x30) }, + { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM061K_LCN, 0xff, 0x00, 0x40) }, + { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM061K_LCN, 0xff, 0xff, 0x40) }, +@@ -1225,6 +1230,7 @@ static const struct usb_device_id option_ids[] = { + { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM520N, 0xff, 0, 0) }, + { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, 0x0900, 0xff, 0, 0), /* RM500U-CN */ + .driver_info = ZLP }, ++ { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC200A, 0xff, 0, 0) }, + { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC200U, 0xff, 0, 0) }, + { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC200S_CN, 0xff, 0, 0) }, + { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC200T, 0xff, 0, 0) }, +diff --git a/drivers/usb/serial/usb-serial-simple.c b/drivers/usb/serial/usb-serial-simple.c +index 4c6747889a194..24b8772a345e2 100644 +--- a/drivers/usb/serial/usb-serial-simple.c ++++ b/drivers/usb/serial/usb-serial-simple.c +@@ -38,16 +38,6 @@ static struct usb_serial_driver vendor##_device = { \ + { USB_DEVICE(0x0a21, 0x8001) } /* MMT-7305WW */ + DEVICE(carelink, CARELINK_IDS); + +-/* ZIO Motherboard USB driver */ +-#define ZIO_IDS() \ +- { USB_DEVICE(0x1CBE, 0x0103) } +-DEVICE(zio, ZIO_IDS); +- +-/* Funsoft Serial USB driver */ +-#define FUNSOFT_IDS() \ +- { USB_DEVICE(0x1404, 0xcddc) } +-DEVICE(funsoft, FUNSOFT_IDS); +- + /* Infineon Flashloader driver */ + #define FLASHLOADER_IDS() \ + { USB_DEVICE_INTERFACE_CLASS(0x058b, 0x0041, USB_CLASS_CDC_DATA) }, \ +@@ -55,6 +45,11 @@ DEVICE(funsoft, FUNSOFT_IDS); + { USB_DEVICE(0x8087, 0x0801) } + DEVICE(flashloader, FLASHLOADER_IDS); + ++/* Funsoft Serial USB driver */ ++#define FUNSOFT_IDS() \ ++ { USB_DEVICE(0x1404, 0xcddc) } ++DEVICE(funsoft, FUNSOFT_IDS); ++ + /* Google Serial USB SubClass */ + #define GOOGLE_IDS() \ + { USB_VENDOR_AND_INTERFACE_INFO(0x18d1, \ +@@ -63,16 +58,21 @@ DEVICE(flashloader, FLASHLOADER_IDS); + 0x01) } + DEVICE(google, GOOGLE_IDS); + ++/* HP4x (48/49) Generic Serial driver */ ++#define HP4X_IDS() \ ++ { USB_DEVICE(0x03f0, 0x0121) } ++DEVICE(hp4x, HP4X_IDS); ++ ++/* KAUFMANN RKS+CAN VCP */ ++#define KAUFMANN_IDS() \ ++ { USB_DEVICE(0x16d0, 0x0870) } ++DEVICE(kaufmann, KAUFMANN_IDS); ++ + /* Libtransistor USB console */ + #define LIBTRANSISTOR_IDS() \ + { USB_DEVICE(0x1209, 0x8b00) } + DEVICE(libtransistor, LIBTRANSISTOR_IDS); + +-/* ViVOpay USB Serial Driver */ +-#define VIVOPAY_IDS() \ +- { USB_DEVICE(0x1d5f, 0x1004) } /* ViVOpay 8800 */ +-DEVICE(vivopay, VIVOPAY_IDS); +- + /* Motorola USB Phone driver */ + #define MOTO_IDS() \ + { USB_DEVICE(0x05c6, 0x3197) }, /* unknown Motorola phone */ \ +@@ -101,10 +101,10 @@ DEVICE(nokia, NOKIA_IDS); + { USB_DEVICE(0x09d7, 0x0100) } /* NovAtel FlexPack GPS */ + DEVICE_N(novatel_gps, NOVATEL_IDS, 3); + +-/* HP4x (48/49) Generic Serial driver */ +-#define HP4X_IDS() \ +- { USB_DEVICE(0x03f0, 0x0121) } +-DEVICE(hp4x, HP4X_IDS); ++/* Siemens USB/MPI adapter */ ++#define SIEMENS_IDS() \ ++ { USB_DEVICE(0x908, 0x0004) } ++DEVICE(siemens_mpi, SIEMENS_IDS); + + /* Suunto ANT+ USB Driver */ + #define SUUNTO_IDS() \ +@@ -112,45 +112,52 @@ DEVICE(hp4x, HP4X_IDS); + { USB_DEVICE(0x0fcf, 0x1009) } /* Dynastream ANT USB-m Stick */ + DEVICE(suunto, SUUNTO_IDS); + +-/* Siemens USB/MPI adapter */ +-#define SIEMENS_IDS() \ +- { USB_DEVICE(0x908, 0x0004) } +-DEVICE(siemens_mpi, SIEMENS_IDS); ++/* ViVOpay USB Serial Driver */ ++#define VIVOPAY_IDS() \ ++ { USB_DEVICE(0x1d5f, 0x1004) } /* ViVOpay 8800 */ ++DEVICE(vivopay, VIVOPAY_IDS); ++ ++/* ZIO Motherboard USB driver */ ++#define ZIO_IDS() \ ++ { USB_DEVICE(0x1CBE, 0x0103) } ++DEVICE(zio, ZIO_IDS); + + /* All of the above structures mushed into two lists */ + static struct usb_serial_driver * const serial_drivers[] = { + &carelink_device, +- &zio_device, +- &funsoft_device, + &flashloader_device, ++ &funsoft_device, + &google_device, ++ &hp4x_device, ++ &kaufmann_device, + &libtransistor_device, +- &vivopay_device, + &moto_modem_device, + &motorola_tetra_device, + &nokia_device, + &novatel_gps_device, +- &hp4x_device, +- &suunto_device, + &siemens_mpi_device, ++ &suunto_device, ++ &vivopay_device, ++ &zio_device, + NULL + }; + + static const struct usb_device_id id_table[] = { + CARELINK_IDS(), +- ZIO_IDS(), +- FUNSOFT_IDS(), + FLASHLOADER_IDS(), ++ FUNSOFT_IDS(), + GOOGLE_IDS(), ++ HP4X_IDS(), ++ KAUFMANN_IDS(), + LIBTRANSISTOR_IDS(), +- VIVOPAY_IDS(), + MOTO_IDS(), + MOTOROLA_TETRA_IDS(), + NOKIA_IDS(), + NOVATEL_IDS(), +- HP4X_IDS(), +- SUUNTO_IDS(), + SIEMENS_IDS(), ++ SUUNTO_IDS(), ++ VIVOPAY_IDS(), ++ ZIO_IDS(), + { }, + }; + MODULE_DEVICE_TABLE(usb, id_table); +diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c +index 1420df997485a..608e41b61689c 100644 +--- a/fs/btrfs/ctree.c ++++ b/fs/btrfs/ctree.c +@@ -3589,6 +3589,8 @@ static noinline int split_node(struct btrfs_trans_handle *trans, + + ret = tree_mod_log_eb_copy(split, c, 0, mid, c_nritems - mid); + if (ret) { ++ btrfs_tree_unlock(split); ++ free_extent_buffer(split); + btrfs_abort_transaction(trans, ret); + return ret; + } +diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c +index 7e9d914369a02..d98cf8aba753b 100644 +--- a/fs/btrfs/disk-io.c ++++ b/fs/btrfs/disk-io.c +@@ -4106,6 +4106,11 @@ void close_ctree(struct btrfs_fs_info *fs_info) + ASSERT(list_empty(&fs_info->delayed_iputs)); + set_bit(BTRFS_FS_CLOSING_DONE, &fs_info->flags); + ++ if (btrfs_check_quota_leak(fs_info)) { ++ WARN_ON(IS_ENABLED(CONFIG_BTRFS_DEBUG)); ++ btrfs_err(fs_info, "qgroup reserved space leaked"); ++ } ++ + btrfs_free_qgroup_config(fs_info); + ASSERT(list_empty(&fs_info->delalloc_roots)); + +diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c +index 22f95a5a58fe1..1197dfdfebbf6 100644 +--- a/fs/btrfs/ioctl.c ++++ b/fs/btrfs/ioctl.c +@@ -4917,7 +4917,9 @@ static long btrfs_ioctl_qgroup_assign(struct file *file, void __user *arg) + } + + /* update qgroup status and info */ ++ mutex_lock(&fs_info->qgroup_ioctl_lock); + err = btrfs_run_qgroups(trans); ++ mutex_unlock(&fs_info->qgroup_ioctl_lock); + if (err < 0) + btrfs_handle_fs_error(fs_info, err, + "failed to update qgroup status and info"); +diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c +index db8f83ab55f63..a743404dce0ce 100644 +--- a/fs/btrfs/qgroup.c ++++ b/fs/btrfs/qgroup.c +@@ -504,6 +504,49 @@ out: + return ret < 0 ? ret : 0; + } + ++static u64 btrfs_qgroup_subvolid(u64 qgroupid) ++{ ++ return (qgroupid & ((1ULL << BTRFS_QGROUP_LEVEL_SHIFT) - 1)); ++} ++ ++/* ++ * Called in close_ctree() when quota is still enabled. This verifies we don't ++ * leak some reserved space. ++ * ++ * Return false if no reserved space is left. ++ * Return true if some reserved space is leaked. ++ */ ++bool btrfs_check_quota_leak(struct btrfs_fs_info *fs_info) ++{ ++ struct rb_node *node; ++ bool ret = false; ++ ++ if (!test_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags)) ++ return ret; ++ /* ++ * Since we're unmounting, there is no race and no need to grab qgroup ++ * lock. And here we don't go post-order to provide a more user ++ * friendly sorted result. ++ */ ++ for (node = rb_first(&fs_info->qgroup_tree); node; node = rb_next(node)) { ++ struct btrfs_qgroup *qgroup; ++ int i; ++ ++ qgroup = rb_entry(node, struct btrfs_qgroup, node); ++ for (i = 0; i < BTRFS_QGROUP_RSV_LAST; i++) { ++ if (qgroup->rsv.values[i]) { ++ ret = true; ++ btrfs_warn(fs_info, ++ "qgroup %llu/%llu has unreleased space, type %d rsv %llu", ++ btrfs_qgroup_level(qgroup->qgroupid), ++ btrfs_qgroup_subvolid(qgroup->qgroupid), ++ i, qgroup->rsv.values[i]); ++ } ++ } ++ } ++ return ret; ++} ++ + /* + * This is called from close_ctree() or open_ctree() or btrfs_quota_disable(), + * first two are in single-threaded paths.And for the third one, we have set +@@ -1121,12 +1164,23 @@ int btrfs_quota_disable(struct btrfs_fs_info *fs_info) + int ret = 0; + + /* +- * We need to have subvol_sem write locked, to prevent races between +- * concurrent tasks trying to disable quotas, because we will unlock +- * and relock qgroup_ioctl_lock across BTRFS_FS_QUOTA_ENABLED changes. ++ * We need to have subvol_sem write locked to prevent races with ++ * snapshot creation. + */ + lockdep_assert_held_write(&fs_info->subvol_sem); + ++ /* ++ * Lock the cleaner mutex to prevent races with concurrent relocation, ++ * because relocation may be building backrefs for blocks of the quota ++ * root while we are deleting the root. This is like dropping fs roots ++ * of deleted snapshots/subvolumes, we need the same protection. ++ * ++ * This also prevents races between concurrent tasks trying to disable ++ * quotas, because we will unlock and relock qgroup_ioctl_lock across ++ * BTRFS_FS_QUOTA_ENABLED changes. ++ */ ++ mutex_lock(&fs_info->cleaner_mutex); ++ + mutex_lock(&fs_info->qgroup_ioctl_lock); + if (!fs_info->quota_root) + goto out; +@@ -1208,6 +1262,7 @@ out: + btrfs_end_transaction(trans); + else if (trans) + ret = btrfs_end_transaction(trans); ++ mutex_unlock(&fs_info->cleaner_mutex); + + return ret; + } +@@ -1340,7 +1395,6 @@ int btrfs_add_qgroup_relation(struct btrfs_trans_handle *trans, u64 src, + u64 dst) + { + struct btrfs_fs_info *fs_info = trans->fs_info; +- struct btrfs_root *quota_root; + struct btrfs_qgroup *parent; + struct btrfs_qgroup *member; + struct btrfs_qgroup_list *list; +@@ -1356,9 +1410,8 @@ int btrfs_add_qgroup_relation(struct btrfs_trans_handle *trans, u64 src, + return -ENOMEM; + + mutex_lock(&fs_info->qgroup_ioctl_lock); +- quota_root = fs_info->quota_root; +- if (!quota_root) { +- ret = -EINVAL; ++ if (!fs_info->quota_root) { ++ ret = -ENOTCONN; + goto out; + } + member = find_qgroup_rb(fs_info, src); +@@ -1404,7 +1457,6 @@ static int __del_qgroup_relation(struct btrfs_trans_handle *trans, u64 src, + u64 dst) + { + struct btrfs_fs_info *fs_info = trans->fs_info; +- struct btrfs_root *quota_root; + struct btrfs_qgroup *parent; + struct btrfs_qgroup *member; + struct btrfs_qgroup_list *list; +@@ -1417,9 +1469,8 @@ static int __del_qgroup_relation(struct btrfs_trans_handle *trans, u64 src, + if (!tmp) + return -ENOMEM; + +- quota_root = fs_info->quota_root; +- if (!quota_root) { +- ret = -EINVAL; ++ if (!fs_info->quota_root) { ++ ret = -ENOTCONN; + goto out; + } + +@@ -1484,11 +1535,11 @@ int btrfs_create_qgroup(struct btrfs_trans_handle *trans, u64 qgroupid) + int ret = 0; + + mutex_lock(&fs_info->qgroup_ioctl_lock); +- quota_root = fs_info->quota_root; +- if (!quota_root) { +- ret = -EINVAL; ++ if (!fs_info->quota_root) { ++ ret = -ENOTCONN; + goto out; + } ++ quota_root = fs_info->quota_root; + qgroup = find_qgroup_rb(fs_info, qgroupid); + if (qgroup) { + ret = -EEXIST; +@@ -1513,15 +1564,13 @@ out: + int btrfs_remove_qgroup(struct btrfs_trans_handle *trans, u64 qgroupid) + { + struct btrfs_fs_info *fs_info = trans->fs_info; +- struct btrfs_root *quota_root; + struct btrfs_qgroup *qgroup; + struct btrfs_qgroup_list *list; + int ret = 0; + + mutex_lock(&fs_info->qgroup_ioctl_lock); +- quota_root = fs_info->quota_root; +- if (!quota_root) { +- ret = -EINVAL; ++ if (!fs_info->quota_root) { ++ ret = -ENOTCONN; + goto out; + } + +@@ -1562,7 +1611,6 @@ int btrfs_limit_qgroup(struct btrfs_trans_handle *trans, u64 qgroupid, + struct btrfs_qgroup_limit *limit) + { + struct btrfs_fs_info *fs_info = trans->fs_info; +- struct btrfs_root *quota_root; + struct btrfs_qgroup *qgroup; + int ret = 0; + /* Sometimes we would want to clear the limit on this qgroup. +@@ -1572,9 +1620,8 @@ int btrfs_limit_qgroup(struct btrfs_trans_handle *trans, u64 qgroupid, + const u64 CLEAR_VALUE = -1; + + mutex_lock(&fs_info->qgroup_ioctl_lock); +- quota_root = fs_info->quota_root; +- if (!quota_root) { +- ret = -EINVAL; ++ if (!fs_info->quota_root) { ++ ret = -ENOTCONN; + goto out; + } + +@@ -2674,15 +2721,23 @@ cleanup: + } + + /* +- * called from commit_transaction. Writes all changed qgroups to disk. ++ * Writes all changed qgroups to disk. ++ * Called by the transaction commit path and the qgroup assign ioctl. + */ + int btrfs_run_qgroups(struct btrfs_trans_handle *trans) + { + struct btrfs_fs_info *fs_info = trans->fs_info; +- struct btrfs_root *quota_root = fs_info->quota_root; + int ret = 0; + +- if (!quota_root) ++ /* ++ * In case we are called from the qgroup assign ioctl, assert that we ++ * are holding the qgroup_ioctl_lock, otherwise we can race with a quota ++ * disable operation (ioctl) and access a freed quota root. ++ */ ++ if (trans->transaction->state != TRANS_STATE_COMMIT_DOING) ++ lockdep_assert_held(&fs_info->qgroup_ioctl_lock); ++ ++ if (!fs_info->quota_root) + return ret; + + spin_lock(&fs_info->qgroup_lock); +@@ -2945,7 +3000,6 @@ static bool qgroup_check_limits(const struct btrfs_qgroup *qg, u64 num_bytes) + static int qgroup_reserve(struct btrfs_root *root, u64 num_bytes, bool enforce, + enum btrfs_qgroup_rsv_type type) + { +- struct btrfs_root *quota_root; + struct btrfs_qgroup *qgroup; + struct btrfs_fs_info *fs_info = root->fs_info; + u64 ref_root = root->root_key.objectid; +@@ -2964,8 +3018,7 @@ static int qgroup_reserve(struct btrfs_root *root, u64 num_bytes, bool enforce, + enforce = false; + + spin_lock(&fs_info->qgroup_lock); +- quota_root = fs_info->quota_root; +- if (!quota_root) ++ if (!fs_info->quota_root) + goto out; + + qgroup = find_qgroup_rb(fs_info, ref_root); +@@ -3032,7 +3085,6 @@ void btrfs_qgroup_free_refroot(struct btrfs_fs_info *fs_info, + u64 ref_root, u64 num_bytes, + enum btrfs_qgroup_rsv_type type) + { +- struct btrfs_root *quota_root; + struct btrfs_qgroup *qgroup; + struct ulist_node *unode; + struct ulist_iterator uiter; +@@ -3050,8 +3102,7 @@ void btrfs_qgroup_free_refroot(struct btrfs_fs_info *fs_info, + } + spin_lock(&fs_info->qgroup_lock); + +- quota_root = fs_info->quota_root; +- if (!quota_root) ++ if (!fs_info->quota_root) + goto out; + + qgroup = find_qgroup_rb(fs_info, ref_root); +@@ -3942,7 +3993,6 @@ void __btrfs_qgroup_free_meta(struct btrfs_root *root, int num_bytes, + static void qgroup_convert_meta(struct btrfs_fs_info *fs_info, u64 ref_root, + int num_bytes) + { +- struct btrfs_root *quota_root = fs_info->quota_root; + struct btrfs_qgroup *qgroup; + struct ulist_node *unode; + struct ulist_iterator uiter; +@@ -3950,7 +4000,7 @@ static void qgroup_convert_meta(struct btrfs_fs_info *fs_info, u64 ref_root, + + if (num_bytes == 0) + return; +- if (!quota_root) ++ if (!fs_info->quota_root) + return; + + spin_lock(&fs_info->qgroup_lock); +diff --git a/fs/btrfs/qgroup.h b/fs/btrfs/qgroup.h +index 0a2659685ad65..94bdfb89505e8 100644 +--- a/fs/btrfs/qgroup.h ++++ b/fs/btrfs/qgroup.h +@@ -416,5 +416,6 @@ int btrfs_qgroup_add_swapped_blocks(struct btrfs_trans_handle *trans, + int btrfs_qgroup_trace_subtree_after_cow(struct btrfs_trans_handle *trans, + struct btrfs_root *root, struct extent_buffer *eb); + void btrfs_qgroup_destroy_extent_records(struct btrfs_transaction *trans); ++bool btrfs_check_quota_leak(struct btrfs_fs_info *fs_info); + + #endif +diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c +index e6cb95b81787f..f2e348d22dc1e 100644 +--- a/fs/btrfs/transaction.c ++++ b/fs/btrfs/transaction.c +@@ -706,8 +706,13 @@ btrfs_attach_transaction_barrier(struct btrfs_root *root) + + trans = start_transaction(root, 0, TRANS_ATTACH, + BTRFS_RESERVE_NO_FLUSH, true); +- if (trans == ERR_PTR(-ENOENT)) +- btrfs_wait_for_commit(root->fs_info, 0); ++ if (trans == ERR_PTR(-ENOENT)) { ++ int ret; ++ ++ ret = btrfs_wait_for_commit(root->fs_info, 0); ++ if (ret) ++ return ERR_PTR(ret); ++ } + + return trans; + } +@@ -771,6 +776,7 @@ int btrfs_wait_for_commit(struct btrfs_fs_info *fs_info, u64 transid) + } + + wait_for_commit(cur_trans); ++ ret = cur_trans->aborted; + btrfs_put_transaction(cur_trans); + out: + return ret; +diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c +index 243e246cb5046..4e88cb9907230 100644 +--- a/fs/ceph/caps.c ++++ b/fs/ceph/caps.c +@@ -2790,7 +2790,19 @@ int ceph_get_caps(struct file *filp, int need, int want, + if (ret == -EAGAIN) + continue; + if (!ret) { ++ struct ceph_mds_client *mdsc = fsc->mdsc; ++ struct cap_wait cw; + DEFINE_WAIT_FUNC(wait, woken_wake_function); ++ ++ cw.ino = inode->i_ino; ++ cw.tgid = current->tgid; ++ cw.need = need; ++ cw.want = want; ++ ++ spin_lock(&mdsc->caps_list_lock); ++ list_add(&cw.list, &mdsc->cap_wait_list); ++ spin_unlock(&mdsc->caps_list_lock); ++ + add_wait_queue(&ci->i_cap_wq, &wait); + + flags |= NON_BLOCKING; +@@ -2804,6 +2816,11 @@ int ceph_get_caps(struct file *filp, int need, int want, + } + + remove_wait_queue(&ci->i_cap_wq, &wait); ++ ++ spin_lock(&mdsc->caps_list_lock); ++ list_del(&cw.list); ++ spin_unlock(&mdsc->caps_list_lock); ++ + if (ret == -EAGAIN) + continue; + } +diff --git a/fs/ceph/debugfs.c b/fs/ceph/debugfs.c +index facb387c27356..c281f32b54f7b 100644 +--- a/fs/ceph/debugfs.c ++++ b/fs/ceph/debugfs.c +@@ -139,6 +139,7 @@ static int caps_show(struct seq_file *s, void *p) + struct ceph_fs_client *fsc = s->private; + struct ceph_mds_client *mdsc = fsc->mdsc; + int total, avail, used, reserved, min, i; ++ struct cap_wait *cw; + + ceph_reservation_status(fsc, &total, &avail, &used, &reserved, &min); + seq_printf(s, "total\t\t%d\n" +@@ -166,6 +167,18 @@ static int caps_show(struct seq_file *s, void *p) + } + mutex_unlock(&mdsc->mutex); + ++ seq_printf(s, "\n\nWaiters:\n--------\n"); ++ seq_printf(s, "tgid ino need want\n"); ++ seq_printf(s, "-----------------------------------------------------\n"); ++ ++ spin_lock(&mdsc->caps_list_lock); ++ list_for_each_entry(cw, &mdsc->cap_wait_list, list) { ++ seq_printf(s, "%-13d0x%-17lx%-17s%-17s\n", cw->tgid, cw->ino, ++ ceph_cap_string(cw->need), ++ ceph_cap_string(cw->want)); ++ } ++ spin_unlock(&mdsc->caps_list_lock); ++ + return 0; + } + +diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c +index 3bf81fe5f10a3..f7acf9680c9b6 100644 +--- a/fs/ceph/mds_client.c ++++ b/fs/ceph/mds_client.c +@@ -4074,7 +4074,7 @@ static void delayed_work(struct work_struct *work) + + dout("mdsc delayed_work\n"); + +- if (mdsc->stopping) ++ if (mdsc->stopping >= CEPH_MDSC_STOPPING_FLUSHED) + return; + + mutex_lock(&mdsc->mutex); +@@ -4174,6 +4174,7 @@ int ceph_mdsc_init(struct ceph_fs_client *fsc) + INIT_DELAYED_WORK(&mdsc->delayed_work, delayed_work); + mdsc->last_renew_caps = jiffies; + INIT_LIST_HEAD(&mdsc->cap_delay_list); ++ INIT_LIST_HEAD(&mdsc->cap_wait_list); + spin_lock_init(&mdsc->cap_delay_lock); + INIT_LIST_HEAD(&mdsc->snap_flush_list); + spin_lock_init(&mdsc->snap_flush_lock); +@@ -4245,7 +4246,7 @@ static void wait_requests(struct ceph_mds_client *mdsc) + void ceph_mdsc_pre_umount(struct ceph_mds_client *mdsc) + { + dout("pre_umount\n"); +- mdsc->stopping = 1; ++ mdsc->stopping = CEPH_MDSC_STOPPING_BEGIN; + + lock_unlock_sessions(mdsc); + ceph_flush_dirty_caps(mdsc); +diff --git a/fs/ceph/mds_client.h b/fs/ceph/mds_client.h +index 5cd131b41d84f..4fbbc33023c97 100644 +--- a/fs/ceph/mds_client.h ++++ b/fs/ceph/mds_client.h +@@ -340,6 +340,19 @@ struct ceph_quotarealm_inode { + struct inode *inode; + }; + ++struct cap_wait { ++ struct list_head list; ++ unsigned long ino; ++ pid_t tgid; ++ int need; ++ int want; ++}; ++ ++enum { ++ CEPH_MDSC_STOPPING_BEGIN = 1, ++ CEPH_MDSC_STOPPING_FLUSHED = 2, ++}; ++ + /* + * mds client state + */ +@@ -416,6 +429,7 @@ struct ceph_mds_client { + spinlock_t caps_list_lock; + struct list_head caps_list; /* unused (reserved or + unreserved) */ ++ struct list_head cap_wait_list; + int caps_total_count; /* total caps allocated */ + int caps_use_count; /* in use */ + int caps_use_max; /* max used caps */ +diff --git a/fs/ceph/super.c b/fs/ceph/super.c +index d40658d5e8089..0e38678d5adda 100644 +--- a/fs/ceph/super.c ++++ b/fs/ceph/super.c +@@ -1174,14 +1174,23 @@ out_final: + static void ceph_kill_sb(struct super_block *s) + { + struct ceph_fs_client *fsc = ceph_sb_to_client(s); +- dev_t dev = s->s_dev; + + dout("kill_sb %p\n", s); + + ceph_mdsc_pre_umount(fsc->mdsc); + flush_fs_workqueues(fsc); + +- generic_shutdown_super(s); ++ /* ++ * Though the kill_anon_super() will finally trigger the ++ * sync_filesystem() anyway, we still need to do it here ++ * and then bump the stage of shutdown to stop the work ++ * queue as earlier as possible. ++ */ ++ sync_filesystem(s); ++ ++ fsc->mdsc->stopping = CEPH_MDSC_STOPPING_FLUSHED; ++ ++ kill_anon_super(s); + + fsc->client->extra_mon_dispatch = NULL; + ceph_fs_debugfs_cleanup(fsc); +@@ -1189,7 +1198,6 @@ static void ceph_kill_sb(struct super_block *s) + ceph_fscache_unregister_fs(fsc); + + destroy_fs_client(fsc); +- free_anon_bdev(dev); + } + + static struct file_system_type ceph_fs_type = { +diff --git a/fs/dlm/plock.c b/fs/dlm/plock.c +index edce0b25cd90e..f3482e936cc25 100644 +--- a/fs/dlm/plock.c ++++ b/fs/dlm/plock.c +@@ -19,20 +19,20 @@ static struct list_head recv_list; + static wait_queue_head_t send_wq; + static wait_queue_head_t recv_wq; + +-struct plock_op { +- struct list_head list; +- int done; +- struct dlm_plock_info info; +- int (*callback)(struct file_lock *fl, int result); +-}; +- +-struct plock_xop { +- struct plock_op xop; ++struct plock_async_data { + void *fl; + void *file; + struct file_lock flc; ++ int (*callback)(struct file_lock *fl, int result); + }; + ++struct plock_op { ++ struct list_head list; ++ int done; ++ struct dlm_plock_info info; ++ /* if set indicates async handling */ ++ struct plock_async_data *data; ++}; + + static inline void set_version(struct dlm_plock_info *info) + { +@@ -58,6 +58,12 @@ static int check_version(struct dlm_plock_info *info) + return 0; + } + ++static void dlm_release_plock_op(struct plock_op *op) ++{ ++ kfree(op->data); ++ kfree(op); ++} ++ + static void send_op(struct plock_op *op) + { + set_version(&op->info); +@@ -101,22 +107,21 @@ static void do_unlock_close(struct dlm_ls *ls, u64 number, + int dlm_posix_lock(dlm_lockspace_t *lockspace, u64 number, struct file *file, + int cmd, struct file_lock *fl) + { ++ struct plock_async_data *op_data; + struct dlm_ls *ls; + struct plock_op *op; +- struct plock_xop *xop; + int rv; + + ls = dlm_find_lockspace_local(lockspace); + if (!ls) + return -EINVAL; + +- xop = kzalloc(sizeof(*xop), GFP_NOFS); +- if (!xop) { ++ op = kzalloc(sizeof(*op), GFP_NOFS); ++ if (!op) { + rv = -ENOMEM; + goto out; + } + +- op = &xop->xop; + op->info.optype = DLM_PLOCK_OP_LOCK; + op->info.pid = fl->fl_pid; + op->info.ex = (fl->fl_type == F_WRLCK); +@@ -125,35 +130,44 @@ int dlm_posix_lock(dlm_lockspace_t *lockspace, u64 number, struct file *file, + op->info.number = number; + op->info.start = fl->fl_start; + op->info.end = fl->fl_end; ++ /* async handling */ + if (fl->fl_lmops && fl->fl_lmops->lm_grant) { ++ op_data = kzalloc(sizeof(*op_data), GFP_NOFS); ++ if (!op_data) { ++ dlm_release_plock_op(op); ++ rv = -ENOMEM; ++ goto out; ++ } ++ + /* fl_owner is lockd which doesn't distinguish + processes on the nfs client */ + op->info.owner = (__u64) fl->fl_pid; +- op->callback = fl->fl_lmops->lm_grant; +- locks_init_lock(&xop->flc); +- locks_copy_lock(&xop->flc, fl); +- xop->fl = fl; +- xop->file = file; ++ op_data->callback = fl->fl_lmops->lm_grant; ++ locks_init_lock(&op_data->flc); ++ locks_copy_lock(&op_data->flc, fl); ++ op_data->fl = fl; ++ op_data->file = file; ++ ++ op->data = op_data; ++ ++ send_op(op); ++ rv = FILE_LOCK_DEFERRED; ++ goto out; + } else { + op->info.owner = (__u64)(long) fl->fl_owner; + } + + send_op(op); + +- if (!op->callback) { +- rv = wait_event_interruptible(recv_wq, (op->done != 0)); +- if (rv == -ERESTARTSYS) { +- log_debug(ls, "dlm_posix_lock: wait killed %llx", +- (unsigned long long)number); +- spin_lock(&ops_lock); +- list_del(&op->list); +- spin_unlock(&ops_lock); +- kfree(xop); +- do_unlock_close(ls, number, file, fl); +- goto out; +- } +- } else { +- rv = FILE_LOCK_DEFERRED; ++ rv = wait_event_killable(recv_wq, (op->done != 0)); ++ if (rv == -ERESTARTSYS) { ++ log_debug(ls, "%s: wait killed %llx", __func__, ++ (unsigned long long)number); ++ spin_lock(&ops_lock); ++ list_del(&op->list); ++ spin_unlock(&ops_lock); ++ dlm_release_plock_op(op); ++ do_unlock_close(ls, number, file, fl); + goto out; + } + +@@ -173,7 +187,7 @@ int dlm_posix_lock(dlm_lockspace_t *lockspace, u64 number, struct file *file, + (unsigned long long)number); + } + +- kfree(xop); ++ dlm_release_plock_op(op); + out: + dlm_put_lockspace(ls); + return rv; +@@ -183,11 +197,11 @@ EXPORT_SYMBOL_GPL(dlm_posix_lock); + /* Returns failure iff a successful lock operation should be canceled */ + static int dlm_plock_callback(struct plock_op *op) + { ++ struct plock_async_data *op_data = op->data; + struct file *file; + struct file_lock *fl; + struct file_lock *flc; + int (*notify)(struct file_lock *fl, int result) = NULL; +- struct plock_xop *xop = (struct plock_xop *)op; + int rv = 0; + + spin_lock(&ops_lock); +@@ -199,10 +213,10 @@ static int dlm_plock_callback(struct plock_op *op) + spin_unlock(&ops_lock); + + /* check if the following 2 are still valid or make a copy */ +- file = xop->file; +- flc = &xop->flc; +- fl = xop->fl; +- notify = op->callback; ++ file = op_data->file; ++ flc = &op_data->flc; ++ fl = op_data->fl; ++ notify = op_data->callback; + + if (op->info.rv) { + notify(fl, op->info.rv); +@@ -233,7 +247,7 @@ static int dlm_plock_callback(struct plock_op *op) + } + + out: +- kfree(xop); ++ dlm_release_plock_op(op); + return rv; + } + +@@ -303,7 +317,7 @@ int dlm_posix_unlock(dlm_lockspace_t *lockspace, u64 number, struct file *file, + rv = 0; + + out_free: +- kfree(op); ++ dlm_release_plock_op(op); + out: + dlm_put_lockspace(ls); + fl->fl_flags = fl_flags; +@@ -371,7 +385,7 @@ int dlm_posix_get(dlm_lockspace_t *lockspace, u64 number, struct file *file, + rv = 0; + } + +- kfree(op); ++ dlm_release_plock_op(op); + out: + dlm_put_lockspace(ls); + return rv; +@@ -407,7 +421,7 @@ static ssize_t dev_read(struct file *file, char __user *u, size_t count, + (the process did not make an unlock call). */ + + if (op->info.flags & DLM_PLOCK_FL_CLOSE) +- kfree(op); ++ dlm_release_plock_op(op); + + if (copy_to_user(u, &info, sizeof(info))) + return -EFAULT; +@@ -439,7 +453,7 @@ static ssize_t dev_write(struct file *file, const char __user *u, size_t count, + op->info.owner == info.owner) { + list_del_init(&op->list); + memcpy(&op->info, &info, sizeof(info)); +- if (op->callback) ++ if (op->data) + do_callback = 1; + else + op->done = 1; +diff --git a/fs/ext2/ext2.h b/fs/ext2/ext2.h +index a89b43d759052..94e39a28bee2e 100644 +--- a/fs/ext2/ext2.h ++++ b/fs/ext2/ext2.h +@@ -68,10 +68,7 @@ struct mb_cache; + * second extended-fs super-block data in memory + */ + struct ext2_sb_info { +- unsigned long s_frag_size; /* Size of a fragment in bytes */ +- unsigned long s_frags_per_block;/* Number of fragments per block */ + unsigned long s_inodes_per_block;/* Number of inodes per block */ +- unsigned long s_frags_per_group;/* Number of fragments in a group */ + unsigned long s_blocks_per_group;/* Number of blocks in a group */ + unsigned long s_inodes_per_group;/* Number of inodes in a group */ + unsigned long s_itb_per_group; /* Number of inode table blocks per group */ +@@ -185,15 +182,6 @@ static inline struct ext2_sb_info *EXT2_SB(struct super_block *sb) + #define EXT2_INODE_SIZE(s) (EXT2_SB(s)->s_inode_size) + #define EXT2_FIRST_INO(s) (EXT2_SB(s)->s_first_ino) + +-/* +- * Macro-instructions used to manage fragments +- */ +-#define EXT2_MIN_FRAG_SIZE 1024 +-#define EXT2_MAX_FRAG_SIZE 4096 +-#define EXT2_MIN_FRAG_LOG_SIZE 10 +-#define EXT2_FRAG_SIZE(s) (EXT2_SB(s)->s_frag_size) +-#define EXT2_FRAGS_PER_BLOCK(s) (EXT2_SB(s)->s_frags_per_block) +- + /* + * Structure of a blocks group descriptor + */ +diff --git a/fs/ext2/super.c b/fs/ext2/super.c +index 6e8e47871fa26..a787f50732b87 100644 +--- a/fs/ext2/super.c ++++ b/fs/ext2/super.c +@@ -681,10 +681,9 @@ static int ext2_setup_super (struct super_block * sb, + es->s_max_mnt_count = cpu_to_le16(EXT2_DFL_MAX_MNT_COUNT); + le16_add_cpu(&es->s_mnt_count, 1); + if (test_opt (sb, DEBUG)) +- ext2_msg(sb, KERN_INFO, "%s, %s, bs=%lu, fs=%lu, gc=%lu, " ++ ext2_msg(sb, KERN_INFO, "%s, %s, bs=%lu, gc=%lu, " + "bpg=%lu, ipg=%lu, mo=%04lx]", + EXT2FS_VERSION, EXT2FS_DATE, sb->s_blocksize, +- sbi->s_frag_size, + sbi->s_groups_count, + EXT2_BLOCKS_PER_GROUP(sb), + EXT2_INODES_PER_GROUP(sb), +@@ -1031,14 +1030,7 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent) + } + } + +- sbi->s_frag_size = EXT2_MIN_FRAG_SIZE << +- le32_to_cpu(es->s_log_frag_size); +- if (sbi->s_frag_size == 0) +- goto cantfind_ext2; +- sbi->s_frags_per_block = sb->s_blocksize / sbi->s_frag_size; +- + sbi->s_blocks_per_group = le32_to_cpu(es->s_blocks_per_group); +- sbi->s_frags_per_group = le32_to_cpu(es->s_frags_per_group); + sbi->s_inodes_per_group = le32_to_cpu(es->s_inodes_per_group); + + sbi->s_inodes_per_block = sb->s_blocksize / EXT2_INODE_SIZE(sb); +@@ -1064,11 +1056,10 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent) + goto failed_mount; + } + +- if (sb->s_blocksize != sbi->s_frag_size) { ++ if (es->s_log_frag_size != es->s_log_block_size) { + ext2_msg(sb, KERN_ERR, +- "error: fragsize %lu != blocksize %lu" +- "(not supported yet)", +- sbi->s_frag_size, sb->s_blocksize); ++ "error: fragsize log %u != blocksize log %u", ++ le32_to_cpu(es->s_log_frag_size), sb->s_blocksize_bits); + goto failed_mount; + } + +@@ -1078,12 +1069,6 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent) + sbi->s_blocks_per_group); + goto failed_mount; + } +- if (sbi->s_frags_per_group > sb->s_blocksize * 8) { +- ext2_msg(sb, KERN_ERR, +- "error: #fragments per group too big: %lu", +- sbi->s_frags_per_group); +- goto failed_mount; +- } + if (sbi->s_inodes_per_group < sbi->s_inodes_per_block || + sbi->s_inodes_per_group > sb->s_blocksize * 8) { + ext2_msg(sb, KERN_ERR, +diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h +index 9d86cf3a09bf7..604fef3b2ddf4 100644 +--- a/fs/ext4/ext4.h ++++ b/fs/ext4/ext4.h +@@ -1441,7 +1441,7 @@ struct ext4_sb_info { + unsigned long s_commit_interval; + u32 s_max_batch_time; + u32 s_min_batch_time; +- struct block_device *journal_bdev; ++ struct block_device *s_journal_bdev; + #ifdef CONFIG_QUOTA + /* Names of quota files with journalled quota */ + char __rcu *s_qf_names[EXT4_MAXQUOTAS]; +diff --git a/fs/ext4/fsmap.c b/fs/ext4/fsmap.c +index d1ef651948d7e..d18c4cd4c63ff 100644 +--- a/fs/ext4/fsmap.c ++++ b/fs/ext4/fsmap.c +@@ -576,8 +576,8 @@ static bool ext4_getfsmap_is_valid_device(struct super_block *sb, + if (fm->fmr_device == 0 || fm->fmr_device == UINT_MAX || + fm->fmr_device == new_encode_dev(sb->s_bdev->bd_dev)) + return true; +- if (EXT4_SB(sb)->journal_bdev && +- fm->fmr_device == new_encode_dev(EXT4_SB(sb)->journal_bdev->bd_dev)) ++ if (EXT4_SB(sb)->s_journal_bdev && ++ fm->fmr_device == new_encode_dev(EXT4_SB(sb)->s_journal_bdev->bd_dev)) + return true; + return false; + } +@@ -647,9 +647,9 @@ int ext4_getfsmap(struct super_block *sb, struct ext4_fsmap_head *head, + memset(handlers, 0, sizeof(handlers)); + handlers[0].gfd_dev = new_encode_dev(sb->s_bdev->bd_dev); + handlers[0].gfd_fn = ext4_getfsmap_datadev; +- if (EXT4_SB(sb)->journal_bdev) { ++ if (EXT4_SB(sb)->s_journal_bdev) { + handlers[1].gfd_dev = new_encode_dev( +- EXT4_SB(sb)->journal_bdev->bd_dev); ++ EXT4_SB(sb)->s_journal_bdev->bd_dev); + handlers[1].gfd_fn = ext4_getfsmap_logdev; + } + +diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c +index 306ad7d0003bb..ae47505964c4b 100644 +--- a/fs/ext4/ioctl.c ++++ b/fs/ext4/ioctl.c +@@ -573,6 +573,7 @@ static int ext4_shutdown(struct super_block *sb, unsigned long arg) + { + struct ext4_sb_info *sbi = EXT4_SB(sb); + __u32 flags; ++ struct super_block *ret; + + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; +@@ -591,7 +592,9 @@ static int ext4_shutdown(struct super_block *sb, unsigned long arg) + + switch (flags) { + case EXT4_GOING_FLAGS_DEFAULT: +- freeze_bdev(sb->s_bdev); ++ ret = freeze_bdev(sb->s_bdev); ++ if (IS_ERR(ret)) ++ return PTR_ERR(ret); + set_bit(EXT4_FLAGS_SHUTDOWN, &sbi->s_ext4_flags); + thaw_bdev(sb->s_bdev, sb); + break; +diff --git a/fs/ext4/super.c b/fs/ext4/super.c +index 9bbd525086562..8ad3de7846c54 100644 +--- a/fs/ext4/super.c ++++ b/fs/ext4/super.c +@@ -906,10 +906,16 @@ static void ext4_blkdev_put(struct block_device *bdev) + static void ext4_blkdev_remove(struct ext4_sb_info *sbi) + { + struct block_device *bdev; +- bdev = sbi->journal_bdev; ++ bdev = sbi->s_journal_bdev; + if (bdev) { ++ /* ++ * Invalidate the journal device's buffers. We don't want them ++ * floating about in memory - the physical journal device may ++ * hotswapped, and it breaks the `ro-after' testing code. ++ */ ++ invalidate_bdev(bdev); + ext4_blkdev_put(bdev); +- sbi->journal_bdev = NULL; ++ sbi->s_journal_bdev = NULL; + } + } + +@@ -1034,14 +1040,8 @@ static void ext4_put_super(struct super_block *sb) + + sync_blockdev(sb->s_bdev); + invalidate_bdev(sb->s_bdev); +- if (sbi->journal_bdev && sbi->journal_bdev != sb->s_bdev) { +- /* +- * Invalidate the journal device's buffers. We don't want them +- * floating about in memory - the physical journal device may +- * hotswapped, and it breaks the `ro-after' testing code. +- */ +- sync_blockdev(sbi->journal_bdev); +- invalidate_bdev(sbi->journal_bdev); ++ if (sbi->s_journal_bdev && sbi->s_journal_bdev != sb->s_bdev) { ++ sync_blockdev(sbi->s_journal_bdev); + ext4_blkdev_remove(sbi); + } + +@@ -3582,7 +3582,7 @@ int ext4_calculate_overhead(struct super_block *sb) + * Add the internal journal blocks whether the journal has been + * loaded or not + */ +- if (sbi->s_journal && !sbi->journal_bdev) ++ if (sbi->s_journal && !sbi->s_journal_bdev) + overhead += EXT4_NUM_B2C(sbi, sbi->s_journal->j_maxlen); + else if (ext4_has_feature_journal(sb) && !sbi->s_journal && j_inum) { + /* j_inum for internal journal is non-zero */ +@@ -4777,6 +4777,7 @@ failed_mount: + ext4_blkdev_remove(sbi); + brelse(bh); + out_fail: ++ invalidate_bdev(sb->s_bdev); + sb->s_fs_info = NULL; + kfree(sbi->s_blockgroup_lock); + out_free_base: +@@ -4952,7 +4953,7 @@ static journal_t *ext4_get_dev_journal(struct super_block *sb, + be32_to_cpu(journal->j_superblock->s_nr_users)); + goto out_journal; + } +- EXT4_SB(sb)->journal_bdev = bdev; ++ EXT4_SB(sb)->s_journal_bdev = bdev; + ext4_init_journal_params(sb, journal); + return journal; + +diff --git a/fs/jbd2/checkpoint.c b/fs/jbd2/checkpoint.c +index 5ef99b9ec8be7..edb17822f8e6b 100644 +--- a/fs/jbd2/checkpoint.c ++++ b/fs/jbd2/checkpoint.c +@@ -57,28 +57,6 @@ static inline void __buffer_unlink(struct journal_head *jh) + } + } + +-/* +- * Move a buffer from the checkpoint list to the checkpoint io list +- * +- * Called with j_list_lock held +- */ +-static inline void __buffer_relink_io(struct journal_head *jh) +-{ +- transaction_t *transaction = jh->b_cp_transaction; +- +- __buffer_unlink_first(jh); +- +- if (!transaction->t_checkpoint_io_list) { +- jh->b_cpnext = jh->b_cpprev = jh; +- } else { +- jh->b_cpnext = transaction->t_checkpoint_io_list; +- jh->b_cpprev = transaction->t_checkpoint_io_list->b_cpprev; +- jh->b_cpprev->b_cpnext = jh; +- jh->b_cpnext->b_cpprev = jh; +- } +- transaction->t_checkpoint_io_list = jh; +-} +- + /* + * Try to release a checkpointed buffer from its transaction. + * Returns 1 if we released it and 2 if we also released the +@@ -91,8 +69,7 @@ static int __try_to_free_cp_buf(struct journal_head *jh) + int ret = 0; + struct buffer_head *bh = jh2bh(jh); + +- if (jh->b_transaction == NULL && !buffer_locked(bh) && +- !buffer_dirty(bh) && !buffer_write_io_error(bh)) { ++ if (!jh->b_transaction && !buffer_locked(bh) && !buffer_dirty(bh)) { + JBUFFER_TRACE(jh, "remove from checkpoint list"); + ret = __jbd2_journal_remove_checkpoint(jh) + 1; + } +@@ -191,6 +168,7 @@ __flush_batch(journal_t *journal, int *batch_count) + struct buffer_head *bh = journal->j_chkpt_bhs[i]; + BUFFER_TRACE(bh, "brelse"); + __brelse(bh); ++ journal->j_chkpt_bhs[i] = NULL; + } + *batch_count = 0; + } +@@ -228,7 +206,6 @@ int jbd2_log_do_checkpoint(journal_t *journal) + * OK, we need to start writing disk blocks. Take one transaction + * and write it. + */ +- result = 0; + spin_lock(&journal->j_list_lock); + if (!journal->j_checkpoint_transactions) + goto out; +@@ -251,15 +228,6 @@ restart: + jh = transaction->t_checkpoint_list; + bh = jh2bh(jh); + +- if (buffer_locked(bh)) { +- get_bh(bh); +- spin_unlock(&journal->j_list_lock); +- wait_on_buffer(bh); +- /* the journal_head may have gone by now */ +- BUFFER_TRACE(bh, "brelse"); +- __brelse(bh); +- goto retry; +- } + if (jh->b_transaction != NULL) { + transaction_t *t = jh->b_transaction; + tid_t tid = t->t_tid; +@@ -294,32 +262,50 @@ restart: + spin_lock(&journal->j_list_lock); + goto restart; + } +- if (!buffer_dirty(bh)) { +- if (unlikely(buffer_write_io_error(bh)) && !result) +- result = -EIO; ++ if (!trylock_buffer(bh)) { ++ /* ++ * The buffer is locked, it may be writing back, or ++ * flushing out in the last couple of cycles, or ++ * re-adding into a new transaction, need to check ++ * it again until it's unlocked. ++ */ ++ get_bh(bh); ++ spin_unlock(&journal->j_list_lock); ++ wait_on_buffer(bh); ++ /* the journal_head may have gone by now */ ++ BUFFER_TRACE(bh, "brelse"); ++ __brelse(bh); ++ goto retry; ++ } else if (!buffer_dirty(bh)) { ++ unlock_buffer(bh); + BUFFER_TRACE(bh, "remove from checkpoint"); +- if (__jbd2_journal_remove_checkpoint(jh)) +- /* The transaction was released; we're done */ ++ /* ++ * If the transaction was released or the checkpoint ++ * list was empty, we're done. ++ */ ++ if (__jbd2_journal_remove_checkpoint(jh) || ++ !transaction->t_checkpoint_list) + goto out; +- continue; ++ } else { ++ unlock_buffer(bh); ++ /* ++ * We are about to write the buffer, it could be ++ * raced by some other transaction shrink or buffer ++ * re-log logic once we release the j_list_lock, ++ * leave it on the checkpoint list and check status ++ * again to make sure it's clean. ++ */ ++ BUFFER_TRACE(bh, "queue"); ++ get_bh(bh); ++ J_ASSERT_BH(bh, !buffer_jwrite(bh)); ++ journal->j_chkpt_bhs[batch_count++] = bh; ++ transaction->t_chp_stats.cs_written++; ++ transaction->t_checkpoint_list = jh->b_cpnext; + } +- /* +- * Important: we are about to write the buffer, and +- * possibly block, while still holding the journal +- * lock. We cannot afford to let the transaction +- * logic start messing around with this buffer before +- * we write it to disk, as that would break +- * recoverability. +- */ +- BUFFER_TRACE(bh, "queue"); +- get_bh(bh); +- J_ASSERT_BH(bh, !buffer_jwrite(bh)); +- journal->j_chkpt_bhs[batch_count++] = bh; +- __buffer_relink_io(jh); +- transaction->t_chp_stats.cs_written++; ++ + if ((batch_count == JBD2_NR_BATCH) || +- need_resched() || +- spin_needbreak(&journal->j_list_lock)) ++ need_resched() || spin_needbreak(&journal->j_list_lock) || ++ jh2bh(transaction->t_checkpoint_list) == journal->j_chkpt_bhs[0]) + goto unlock_and_flush; + } + +@@ -333,46 +319,9 @@ restart: + goto restart; + } + +- /* +- * Now we issued all of the transaction's buffers, let's deal +- * with the buffers that are out for I/O. +- */ +-restart2: +- /* Did somebody clean up the transaction in the meanwhile? */ +- if (journal->j_checkpoint_transactions != transaction || +- transaction->t_tid != this_tid) +- goto out; +- +- while (transaction->t_checkpoint_io_list) { +- jh = transaction->t_checkpoint_io_list; +- bh = jh2bh(jh); +- if (buffer_locked(bh)) { +- get_bh(bh); +- spin_unlock(&journal->j_list_lock); +- wait_on_buffer(bh); +- /* the journal_head may have gone by now */ +- BUFFER_TRACE(bh, "brelse"); +- __brelse(bh); +- spin_lock(&journal->j_list_lock); +- goto restart2; +- } +- if (unlikely(buffer_write_io_error(bh)) && !result) +- result = -EIO; +- +- /* +- * Now in whatever state the buffer currently is, we +- * know that it has been written out and so we can +- * drop it from the list +- */ +- if (__jbd2_journal_remove_checkpoint(jh)) +- break; +- } + out: + spin_unlock(&journal->j_list_lock); +- if (result < 0) +- jbd2_journal_abort(journal, result); +- else +- result = jbd2_cleanup_journal_tail(journal); ++ result = jbd2_cleanup_journal_tail(journal); + + return (result < 0) ? result : 0; + } +diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c +index b7c5819bfc411..eeebe64b7c543 100644 +--- a/fs/jbd2/journal.c ++++ b/fs/jbd2/journal.c +@@ -562,12 +562,14 @@ static int __jbd2_journal_force_commit(journal_t *journal) + } + + /** +- * Force and wait upon a commit if the calling process is not within +- * transaction. This is used for forcing out undo-protected data which contains +- * bitmaps, when the fs is running out of space. ++ * jbd2_journal_force_commit_nested - Force and wait upon a commit if the ++ * calling process is not within transaction. + * + * @journal: journal to force + * Returns true if progress was made. ++ * ++ * This is used for forcing out undo-protected data which contains ++ * bitmaps, when the fs is running out of space. + */ + int jbd2_journal_force_commit_nested(journal_t *journal) + { +@@ -578,7 +580,7 @@ int jbd2_journal_force_commit_nested(journal_t *journal) + } + + /** +- * int journal_force_commit() - force any uncommitted transactions ++ * jbd2_journal_force_commit() - force any uncommitted transactions + * @journal: journal to force + * + * Caller want unconditional commit. We can only force the running transaction +@@ -1266,7 +1268,7 @@ journal_t *jbd2_journal_init_inode(struct inode *inode) + * superblock as being NULL to prevent the journal destroy from writing + * back a bogus superblock. + */ +-static void journal_fail_superblock (journal_t *journal) ++static void journal_fail_superblock(journal_t *journal) + { + struct buffer_head *bh = journal->j_sb_buffer; + brelse(bh); +@@ -1634,7 +1636,7 @@ static int load_superblock(journal_t *journal) + + + /** +- * int jbd2_journal_load() - Read journal from disk. ++ * jbd2_journal_load() - Read journal from disk. + * @journal: Journal to act on. + * + * Given a journal_t structure which tells us which disk blocks contain +@@ -1704,7 +1706,7 @@ recovery_error: + } + + /** +- * void jbd2_journal_destroy() - Release a journal_t structure. ++ * jbd2_journal_destroy() - Release a journal_t structure. + * @journal: Journal to act on. + * + * Release a journal_t structure once it is no longer in use by the +@@ -1780,7 +1782,7 @@ int jbd2_journal_destroy(journal_t *journal) + + + /** +- *int jbd2_journal_check_used_features () - Check if features specified are used. ++ * jbd2_journal_check_used_features() - Check if features specified are used. + * @journal: Journal to check. + * @compat: bitmask of compatible features + * @ro: bitmask of features that force read-only mount +@@ -1790,7 +1792,7 @@ int jbd2_journal_destroy(journal_t *journal) + * features. Return true (non-zero) if it does. + **/ + +-int jbd2_journal_check_used_features (journal_t *journal, unsigned long compat, ++int jbd2_journal_check_used_features(journal_t *journal, unsigned long compat, + unsigned long ro, unsigned long incompat) + { + journal_superblock_t *sb; +@@ -1815,7 +1817,7 @@ int jbd2_journal_check_used_features (journal_t *journal, unsigned long compat, + } + + /** +- * int jbd2_journal_check_available_features() - Check feature set in journalling layer ++ * jbd2_journal_check_available_features() - Check feature set in journalling layer + * @journal: Journal to check. + * @compat: bitmask of compatible features + * @ro: bitmask of features that force read-only mount +@@ -1825,7 +1827,7 @@ int jbd2_journal_check_used_features (journal_t *journal, unsigned long compat, + * all of a given set of features on this journal. Return true + * (non-zero) if it can. */ + +-int jbd2_journal_check_available_features (journal_t *journal, unsigned long compat, ++int jbd2_journal_check_available_features(journal_t *journal, unsigned long compat, + unsigned long ro, unsigned long incompat) + { + if (!compat && !ro && !incompat) +@@ -1847,7 +1849,7 @@ int jbd2_journal_check_available_features (journal_t *journal, unsigned long com + } + + /** +- * int jbd2_journal_set_features () - Mark a given journal feature in the superblock ++ * jbd2_journal_set_features() - Mark a given journal feature in the superblock + * @journal: Journal to act on. + * @compat: bitmask of compatible features + * @ro: bitmask of features that force read-only mount +@@ -1858,7 +1860,7 @@ int jbd2_journal_check_available_features (journal_t *journal, unsigned long com + * + */ + +-int jbd2_journal_set_features (journal_t *journal, unsigned long compat, ++int jbd2_journal_set_features(journal_t *journal, unsigned long compat, + unsigned long ro, unsigned long incompat) + { + #define INCOMPAT_FEATURE_ON(f) \ +@@ -1929,7 +1931,7 @@ int jbd2_journal_set_features (journal_t *journal, unsigned long compat, + } + + /* +- * jbd2_journal_clear_features () - Clear a given journal feature in the ++ * jbd2_journal_clear_features() - Clear a given journal feature in the + * superblock + * @journal: Journal to act on. + * @compat: bitmask of compatible features +@@ -1956,7 +1958,7 @@ void jbd2_journal_clear_features(journal_t *journal, unsigned long compat, + EXPORT_SYMBOL(jbd2_journal_clear_features); + + /** +- * int jbd2_journal_flush () - Flush journal ++ * jbd2_journal_flush() - Flush journal + * @journal: Journal to act on. + * + * Flush all data for a given journal to disk and empty the journal. +@@ -2031,7 +2033,7 @@ out: + } + + /** +- * int jbd2_journal_wipe() - Wipe journal contents ++ * jbd2_journal_wipe() - Wipe journal contents + * @journal: Journal to act on. + * @write: flag (see below) + * +@@ -2072,7 +2074,7 @@ int jbd2_journal_wipe(journal_t *journal, int write) + } + + /** +- * void jbd2_journal_abort () - Shutdown the journal immediately. ++ * jbd2_journal_abort () - Shutdown the journal immediately. + * @journal: the journal to shutdown. + * @errno: an error number to record in the journal indicating + * the reason for the shutdown. +@@ -2158,7 +2160,7 @@ void jbd2_journal_abort(journal_t *journal, int errno) + } + + /** +- * int jbd2_journal_errno () - returns the journal's error state. ++ * jbd2_journal_errno() - returns the journal's error state. + * @journal: journal to examine. + * + * This is the errno number set with jbd2_journal_abort(), the last +@@ -2182,7 +2184,7 @@ int jbd2_journal_errno(journal_t *journal) + } + + /** +- * int jbd2_journal_clear_err () - clears the journal's error state ++ * jbd2_journal_clear_err() - clears the journal's error state + * @journal: journal to act on. + * + * An error must be cleared or acked to take a FS out of readonly +@@ -2202,7 +2204,7 @@ int jbd2_journal_clear_err(journal_t *journal) + } + + /** +- * void jbd2_journal_ack_err() - Ack journal err. ++ * jbd2_journal_ack_err() - Ack journal err. + * @journal: journal to act on. + * + * An error must be cleared or acked to take a FS out of readonly +diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c +index 09f4d00fece2f..91c2d3f6d1b3b 100644 +--- a/fs/jbd2/transaction.c ++++ b/fs/jbd2/transaction.c +@@ -490,7 +490,7 @@ EXPORT_SYMBOL(jbd2__journal_start); + + + /** +- * handle_t *jbd2_journal_start() - Obtain a new handle. ++ * jbd2_journal_start() - Obtain a new handle. + * @journal: Journal to start transaction on. + * @nblocks: number of block buffer we might modify + * +@@ -525,7 +525,7 @@ void jbd2_journal_free_reserved(handle_t *handle) + EXPORT_SYMBOL(jbd2_journal_free_reserved); + + /** +- * int jbd2_journal_start_reserved() - start reserved handle ++ * jbd2_journal_start_reserved() - start reserved handle + * @handle: handle to start + * @type: for handle statistics + * @line_no: for handle statistics +@@ -579,7 +579,7 @@ int jbd2_journal_start_reserved(handle_t *handle, unsigned int type, + EXPORT_SYMBOL(jbd2_journal_start_reserved); + + /** +- * int jbd2_journal_extend() - extend buffer credits. ++ * jbd2_journal_extend() - extend buffer credits. + * @handle: handle to 'extend' + * @nblocks: nr blocks to try to extend by. + * +@@ -659,7 +659,7 @@ error_out: + + + /** +- * int jbd2_journal_restart() - restart a handle . ++ * jbd2__journal_restart() - restart a handle . + * @handle: handle to restart + * @nblocks: nr credits requested + * @gfp_mask: memory allocation flags (for start_this_handle) +@@ -736,7 +736,7 @@ int jbd2_journal_restart(handle_t *handle, int nblocks) + EXPORT_SYMBOL(jbd2_journal_restart); + + /** +- * void jbd2_journal_lock_updates () - establish a transaction barrier. ++ * jbd2_journal_lock_updates () - establish a transaction barrier. + * @journal: Journal to establish a barrier on. + * + * This locks out any further updates from being started, and blocks +@@ -795,7 +795,7 @@ void jbd2_journal_lock_updates(journal_t *journal) + } + + /** +- * void jbd2_journal_unlock_updates (journal_t* journal) - release barrier ++ * jbd2_journal_unlock_updates () - release barrier + * @journal: Journal to release the barrier on. + * + * Release a transaction barrier obtained with jbd2_journal_lock_updates(). +@@ -1103,7 +1103,8 @@ out: + } + + /** +- * int jbd2_journal_get_write_access() - notify intent to modify a buffer for metadata (not data) update. ++ * jbd2_journal_get_write_access() - notify intent to modify a buffer ++ * for metadata (not data) update. + * @handle: transaction to add buffer modifications to + * @bh: bh to be used for metadata writes + * +@@ -1147,7 +1148,7 @@ int jbd2_journal_get_write_access(handle_t *handle, struct buffer_head *bh) + * unlocked buffer beforehand. */ + + /** +- * int jbd2_journal_get_create_access () - notify intent to use newly created bh ++ * jbd2_journal_get_create_access () - notify intent to use newly created bh + * @handle: transaction to new buffer to + * @bh: new buffer. + * +@@ -1227,7 +1228,7 @@ out: + } + + /** +- * int jbd2_journal_get_undo_access() - Notify intent to modify metadata with ++ * jbd2_journal_get_undo_access() - Notify intent to modify metadata with + * non-rewindable consequences + * @handle: transaction + * @bh: buffer to undo +@@ -1304,7 +1305,7 @@ out: + } + + /** +- * void jbd2_journal_set_triggers() - Add triggers for commit writeout ++ * jbd2_journal_set_triggers() - Add triggers for commit writeout + * @bh: buffer to trigger on + * @type: struct jbd2_buffer_trigger_type containing the trigger(s). + * +@@ -1346,7 +1347,7 @@ void jbd2_buffer_abort_trigger(struct journal_head *jh, + } + + /** +- * int jbd2_journal_dirty_metadata() - mark a buffer as containing dirty metadata ++ * jbd2_journal_dirty_metadata() - mark a buffer as containing dirty metadata + * @handle: transaction to add buffer to. + * @bh: buffer to mark + * +@@ -1524,7 +1525,7 @@ out: + } + + /** +- * void jbd2_journal_forget() - bforget() for potentially-journaled buffers. ++ * jbd2_journal_forget() - bforget() for potentially-journaled buffers. + * @handle: transaction handle + * @bh: bh to 'forget' + * +@@ -1699,7 +1700,7 @@ not_jbd: + } + + /** +- * int jbd2_journal_stop() - complete a transaction ++ * jbd2_journal_stop() - complete a transaction + * @handle: transaction to complete. + * + * All done for a particular handle. +@@ -2047,7 +2048,7 @@ out: + } + + /** +- * int jbd2_journal_try_to_free_buffers() - try to free page buffers. ++ * jbd2_journal_try_to_free_buffers() - try to free page buffers. + * @journal: journal for operation + * @page: to try and free + * @gfp_mask: we use the mask to detect how hard should we try to release +@@ -2386,7 +2387,7 @@ zap_buffer_unlocked: + } + + /** +- * void jbd2_journal_invalidatepage() ++ * jbd2_journal_invalidatepage() + * @journal: journal to use for flush... + * @page: page to flush + * @offset: start of the range to invalidate +diff --git a/fs/super.c b/fs/super.c +index e255c18fa2c88..47ca7dc0e6c3d 100644 +--- a/fs/super.c ++++ b/fs/super.c +@@ -905,6 +905,7 @@ int reconfigure_super(struct fs_context *fc) + struct super_block *sb = fc->root->d_sb; + int retval; + bool remount_ro = false; ++ bool remount_rw = false; + bool force = fc->sb_flags & SB_FORCE; + + if (fc->sb_flags_mask & ~MS_RMT_MASK) +@@ -921,7 +922,7 @@ int reconfigure_super(struct fs_context *fc) + if (!(fc->sb_flags & SB_RDONLY) && bdev_read_only(sb->s_bdev)) + return -EACCES; + #endif +- ++ remount_rw = !(fc->sb_flags & SB_RDONLY) && sb_rdonly(sb); + remount_ro = (fc->sb_flags & SB_RDONLY) && !sb_rdonly(sb); + } + +@@ -951,6 +952,14 @@ int reconfigure_super(struct fs_context *fc) + if (retval) + return retval; + } ++ } else if (remount_rw) { ++ /* ++ * We set s_readonly_remount here to protect filesystem's ++ * reconfigure code from writes from userspace until ++ * reconfigure finishes. ++ */ ++ sb->s_readonly_remount = 1; ++ smp_wmb(); + } + + if (fc->ops->reconfigure) { +diff --git a/fs/sysv/itree.c b/fs/sysv/itree.c +index 31f66053e2393..e3d1673b8ec97 100644 +--- a/fs/sysv/itree.c ++++ b/fs/sysv/itree.c +@@ -145,6 +145,10 @@ static int alloc_branch(struct inode *inode, + */ + parent = block_to_cpu(SYSV_SB(inode->i_sb), branch[n-1].key); + bh = sb_getblk(inode->i_sb, parent); ++ if (!bh) { ++ sysv_free_block(inode->i_sb, branch[n].key); ++ break; ++ } + lock_buffer(bh); + memset(bh->b_data, 0, blocksize); + branch[n].bh = bh; +diff --git a/include/asm-generic/word-at-a-time.h b/include/asm-generic/word-at-a-time.h +index 20c93f08c9933..95a1d214108a5 100644 +--- a/include/asm-generic/word-at-a-time.h ++++ b/include/asm-generic/word-at-a-time.h +@@ -38,7 +38,7 @@ static inline long find_zero(unsigned long mask) + return (mask >> 8) ? byte : byte + 1; + } + +-static inline bool has_zero(unsigned long val, unsigned long *data, const struct word_at_a_time *c) ++static inline unsigned long has_zero(unsigned long val, unsigned long *data, const struct word_at_a_time *c) + { + unsigned long rhs = val | c->low_bits; + *data = rhs; +diff --git a/include/linux/device.h b/include/linux/device.h +index d74275e2047a4..c7be3a8073ec3 100644 +--- a/include/linux/device.h ++++ b/include/linux/device.h +@@ -1871,6 +1871,9 @@ do { \ + WARN_ONCE(condition, "%s %s: " format, \ + dev_driver_string(dev), dev_name(dev), ## arg) + ++extern __printf(3, 4) ++int dev_err_probe(const struct device *dev, int err, const char *fmt, ...); ++ + /* Create alias, so I can be autoloaded. */ + #define MODULE_ALIAS_CHARDEV(major,minor) \ + MODULE_ALIAS("char-major-" __stringify(major) "-" __stringify(minor)) +diff --git a/include/linux/jbd2.h b/include/linux/jbd2.h +index b0e97e5de8ca4..b60adc4210b57 100644 +--- a/include/linux/jbd2.h ++++ b/include/linux/jbd2.h +@@ -415,7 +415,7 @@ static inline void jbd_unlock_bh_journal_head(struct buffer_head *bh) + #define JI_WAIT_DATA (1 << __JI_WAIT_DATA) + + /** +- * struct jbd_inode - The jbd_inode type is the structure linking inodes in ++ * struct jbd2_inode - The jbd_inode type is the structure linking inodes in + * ordered mode present in a transaction so that we can sync them during commit. + */ + struct jbd2_inode { +diff --git a/include/linux/pm_wakeirq.h b/include/linux/pm_wakeirq.h +index cd5b62db90845..e63a63aa47a37 100644 +--- a/include/linux/pm_wakeirq.h ++++ b/include/linux/pm_wakeirq.h +@@ -17,8 +17,8 @@ + #ifdef CONFIG_PM + + extern int dev_pm_set_wake_irq(struct device *dev, int irq); +-extern int dev_pm_set_dedicated_wake_irq(struct device *dev, +- int irq); ++extern int dev_pm_set_dedicated_wake_irq(struct device *dev, int irq); ++extern int dev_pm_set_dedicated_wake_irq_reverse(struct device *dev, int irq); + extern void dev_pm_clear_wake_irq(struct device *dev); + extern void dev_pm_enable_wake_irq(struct device *dev); + extern void dev_pm_disable_wake_irq(struct device *dev); +@@ -35,6 +35,11 @@ static inline int dev_pm_set_dedicated_wake_irq(struct device *dev, int irq) + return 0; + } + ++static inline int dev_pm_set_dedicated_wake_irq_reverse(struct device *dev, int irq) ++{ ++ return 0; ++} ++ + static inline void dev_pm_clear_wake_irq(struct device *dev) + { + } +diff --git a/include/net/ipv6.h b/include/net/ipv6.h +index 0e031a4fef408..8c454509f299f 100644 +--- a/include/net/ipv6.h ++++ b/include/net/ipv6.h +@@ -660,12 +660,8 @@ static inline u32 ipv6_addr_hash(const struct in6_addr *a) + /* more secured version of ipv6_addr_hash() */ + static inline u32 __ipv6_addr_jhash(const struct in6_addr *a, const u32 initval) + { +- u32 v = (__force u32)a->s6_addr32[0] ^ (__force u32)a->s6_addr32[1]; +- +- return jhash_3words(v, +- (__force u32)a->s6_addr32[2], +- (__force u32)a->s6_addr32[3], +- initval); ++ return jhash2((__force const u32 *)a->s6_addr32, ++ ARRAY_SIZE(a->s6_addr32), initval); + } + + static inline bool ipv6_addr_loopback(const struct in6_addr *a) +diff --git a/include/net/vxlan.h b/include/net/vxlan.h +index 373aadcfea21d..d79ee21d7932a 100644 +--- a/include/net/vxlan.h ++++ b/include/net/vxlan.h +@@ -323,10 +323,15 @@ static inline netdev_features_t vxlan_features_check(struct sk_buff *skb, + return features; + } + +-/* IP header + UDP + VXLAN + Ethernet header */ +-#define VXLAN_HEADROOM (20 + 8 + 8 + 14) +-/* IPv6 header + UDP + VXLAN + Ethernet header */ +-#define VXLAN6_HEADROOM (40 + 8 + 8 + 14) ++static inline int vxlan_headroom(u32 flags) ++{ ++ /* VXLAN: IP4/6 header + UDP + VXLAN + Ethernet header */ ++ /* VXLAN-GPE: IP4/6 header + UDP + VXLAN */ ++ return (flags & VXLAN_F_IPV6 ? sizeof(struct ipv6hdr) : ++ sizeof(struct iphdr)) + ++ sizeof(struct udphdr) + sizeof(struct vxlanhdr) + ++ (flags & VXLAN_F_GPE ? 0 : ETH_HLEN); ++} + + static inline struct vxlanhdr *vxlan_hdr(struct sk_buff *skb) + { +diff --git a/include/uapi/linux/blkzoned.h b/include/uapi/linux/blkzoned.h +index 498eec813494c..94649130e3d74 100644 +--- a/include/uapi/linux/blkzoned.h ++++ b/include/uapi/linux/blkzoned.h +@@ -51,13 +51,13 @@ enum blk_zone_type { + * + * The Zone Condition state machine in the ZBC/ZAC standards maps the above + * deinitions as: +- * - ZC1: Empty | BLK_ZONE_EMPTY ++ * - ZC1: Empty | BLK_ZONE_COND_EMPTY + * - ZC2: Implicit Open | BLK_ZONE_COND_IMP_OPEN + * - ZC3: Explicit Open | BLK_ZONE_COND_EXP_OPEN +- * - ZC4: Closed | BLK_ZONE_CLOSED +- * - ZC5: Full | BLK_ZONE_FULL +- * - ZC6: Read Only | BLK_ZONE_READONLY +- * - ZC7: Offline | BLK_ZONE_OFFLINE ++ * - ZC4: Closed | BLK_ZONE_COND_CLOSED ++ * - ZC5: Full | BLK_ZONE_COND_FULL ++ * - ZC6: Read Only | BLK_ZONE_COND_READONLY ++ * - ZC7: Offline | BLK_ZONE_COND_OFFLINE + * + * Conditions 0x5 to 0xC are reserved by the current ZBC/ZAC spec and should + * be considered invalid. +diff --git a/include/uapi/linux/watch_queue.h b/include/uapi/linux/watch_queue.h +new file mode 100644 +index 0000000000000..5f3d21e8a34b0 +--- /dev/null ++++ b/include/uapi/linux/watch_queue.h +@@ -0,0 +1,55 @@ ++/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ ++#ifndef _UAPI_LINUX_WATCH_QUEUE_H ++#define _UAPI_LINUX_WATCH_QUEUE_H ++ ++#include ++ ++enum watch_notification_type { ++ WATCH_TYPE_META = 0, /* Special record */ ++ WATCH_TYPE__NR = 1 ++}; ++ ++enum watch_meta_notification_subtype { ++ WATCH_META_REMOVAL_NOTIFICATION = 0, /* Watched object was removed */ ++ WATCH_META_LOSS_NOTIFICATION = 1, /* Data loss occurred */ ++}; ++ ++/* ++ * Notification record header. This is aligned to 64-bits so that subclasses ++ * can contain __u64 fields. ++ */ ++struct watch_notification { ++ __u32 type:24; /* enum watch_notification_type */ ++ __u32 subtype:8; /* Type-specific subtype (filterable) */ ++ __u32 info; ++#define WATCH_INFO_LENGTH 0x0000007f /* Length of record */ ++#define WATCH_INFO_LENGTH__SHIFT 0 ++#define WATCH_INFO_ID 0x0000ff00 /* ID of watchpoint */ ++#define WATCH_INFO_ID__SHIFT 8 ++#define WATCH_INFO_TYPE_INFO 0xffff0000 /* Type-specific info */ ++#define WATCH_INFO_TYPE_INFO__SHIFT 16 ++#define WATCH_INFO_FLAG_0 0x00010000 /* Type-specific info, flag bit 0 */ ++#define WATCH_INFO_FLAG_1 0x00020000 /* ... */ ++#define WATCH_INFO_FLAG_2 0x00040000 ++#define WATCH_INFO_FLAG_3 0x00080000 ++#define WATCH_INFO_FLAG_4 0x00100000 ++#define WATCH_INFO_FLAG_5 0x00200000 ++#define WATCH_INFO_FLAG_6 0x00400000 ++#define WATCH_INFO_FLAG_7 0x00800000 ++}; ++ ++ ++/* ++ * Extended watch removal notification. This is used optionally if the type ++ * wants to indicate an identifier for the object being watched, if there is ++ * such. This can be distinguished by the length. ++ * ++ * type -> WATCH_TYPE_META ++ * subtype -> WATCH_META_REMOVAL_NOTIFICATION ++ */ ++struct watch_notification_removal { ++ struct watch_notification watch; ++ __u64 id; /* Type-dependent identifier */ ++}; ++ ++#endif /* _UAPI_LINUX_WATCH_QUEUE_H */ +diff --git a/kernel/events/core.c b/kernel/events/core.c +index c4a44ef836b02..875b3c27eab02 100644 +--- a/kernel/events/core.c ++++ b/kernel/events/core.c +@@ -1134,6 +1134,11 @@ static int perf_mux_hrtimer_restart(struct perf_cpu_context *cpuctx) + return 0; + } + ++static int perf_mux_hrtimer_restart_ipi(void *arg) ++{ ++ return perf_mux_hrtimer_restart(arg); ++} ++ + void perf_pmu_disable(struct pmu *pmu) + { + int *count = this_cpu_ptr(pmu->pmu_disable_count); +@@ -9997,8 +10002,7 @@ perf_event_mux_interval_ms_store(struct device *dev, + cpuctx = per_cpu_ptr(pmu->pmu_cpu_context, cpu); + cpuctx->hrtimer_interval = ns_to_ktime(NSEC_PER_MSEC * timer); + +- cpu_function_call(cpu, +- (remote_function_f)perf_mux_hrtimer_restart, cpuctx); ++ cpu_function_call(cpu, perf_mux_hrtimer_restart_ipi, cpuctx); + } + cpus_read_unlock(); + mutex_unlock(&mux_interval_mutex); +diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c +index 8e3c76dcc0ffe..412505d948651 100644 +--- a/kernel/trace/ftrace.c ++++ b/kernel/trace/ftrace.c +@@ -1100,7 +1100,7 @@ struct ftrace_page { + struct ftrace_page *next; + struct dyn_ftrace *records; + int index; +- int size; ++ int order; + }; + + #define ENTRY_SIZE sizeof(struct dyn_ftrace) +@@ -2899,6 +2899,8 @@ static void ftrace_shutdown_sysctl(void) + + static u64 ftrace_update_time; + unsigned long ftrace_update_tot_cnt; ++unsigned long ftrace_number_of_pages; ++unsigned long ftrace_number_of_groups; + + static inline int ops_traces_mod(struct ftrace_ops *ops) + { +@@ -3023,8 +3025,11 @@ static int ftrace_allocate_records(struct ftrace_page *pg, int count) + goto again; + } + ++ ftrace_number_of_pages += 1 << order; ++ ftrace_number_of_groups++; ++ + cnt = (PAGE_SIZE << order) / ENTRY_SIZE; +- pg->size = cnt; ++ pg->order = order; + + if (cnt > count) + cnt = count; +@@ -3032,12 +3037,27 @@ static int ftrace_allocate_records(struct ftrace_page *pg, int count) + return cnt; + } + ++static void ftrace_free_pages(struct ftrace_page *pages) ++{ ++ struct ftrace_page *pg = pages; ++ ++ while (pg) { ++ if (pg->records) { ++ free_pages((unsigned long)pg->records, pg->order); ++ ftrace_number_of_pages -= 1 << pg->order; ++ } ++ pages = pg->next; ++ kfree(pg); ++ pg = pages; ++ ftrace_number_of_groups--; ++ } ++} ++ + static struct ftrace_page * + ftrace_allocate_pages(unsigned long num_to_init) + { + struct ftrace_page *start_pg; + struct ftrace_page *pg; +- int order; + int cnt; + + if (!num_to_init) +@@ -3071,14 +3091,7 @@ ftrace_allocate_pages(unsigned long num_to_init) + return start_pg; + + free_pages: +- pg = start_pg; +- while (pg) { +- order = get_count_order(pg->size / ENTRIES_PER_PAGE); +- free_pages((unsigned long)pg->records, order); +- start_pg = pg->next; +- kfree(pg); +- pg = start_pg; +- } ++ ftrace_free_pages(start_pg); + pr_info("ftrace: FAILED to allocate memory for functions\n"); + return NULL; + } +@@ -5620,9 +5633,11 @@ static int ftrace_process_locs(struct module *mod, + unsigned long *start, + unsigned long *end) + { ++ struct ftrace_page *pg_unuse = NULL; + struct ftrace_page *start_pg; + struct ftrace_page *pg; + struct dyn_ftrace *rec; ++ unsigned long skipped = 0; + unsigned long count; + unsigned long *p; + unsigned long addr; +@@ -5668,6 +5683,7 @@ static int ftrace_process_locs(struct module *mod, + p = start; + pg = start_pg; + while (p < end) { ++ unsigned long end_offset; + addr = ftrace_call_adjust(*p++); + /* + * Some architecture linkers will pad between +@@ -5675,10 +5691,13 @@ static int ftrace_process_locs(struct module *mod, + * object files to satisfy alignments. + * Skip any NULL pointers. + */ +- if (!addr) ++ if (!addr) { ++ skipped++; + continue; ++ } + +- if (pg->index == pg->size) { ++ end_offset = (pg->index+1) * sizeof(pg->records[0]); ++ if (end_offset > PAGE_SIZE << pg->order) { + /* We should have allocated enough */ + if (WARN_ON(!pg->next)) + break; +@@ -5689,8 +5708,10 @@ static int ftrace_process_locs(struct module *mod, + rec->ip = addr; + } + +- /* We should have used all pages */ +- WARN_ON(pg->next); ++ if (pg->next) { ++ pg_unuse = pg->next; ++ pg->next = NULL; ++ } + + /* Assign the last page to ftrace_pages */ + ftrace_pages = pg; +@@ -5712,6 +5733,11 @@ static int ftrace_process_locs(struct module *mod, + out: + mutex_unlock(&ftrace_lock); + ++ /* We should have used all pages unless we skipped some */ ++ if (pg_unuse) { ++ WARN_ON(!skipped); ++ ftrace_free_pages(pg_unuse); ++ } + return ret; + } + +@@ -5818,7 +5844,6 @@ void ftrace_release_mod(struct module *mod) + struct ftrace_page **last_pg; + struct ftrace_page *tmp_page = NULL; + struct ftrace_page *pg; +- int order; + + mutex_lock(&ftrace_lock); + +@@ -5869,10 +5894,13 @@ void ftrace_release_mod(struct module *mod) + /* Needs to be called outside of ftrace_lock */ + clear_mod_from_hashes(pg); + +- order = get_count_order(pg->size / ENTRIES_PER_PAGE); +- free_pages((unsigned long)pg->records, order); ++ if (pg->records) { ++ free_pages((unsigned long)pg->records, pg->order); ++ ftrace_number_of_pages -= 1 << pg->order; ++ } + tmp_page = pg->next; + kfree(pg); ++ ftrace_number_of_groups--; + } + } + +@@ -6174,7 +6202,6 @@ void ftrace_free_mem(struct module *mod, void *start_ptr, void *end_ptr) + struct ftrace_mod_map *mod_map = NULL; + struct ftrace_init_func *func, *func_next; + struct list_head clear_hash; +- int order; + + INIT_LIST_HEAD(&clear_hash); + +@@ -6212,8 +6239,11 @@ void ftrace_free_mem(struct module *mod, void *start_ptr, void *end_ptr) + ftrace_update_tot_cnt--; + if (!pg->index) { + *last_pg = pg->next; +- order = get_count_order(pg->size / ENTRIES_PER_PAGE); +- free_pages((unsigned long)pg->records, order); ++ if (pg->records) { ++ free_pages((unsigned long)pg->records, pg->order); ++ ftrace_number_of_pages -= 1 << pg->order; ++ } ++ ftrace_number_of_groups--; + kfree(pg); + pg = container_of(last_pg, struct ftrace_page, next); + if (!(*last_pg)) +@@ -6269,6 +6299,9 @@ void __init ftrace_init(void) + __start_mcount_loc, + __stop_mcount_loc); + ++ pr_info("ftrace: allocated %ld pages with %ld groups\n", ++ ftrace_number_of_pages, ftrace_number_of_groups); ++ + set_ftrace_early_filters(); + + return; +diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c +index afd7f3a51485e..445475c229b3a 100644 +--- a/kernel/trace/ring_buffer.c ++++ b/kernel/trace/ring_buffer.c +@@ -485,6 +485,8 @@ struct ring_buffer_per_cpu { + unsigned long read_bytes; + u64 write_stamp; + u64 read_stamp; ++ /* pages removed since last reset */ ++ unsigned long pages_removed; + /* ring buffer pages to update, > 0 to add, < 0 to remove */ + long nr_pages_to_update; + struct list_head new_pages; /* new pages to add */ +@@ -520,6 +522,7 @@ struct ring_buffer_iter { + struct buffer_page *head_page; + struct buffer_page *cache_reader_page; + unsigned long cache_read; ++ unsigned long cache_pages_removed; + u64 read_stamp; + }; + +@@ -1581,6 +1584,8 @@ rb_remove_pages(struct ring_buffer_per_cpu *cpu_buffer, unsigned long nr_pages) + to_remove = rb_list_head(to_remove)->next; + head_bit |= (unsigned long)to_remove & RB_PAGE_HEAD; + } ++ /* Read iterators need to reset themselves when some pages removed */ ++ cpu_buffer->pages_removed += nr_removed; + + next_page = rb_list_head(to_remove)->next; + +@@ -1602,12 +1607,6 @@ rb_remove_pages(struct ring_buffer_per_cpu *cpu_buffer, unsigned long nr_pages) + cpu_buffer->head_page = list_entry(next_page, + struct buffer_page, list); + +- /* +- * change read pointer to make sure any read iterators reset +- * themselves +- */ +- cpu_buffer->read = 0; +- + /* pages are removed, resume tracing and then free the pages */ + atomic_dec(&cpu_buffer->record_disabled); + raw_spin_unlock_irq(&cpu_buffer->reader_lock); +@@ -3659,6 +3658,7 @@ static void rb_iter_reset(struct ring_buffer_iter *iter) + + iter->cache_reader_page = iter->head_page; + iter->cache_read = cpu_buffer->read; ++ iter->cache_pages_removed = cpu_buffer->pages_removed; + + if (iter->head) + iter->read_stamp = cpu_buffer->read_stamp; +@@ -4101,12 +4101,13 @@ rb_iter_peek(struct ring_buffer_iter *iter, u64 *ts) + buffer = cpu_buffer->buffer; + + /* +- * Check if someone performed a consuming read to +- * the buffer. A consuming read invalidates the iterator +- * and we need to reset the iterator in this case. ++ * Check if someone performed a consuming read to the buffer ++ * or removed some pages from the buffer. In these cases, ++ * iterator was invalidated and we need to reset it. + */ + if (unlikely(iter->cache_read != cpu_buffer->read || +- iter->cache_reader_page != cpu_buffer->reader_page)) ++ iter->cache_reader_page != cpu_buffer->reader_page || ++ iter->cache_pages_removed != cpu_buffer->pages_removed)) + rb_iter_reset(iter); + + again: +@@ -4538,6 +4539,7 @@ rb_reset_cpu(struct ring_buffer_per_cpu *cpu_buffer) + cpu_buffer->last_overrun = 0; + + rb_head_page_activate(cpu_buffer); ++ cpu_buffer->pages_removed = 0; + } + + /** +diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c +index 7f7c700a61560..8006592803e1c 100644 +--- a/kernel/trace/trace.c ++++ b/kernel/trace/trace.c +@@ -7662,14 +7662,23 @@ static ssize_t + tracing_read_dyn_info(struct file *filp, char __user *ubuf, + size_t cnt, loff_t *ppos) + { +- unsigned long *p = filp->private_data; +- char buf[64]; /* Not too big for a shallow stack */ ++ ssize_t ret; ++ char *buf; + int r; + +- r = scnprintf(buf, 63, "%ld", *p); +- buf[r++] = '\n'; ++ /* 256 should be plenty to hold the amount needed */ ++ buf = kmalloc(256, GFP_KERNEL); ++ if (!buf) ++ return -ENOMEM; + +- return simple_read_from_buffer(ubuf, cnt, ppos, buf, r); ++ r = scnprintf(buf, 256, "%ld pages:%ld groups: %ld\n", ++ ftrace_update_tot_cnt, ++ ftrace_number_of_pages, ++ ftrace_number_of_groups); ++ ++ ret = simple_read_from_buffer(ubuf, cnt, ppos, buf, r); ++ kfree(buf); ++ return ret; + } + + static const struct file_operations tracing_dyn_info_fops = { +@@ -8889,7 +8898,7 @@ static __init int tracer_init_tracefs(void) + + #ifdef CONFIG_DYNAMIC_FTRACE + trace_create_file("dyn_ftrace_total_info", 0444, d_tracer, +- &ftrace_update_tot_cnt, &tracing_dyn_info_fops); ++ NULL, &tracing_dyn_info_fops); + #endif + + create_trace_instances(d_tracer); +diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h +index edc17a640ab34..21f85c0bd66ec 100644 +--- a/kernel/trace/trace.h ++++ b/kernel/trace/trace.h +@@ -801,6 +801,8 @@ extern void trace_event_follow_fork(struct trace_array *tr, bool enable); + + #ifdef CONFIG_DYNAMIC_FTRACE + extern unsigned long ftrace_update_tot_cnt; ++extern unsigned long ftrace_number_of_pages; ++extern unsigned long ftrace_number_of_groups; + void ftrace_init_trace_array(struct trace_array *tr); + #else + static inline void ftrace_init_trace_array(struct trace_array *tr) { } +diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c +index a0675ecc8142e..0c21da12b650c 100644 +--- a/kernel/trace/trace_events.c ++++ b/kernel/trace/trace_events.c +@@ -365,7 +365,6 @@ static int __ftrace_event_enable_disable(struct trace_event_file *file, + { + struct trace_event_call *call = file->event_call; + struct trace_array *tr = file->tr; +- unsigned long file_flags = file->flags; + int ret = 0; + int disable; + +@@ -389,6 +388,8 @@ static int __ftrace_event_enable_disable(struct trace_event_file *file, + break; + disable = file->flags & EVENT_FILE_FL_SOFT_DISABLED; + clear_bit(EVENT_FILE_FL_SOFT_MODE_BIT, &file->flags); ++ /* Disable use of trace_buffered_event */ ++ trace_buffered_event_disable(); + } else + disable = !(file->flags & EVENT_FILE_FL_SOFT_MODE); + +@@ -427,6 +428,8 @@ static int __ftrace_event_enable_disable(struct trace_event_file *file, + if (atomic_inc_return(&file->sm_ref) > 1) + break; + set_bit(EVENT_FILE_FL_SOFT_MODE_BIT, &file->flags); ++ /* Enable use of trace_buffered_event */ ++ trace_buffered_event_enable(); + } + + if (!(file->flags & EVENT_FILE_FL_ENABLED)) { +@@ -466,15 +469,6 @@ static int __ftrace_event_enable_disable(struct trace_event_file *file, + break; + } + +- /* Enable or disable use of trace_buffered_event */ +- if ((file_flags & EVENT_FILE_FL_SOFT_DISABLED) != +- (file->flags & EVENT_FILE_FL_SOFT_DISABLED)) { +- if (file->flags & EVENT_FILE_FL_SOFT_DISABLED) +- trace_buffered_event_enable(); +- else +- trace_buffered_event_disable(); +- } +- + return ret; + } + +diff --git a/lib/test_firmware.c b/lib/test_firmware.c +index 38553944e9675..dd3850ec1dfa1 100644 +--- a/lib/test_firmware.c ++++ b/lib/test_firmware.c +@@ -173,7 +173,7 @@ static int __kstrncpy(char **dst, const char *name, size_t count, gfp_t gfp) + { + *dst = kstrndup(name, count, gfp); + if (!*dst) +- return -ENOSPC; ++ return -ENOMEM; + return count; + } + +@@ -301,16 +301,26 @@ static ssize_t config_test_show_str(char *dst, + return len; + } + +-static int test_dev_config_update_bool(const char *buf, size_t size, +- bool *cfg) ++static inline int __test_dev_config_update_bool(const char *buf, size_t size, ++ bool *cfg) + { + int ret; + +- mutex_lock(&test_fw_mutex); + if (strtobool(buf, cfg) < 0) + ret = -EINVAL; + else + ret = size; ++ ++ return ret; ++} ++ ++static int test_dev_config_update_bool(const char *buf, size_t size, ++ bool *cfg) ++{ ++ int ret; ++ ++ mutex_lock(&test_fw_mutex); ++ ret = __test_dev_config_update_bool(buf, size, cfg); + mutex_unlock(&test_fw_mutex); + + return ret; +@@ -340,7 +350,7 @@ static ssize_t test_dev_config_show_int(char *buf, int cfg) + return snprintf(buf, PAGE_SIZE, "%d\n", val); + } + +-static int test_dev_config_update_u8(const char *buf, size_t size, u8 *cfg) ++static inline int __test_dev_config_update_u8(const char *buf, size_t size, u8 *cfg) + { + int ret; + long new; +@@ -352,14 +362,23 @@ static int test_dev_config_update_u8(const char *buf, size_t size, u8 *cfg) + if (new > U8_MAX) + return -EINVAL; + +- mutex_lock(&test_fw_mutex); + *(u8 *)cfg = new; +- mutex_unlock(&test_fw_mutex); + + /* Always return full write size even if we didn't consume all */ + return size; + } + ++static int test_dev_config_update_u8(const char *buf, size_t size, u8 *cfg) ++{ ++ int ret; ++ ++ mutex_lock(&test_fw_mutex); ++ ret = __test_dev_config_update_u8(buf, size, cfg); ++ mutex_unlock(&test_fw_mutex); ++ ++ return ret; ++} ++ + static ssize_t test_dev_config_show_u8(char *buf, u8 cfg) + { + u8 val; +@@ -392,10 +411,10 @@ static ssize_t config_num_requests_store(struct device *dev, + mutex_unlock(&test_fw_mutex); + goto out; + } +- mutex_unlock(&test_fw_mutex); + +- rc = test_dev_config_update_u8(buf, count, +- &test_fw_config->num_requests); ++ rc = __test_dev_config_update_u8(buf, count, ++ &test_fw_config->num_requests); ++ mutex_unlock(&test_fw_mutex); + + out: + return rc; +@@ -490,7 +509,7 @@ static ssize_t trigger_request_store(struct device *dev, + + name = kstrndup(buf, count, GFP_KERNEL); + if (!name) +- return -ENOSPC; ++ return -ENOMEM; + + pr_info("loading '%s'\n", name); + +@@ -533,7 +552,7 @@ static ssize_t trigger_async_request_store(struct device *dev, + + name = kstrndup(buf, count, GFP_KERNEL); + if (!name) +- return -ENOSPC; ++ return -ENOMEM; + + pr_info("loading '%s'\n", name); + +@@ -578,7 +597,7 @@ static ssize_t trigger_custom_fallback_store(struct device *dev, + + name = kstrndup(buf, count, GFP_KERNEL); + if (!name) +- return -ENOSPC; ++ return -ENOMEM; + + pr_info("loading '%s' using custom fallback mechanism\n", name); + +@@ -629,7 +648,7 @@ static int test_fw_run_batch_request(void *data) + + test_buf = kzalloc(TEST_FIRMWARE_BUF_SIZE, GFP_KERNEL); + if (!test_buf) +- return -ENOSPC; ++ return -ENOMEM; + + req->rc = request_firmware_into_buf(&req->fw, + req->name, +diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c +index 0fa5ced767a24..712bffa4e8b47 100644 +--- a/net/bluetooth/l2cap_sock.c ++++ b/net/bluetooth/l2cap_sock.c +@@ -45,6 +45,7 @@ static const struct proto_ops l2cap_sock_ops; + static void l2cap_sock_init(struct sock *sk, struct sock *parent); + static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, + int proto, gfp_t prio, int kern); ++static void l2cap_sock_cleanup_listen(struct sock *parent); + + bool l2cap_is_socket(struct socket *sock) + { +@@ -1224,6 +1225,7 @@ static int l2cap_sock_release(struct socket *sock) + if (!sk) + return 0; + ++ l2cap_sock_cleanup_listen(sk); + bt_sock_unlink(&l2cap_sk_list, sk); + + err = l2cap_sock_shutdown(sock, 2); +diff --git a/net/ceph/osd_client.c b/net/ceph/osd_client.c +index a8481da37f1ad..7412bcc94d1d9 100644 +--- a/net/ceph/osd_client.c ++++ b/net/ceph/osd_client.c +@@ -3249,17 +3249,24 @@ static int linger_reg_commit_wait(struct ceph_osd_linger_request *lreq) + int ret; + + dout("%s lreq %p linger_id %llu\n", __func__, lreq, lreq->linger_id); +- ret = wait_for_completion_interruptible(&lreq->reg_commit_wait); ++ ret = wait_for_completion_killable(&lreq->reg_commit_wait); + return ret ?: lreq->reg_commit_error; + } + +-static int linger_notify_finish_wait(struct ceph_osd_linger_request *lreq) ++static int linger_notify_finish_wait(struct ceph_osd_linger_request *lreq, ++ unsigned long timeout) + { +- int ret; ++ long left; + + dout("%s lreq %p linger_id %llu\n", __func__, lreq, lreq->linger_id); +- ret = wait_for_completion_interruptible(&lreq->notify_finish_wait); +- return ret ?: lreq->notify_finish_error; ++ left = wait_for_completion_killable_timeout(&lreq->notify_finish_wait, ++ ceph_timeout_jiffies(timeout)); ++ if (left <= 0) ++ left = left ?: -ETIMEDOUT; ++ else ++ left = lreq->notify_finish_error; /* completed */ ++ ++ return left; + } + + /* +@@ -4875,7 +4882,8 @@ int ceph_osdc_notify(struct ceph_osd_client *osdc, + linger_submit(lreq); + ret = linger_reg_commit_wait(lreq); + if (!ret) +- ret = linger_notify_finish_wait(lreq); ++ ret = linger_notify_finish_wait(lreq, ++ msecs_to_jiffies(2 * timeout * MSEC_PER_SEC)); + else + dout("lreq %p failed to initiate notify %d\n", lreq, ret); + +diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c +index 1db92a44548f0..3eaf7c706b0ec 100644 +--- a/net/core/rtnetlink.c ++++ b/net/core/rtnetlink.c +@@ -4590,13 +4590,17 @@ static int rtnl_bridge_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, + br_spec = nlmsg_find_attr(nlh, sizeof(struct ifinfomsg), IFLA_AF_SPEC); + if (br_spec) { + nla_for_each_nested(attr, br_spec, rem) { +- if (nla_type(attr) == IFLA_BRIDGE_FLAGS) { ++ if (nla_type(attr) == IFLA_BRIDGE_FLAGS && !have_flags) { + if (nla_len(attr) < sizeof(flags)) + return -EINVAL; + + have_flags = true; + flags = nla_get_u16(attr); +- break; ++ } ++ ++ if (nla_type(attr) == IFLA_BRIDGE_MODE) { ++ if (nla_len(attr) < sizeof(u16)) ++ return -EINVAL; + } + } + } +diff --git a/net/core/sock.c b/net/core/sock.c +index d55eea5538bce..636427d400d7f 100644 +--- a/net/core/sock.c ++++ b/net/core/sock.c +@@ -1117,7 +1117,8 @@ set_rcvbuf: + cmpxchg(&sk->sk_pacing_status, + SK_PACING_NONE, + SK_PACING_NEEDED); +- sk->sk_max_pacing_rate = ulval; ++ /* Pairs with READ_ONCE() from sk_getsockopt() */ ++ WRITE_ONCE(sk->sk_max_pacing_rate, ulval); + sk->sk_pacing_rate = min(sk->sk_pacing_rate, ulval); + break; + } +@@ -1257,11 +1258,11 @@ int sock_getsockopt(struct socket *sock, int level, int optname, + break; + + case SO_SNDBUF: +- v.val = sk->sk_sndbuf; ++ v.val = READ_ONCE(sk->sk_sndbuf); + break; + + case SO_RCVBUF: +- v.val = sk->sk_rcvbuf; ++ v.val = READ_ONCE(sk->sk_rcvbuf); + break; + + case SO_REUSEADDR: +@@ -1349,7 +1350,7 @@ int sock_getsockopt(struct socket *sock, int level, int optname, + break; + + case SO_RCVLOWAT: +- v.val = sk->sk_rcvlowat; ++ v.val = READ_ONCE(sk->sk_rcvlowat); + break; + + case SO_SNDLOWAT: +@@ -1443,7 +1444,7 @@ int sock_getsockopt(struct socket *sock, int level, int optname, + if (!sock->ops->set_peek_off) + return -EOPNOTSUPP; + +- v.val = sk->sk_peek_off; ++ v.val = READ_ONCE(sk->sk_peek_off); + break; + case SO_NOFCS: + v.val = sock_flag(sk, SOCK_NOFCS); +@@ -1473,17 +1474,19 @@ int sock_getsockopt(struct socket *sock, int level, int optname, + + #ifdef CONFIG_NET_RX_BUSY_POLL + case SO_BUSY_POLL: +- v.val = sk->sk_ll_usec; ++ v.val = READ_ONCE(sk->sk_ll_usec); + break; + #endif + + case SO_MAX_PACING_RATE: ++ /* The READ_ONCE() pair with the WRITE_ONCE() in sk_setsockopt() */ + if (sizeof(v.ulval) != sizeof(v.val) && len >= sizeof(v.ulval)) { + lv = sizeof(v.ulval); +- v.ulval = sk->sk_max_pacing_rate; ++ v.ulval = READ_ONCE(sk->sk_max_pacing_rate); + } else { + /* 32bit version */ +- v.val = min_t(unsigned long, sk->sk_max_pacing_rate, ~0U); ++ v.val = min_t(unsigned long, ~0U, ++ READ_ONCE(sk->sk_max_pacing_rate)); + } + break; + +@@ -2649,7 +2652,7 @@ EXPORT_SYMBOL(__sk_mem_reclaim); + + int sk_set_peek_off(struct sock *sk, int val) + { +- sk->sk_peek_off = val; ++ WRITE_ONCE(sk->sk_peek_off, val); + return 0; + } + EXPORT_SYMBOL_GPL(sk_set_peek_off); +diff --git a/net/core/sock_map.c b/net/core/sock_map.c +index 5bce6d4d20573..5b82ff0e2680f 100644 +--- a/net/core/sock_map.c ++++ b/net/core/sock_map.c +@@ -115,7 +115,6 @@ static void sock_map_sk_acquire(struct sock *sk) + __acquires(&sk->sk_lock.slock) + { + lock_sock(sk); +- preempt_disable(); + rcu_read_lock(); + } + +@@ -123,7 +122,6 @@ static void sock_map_sk_release(struct sock *sk) + __releases(&sk->sk_lock.slock) + { + rcu_read_unlock(); +- preempt_enable(); + release_sock(sk); + } + +diff --git a/net/dcb/dcbnl.c b/net/dcb/dcbnl.c +index b53d5e1d026fe..71e97e2a36845 100644 +--- a/net/dcb/dcbnl.c ++++ b/net/dcb/dcbnl.c +@@ -946,7 +946,7 @@ static int dcbnl_bcn_setcfg(struct net_device *netdev, struct nlmsghdr *nlh, + return -EOPNOTSUPP; + + ret = nla_parse_nested_deprecated(data, DCB_BCN_ATTR_MAX, +- tb[DCB_ATTR_BCN], dcbnl_pfc_up_nest, ++ tb[DCB_ATTR_BCN], dcbnl_bcn_nest, + NULL); + if (ret) + return ret; +diff --git a/net/ipv4/tcp_metrics.c b/net/ipv4/tcp_metrics.c +index 0af6249a993af..e89e19a6852ce 100644 +--- a/net/ipv4/tcp_metrics.c ++++ b/net/ipv4/tcp_metrics.c +@@ -40,7 +40,7 @@ struct tcp_fastopen_metrics { + + struct tcp_metrics_block { + struct tcp_metrics_block __rcu *tcpm_next; +- possible_net_t tcpm_net; ++ struct net *tcpm_net; + struct inetpeer_addr tcpm_saddr; + struct inetpeer_addr tcpm_daddr; + unsigned long tcpm_stamp; +@@ -51,34 +51,38 @@ struct tcp_metrics_block { + struct rcu_head rcu_head; + }; + +-static inline struct net *tm_net(struct tcp_metrics_block *tm) ++static inline struct net *tm_net(const struct tcp_metrics_block *tm) + { +- return read_pnet(&tm->tcpm_net); ++ /* Paired with the WRITE_ONCE() in tcpm_new() */ ++ return READ_ONCE(tm->tcpm_net); + } + + static bool tcp_metric_locked(struct tcp_metrics_block *tm, + enum tcp_metric_index idx) + { +- return tm->tcpm_lock & (1 << idx); ++ /* Paired with WRITE_ONCE() in tcpm_suck_dst() */ ++ return READ_ONCE(tm->tcpm_lock) & (1 << idx); + } + +-static u32 tcp_metric_get(struct tcp_metrics_block *tm, ++static u32 tcp_metric_get(const struct tcp_metrics_block *tm, + enum tcp_metric_index idx) + { +- return tm->tcpm_vals[idx]; ++ /* Paired with WRITE_ONCE() in tcp_metric_set() */ ++ return READ_ONCE(tm->tcpm_vals[idx]); + } + + static void tcp_metric_set(struct tcp_metrics_block *tm, + enum tcp_metric_index idx, + u32 val) + { +- tm->tcpm_vals[idx] = val; ++ /* Paired with READ_ONCE() in tcp_metric_get() */ ++ WRITE_ONCE(tm->tcpm_vals[idx], val); + } + + static bool addr_same(const struct inetpeer_addr *a, + const struct inetpeer_addr *b) + { +- return inetpeer_addr_cmp(a, b) == 0; ++ return (a->family == b->family) && !inetpeer_addr_cmp(a, b); + } + + struct tcpm_hash_bucket { +@@ -89,6 +93,7 @@ static struct tcpm_hash_bucket *tcp_metrics_hash __read_mostly; + static unsigned int tcp_metrics_hash_log __read_mostly; + + static DEFINE_SPINLOCK(tcp_metrics_lock); ++static DEFINE_SEQLOCK(fastopen_seqlock); + + static void tcpm_suck_dst(struct tcp_metrics_block *tm, + const struct dst_entry *dst, +@@ -97,7 +102,7 @@ static void tcpm_suck_dst(struct tcp_metrics_block *tm, + u32 msval; + u32 val; + +- tm->tcpm_stamp = jiffies; ++ WRITE_ONCE(tm->tcpm_stamp, jiffies); + + val = 0; + if (dst_metric_locked(dst, RTAX_RTT)) +@@ -110,30 +115,42 @@ static void tcpm_suck_dst(struct tcp_metrics_block *tm, + val |= 1 << TCP_METRIC_CWND; + if (dst_metric_locked(dst, RTAX_REORDERING)) + val |= 1 << TCP_METRIC_REORDERING; +- tm->tcpm_lock = val; ++ /* Paired with READ_ONCE() in tcp_metric_locked() */ ++ WRITE_ONCE(tm->tcpm_lock, val); + + msval = dst_metric_raw(dst, RTAX_RTT); +- tm->tcpm_vals[TCP_METRIC_RTT] = msval * USEC_PER_MSEC; ++ tcp_metric_set(tm, TCP_METRIC_RTT, msval * USEC_PER_MSEC); + + msval = dst_metric_raw(dst, RTAX_RTTVAR); +- tm->tcpm_vals[TCP_METRIC_RTTVAR] = msval * USEC_PER_MSEC; +- tm->tcpm_vals[TCP_METRIC_SSTHRESH] = dst_metric_raw(dst, RTAX_SSTHRESH); +- tm->tcpm_vals[TCP_METRIC_CWND] = dst_metric_raw(dst, RTAX_CWND); +- tm->tcpm_vals[TCP_METRIC_REORDERING] = dst_metric_raw(dst, RTAX_REORDERING); ++ tcp_metric_set(tm, TCP_METRIC_RTTVAR, msval * USEC_PER_MSEC); ++ tcp_metric_set(tm, TCP_METRIC_SSTHRESH, ++ dst_metric_raw(dst, RTAX_SSTHRESH)); ++ tcp_metric_set(tm, TCP_METRIC_CWND, ++ dst_metric_raw(dst, RTAX_CWND)); ++ tcp_metric_set(tm, TCP_METRIC_REORDERING, ++ dst_metric_raw(dst, RTAX_REORDERING)); + if (fastopen_clear) { ++ write_seqlock(&fastopen_seqlock); + tm->tcpm_fastopen.mss = 0; + tm->tcpm_fastopen.syn_loss = 0; + tm->tcpm_fastopen.try_exp = 0; + tm->tcpm_fastopen.cookie.exp = false; + tm->tcpm_fastopen.cookie.len = 0; ++ write_sequnlock(&fastopen_seqlock); + } + } + + #define TCP_METRICS_TIMEOUT (60 * 60 * HZ) + +-static void tcpm_check_stamp(struct tcp_metrics_block *tm, struct dst_entry *dst) ++static void tcpm_check_stamp(struct tcp_metrics_block *tm, ++ const struct dst_entry *dst) + { +- if (tm && unlikely(time_after(jiffies, tm->tcpm_stamp + TCP_METRICS_TIMEOUT))) ++ unsigned long limit; ++ ++ if (!tm) ++ return; ++ limit = READ_ONCE(tm->tcpm_stamp) + TCP_METRICS_TIMEOUT; ++ if (unlikely(time_after(jiffies, limit))) + tcpm_suck_dst(tm, dst, false); + } + +@@ -174,20 +191,23 @@ static struct tcp_metrics_block *tcpm_new(struct dst_entry *dst, + oldest = deref_locked(tcp_metrics_hash[hash].chain); + for (tm = deref_locked(oldest->tcpm_next); tm; + tm = deref_locked(tm->tcpm_next)) { +- if (time_before(tm->tcpm_stamp, oldest->tcpm_stamp)) ++ if (time_before(READ_ONCE(tm->tcpm_stamp), ++ READ_ONCE(oldest->tcpm_stamp))) + oldest = tm; + } + tm = oldest; + } else { +- tm = kmalloc(sizeof(*tm), GFP_ATOMIC); ++ tm = kzalloc(sizeof(*tm), GFP_ATOMIC); + if (!tm) + goto out_unlock; + } +- write_pnet(&tm->tcpm_net, net); ++ /* Paired with the READ_ONCE() in tm_net() */ ++ WRITE_ONCE(tm->tcpm_net, net); ++ + tm->tcpm_saddr = *saddr; + tm->tcpm_daddr = *daddr; + +- tcpm_suck_dst(tm, dst, true); ++ tcpm_suck_dst(tm, dst, reclaim); + + if (likely(!reclaim)) { + tm->tcpm_next = tcp_metrics_hash[hash].chain; +@@ -431,7 +451,7 @@ void tcp_update_metrics(struct sock *sk) + tp->reordering); + } + } +- tm->tcpm_stamp = jiffies; ++ WRITE_ONCE(tm->tcpm_stamp, jiffies); + out_unlock: + rcu_read_unlock(); + } +@@ -534,8 +554,6 @@ bool tcp_peer_is_proven(struct request_sock *req, struct dst_entry *dst) + return ret; + } + +-static DEFINE_SEQLOCK(fastopen_seqlock); +- + void tcp_fastopen_cache_get(struct sock *sk, u16 *mss, + struct tcp_fastopen_cookie *cookie) + { +@@ -642,7 +660,7 @@ static int tcp_metrics_fill_info(struct sk_buff *msg, + } + + if (nla_put_msecs(msg, TCP_METRICS_ATTR_AGE, +- jiffies - tm->tcpm_stamp, ++ jiffies - READ_ONCE(tm->tcpm_stamp), + TCP_METRICS_ATTR_PAD) < 0) + goto nla_put_failure; + +@@ -653,7 +671,7 @@ static int tcp_metrics_fill_info(struct sk_buff *msg, + if (!nest) + goto nla_put_failure; + for (i = 0; i < TCP_METRIC_MAX_KERNEL + 1; i++) { +- u32 val = tm->tcpm_vals[i]; ++ u32 val = tcp_metric_get(tm, i); + + if (!val) + continue; +diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c +index 46e3c939958bb..a4c3cb72bdc6a 100644 +--- a/net/ipv6/addrconf.c ++++ b/net/ipv6/addrconf.c +@@ -2541,12 +2541,18 @@ static void manage_tempaddrs(struct inet6_dev *idev, + ipv6_ifa_notify(0, ift); + } + +- if ((create || list_empty(&idev->tempaddr_list)) && +- idev->cnf.use_tempaddr > 0) { ++ /* Also create a temporary address if it's enabled but no temporary ++ * address currently exists. ++ * However, we get called with valid_lft == 0, prefered_lft == 0, create == false ++ * as part of cleanup (ie. deleting the mngtmpaddr). ++ * We don't want that to result in creating a new temporary ip address. ++ */ ++ if (list_empty(&idev->tempaddr_list) && (valid_lft || prefered_lft)) ++ create = true; ++ ++ if (create && idev->cnf.use_tempaddr > 0) { + /* When a new public address is created as described + * in [ADDRCONF], also create a new temporary address. +- * Also create a temporary address if it's enabled but +- * no temporary address currently exists. + */ + read_unlock_bh(&idev->lock); + ipv6_create_tempaddr(ifp, NULL, false); +diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c +index 6248e00c2bf72..6642bc7b9870f 100644 +--- a/net/ipv6/ip6mr.c ++++ b/net/ipv6/ip6mr.c +@@ -1065,7 +1065,7 @@ static int ip6mr_cache_report(struct mr_table *mrt, struct sk_buff *pkt, + And all this only to mangle msg->im6_msgtype and + to set msg->im6_mbz to "mbz" :-) + */ +- skb_push(skb, -skb_network_offset(pkt)); ++ __skb_pull(skb, skb_network_offset(pkt)); + + skb_push(skb, sizeof(*msg)); + skb_reset_transport_header(skb); +diff --git a/net/sched/cls_fw.c b/net/sched/cls_fw.c +index 41f0898a5a565..08c41f1976c47 100644 +--- a/net/sched/cls_fw.c ++++ b/net/sched/cls_fw.c +@@ -266,7 +266,6 @@ static int fw_change(struct net *net, struct sk_buff *in_skb, + return -ENOBUFS; + + fnew->id = f->id; +- fnew->res = f->res; + fnew->ifindex = f->ifindex; + fnew->tp = f->tp; + +diff --git a/net/sched/cls_route.c b/net/sched/cls_route.c +index b775e681cb56e..1ad4b3e60eb3b 100644 +--- a/net/sched/cls_route.c ++++ b/net/sched/cls_route.c +@@ -511,7 +511,6 @@ static int route4_change(struct net *net, struct sk_buff *in_skb, + if (fold) { + f->id = fold->id; + f->iif = fold->iif; +- f->res = fold->res; + f->handle = fold->handle; + + f->tp = fold->tp; +diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c +index e5cc2b4d38d5a..65598207a2fcb 100644 +--- a/net/sched/cls_u32.c ++++ b/net/sched/cls_u32.c +@@ -814,7 +814,6 @@ static struct tc_u_knode *u32_init_knode(struct net *net, struct tcf_proto *tp, + + new->ifindex = n->ifindex; + new->fshift = n->fshift; +- new->res = n->res; + new->flags = n->flags; + RCU_INIT_POINTER(new->ht_down, ht); + +@@ -1004,18 +1003,62 @@ static int u32_change(struct net *net, struct sk_buff *in_skb, + return -EINVAL; + } + ++ /* At this point, we need to derive the new handle that will be used to ++ * uniquely map the identity of this table match entry. The ++ * identity of the entry that we need to construct is 32 bits made of: ++ * htid(12b):bucketid(8b):node/entryid(12b) ++ * ++ * At this point _we have the table(ht)_ in which we will insert this ++ * entry. We carry the table's id in variable "htid". ++ * Note that earlier code picked the ht selection either by a) the user ++ * providing the htid specified via TCA_U32_HASH attribute or b) when ++ * no such attribute is passed then the root ht, is default to at ID ++ * 0x[800][00][000]. Rule: the root table has a single bucket with ID 0. ++ * If OTOH the user passed us the htid, they may also pass a bucketid of ++ * choice. 0 is fine. For example a user htid is 0x[600][01][000] it is ++ * indicating hash bucketid of 1. Rule: the entry/node ID _cannot_ be ++ * passed via the htid, so even if it was non-zero it will be ignored. ++ * ++ * We may also have a handle, if the user passed one. The handle also ++ * carries the same addressing of htid(12b):bucketid(8b):node/entryid(12b). ++ * Rule: the bucketid on the handle is ignored even if one was passed; ++ * rather the value on "htid" is always assumed to be the bucketid. ++ */ + if (handle) { ++ /* Rule: The htid from handle and tableid from htid must match */ + if (TC_U32_HTID(handle) && TC_U32_HTID(handle ^ htid)) { + NL_SET_ERR_MSG_MOD(extack, "Handle specified hash table address mismatch"); + return -EINVAL; + } +- handle = htid | TC_U32_NODE(handle); +- err = idr_alloc_u32(&ht->handle_idr, NULL, &handle, handle, +- GFP_KERNEL); +- if (err) +- return err; +- } else ++ /* Ok, so far we have a valid htid(12b):bucketid(8b) but we ++ * need to finalize the table entry identification with the last ++ * part - the node/entryid(12b)). Rule: Nodeid _cannot be 0_ for ++ * entries. Rule: nodeid of 0 is reserved only for tables(see ++ * earlier code which processes TC_U32_DIVISOR attribute). ++ * Rule: The nodeid can only be derived from the handle (and not ++ * htid). ++ * Rule: if the handle specified zero for the node id example ++ * 0x60000000, then pick a new nodeid from the pool of IDs ++ * this hash table has been allocating from. ++ * If OTOH it is specified (i.e for example the user passed a ++ * handle such as 0x60000123), then we use it generate our final ++ * handle which is used to uniquely identify the match entry. ++ */ ++ if (!TC_U32_NODE(handle)) { ++ handle = gen_new_kid(ht, htid); ++ } else { ++ handle = htid | TC_U32_NODE(handle); ++ err = idr_alloc_u32(&ht->handle_idr, NULL, &handle, ++ handle, GFP_KERNEL); ++ if (err) ++ return err; ++ } ++ } else { ++ /* The user did not give us a handle; lets just generate one ++ * from the table's pool of nodeids. ++ */ + handle = gen_new_kid(ht, htid); ++ } + + if (tb[TCA_U32_SEL] == NULL) { + NL_SET_ERR_MSG_MOD(extack, "Selector not specified"); +diff --git a/net/sched/sch_mqprio.c b/net/sched/sch_mqprio.c +index 50e15add6068f..56d3dc5e95c7c 100644 +--- a/net/sched/sch_mqprio.c ++++ b/net/sched/sch_mqprio.c +@@ -130,6 +130,97 @@ static int parse_attr(struct nlattr *tb[], int maxtype, struct nlattr *nla, + return 0; + } + ++static int mqprio_parse_nlattr(struct Qdisc *sch, struct tc_mqprio_qopt *qopt, ++ struct nlattr *opt, ++ struct netlink_ext_ack *extack) ++{ ++ struct mqprio_sched *priv = qdisc_priv(sch); ++ struct nlattr *tb[TCA_MQPRIO_MAX + 1]; ++ struct nlattr *attr; ++ int i, rem, err; ++ ++ err = parse_attr(tb, TCA_MQPRIO_MAX, opt, mqprio_policy, ++ sizeof(*qopt)); ++ if (err < 0) ++ return err; ++ ++ if (!qopt->hw) { ++ NL_SET_ERR_MSG(extack, ++ "mqprio TCA_OPTIONS can only contain netlink attributes in hardware mode"); ++ return -EINVAL; ++ } ++ ++ if (tb[TCA_MQPRIO_MODE]) { ++ priv->flags |= TC_MQPRIO_F_MODE; ++ priv->mode = *(u16 *)nla_data(tb[TCA_MQPRIO_MODE]); ++ } ++ ++ if (tb[TCA_MQPRIO_SHAPER]) { ++ priv->flags |= TC_MQPRIO_F_SHAPER; ++ priv->shaper = *(u16 *)nla_data(tb[TCA_MQPRIO_SHAPER]); ++ } ++ ++ if (tb[TCA_MQPRIO_MIN_RATE64]) { ++ if (priv->shaper != TC_MQPRIO_SHAPER_BW_RATE) { ++ NL_SET_ERR_MSG_ATTR(extack, tb[TCA_MQPRIO_MIN_RATE64], ++ "min_rate accepted only when shaper is in bw_rlimit mode"); ++ return -EINVAL; ++ } ++ i = 0; ++ nla_for_each_nested(attr, tb[TCA_MQPRIO_MIN_RATE64], ++ rem) { ++ if (nla_type(attr) != TCA_MQPRIO_MIN_RATE64) { ++ NL_SET_ERR_MSG_ATTR(extack, attr, ++ "Attribute type expected to be TCA_MQPRIO_MIN_RATE64"); ++ return -EINVAL; ++ } ++ ++ if (nla_len(attr) != sizeof(u64)) { ++ NL_SET_ERR_MSG_ATTR(extack, attr, ++ "Attribute TCA_MQPRIO_MIN_RATE64 expected to have 8 bytes length"); ++ return -EINVAL; ++ } ++ ++ if (i >= qopt->num_tc) ++ break; ++ priv->min_rate[i] = *(u64 *)nla_data(attr); ++ i++; ++ } ++ priv->flags |= TC_MQPRIO_F_MIN_RATE; ++ } ++ ++ if (tb[TCA_MQPRIO_MAX_RATE64]) { ++ if (priv->shaper != TC_MQPRIO_SHAPER_BW_RATE) { ++ NL_SET_ERR_MSG_ATTR(extack, tb[TCA_MQPRIO_MAX_RATE64], ++ "max_rate accepted only when shaper is in bw_rlimit mode"); ++ return -EINVAL; ++ } ++ i = 0; ++ nla_for_each_nested(attr, tb[TCA_MQPRIO_MAX_RATE64], ++ rem) { ++ if (nla_type(attr) != TCA_MQPRIO_MAX_RATE64) { ++ NL_SET_ERR_MSG_ATTR(extack, attr, ++ "Attribute type expected to be TCA_MQPRIO_MAX_RATE64"); ++ return -EINVAL; ++ } ++ ++ if (nla_len(attr) != sizeof(u64)) { ++ NL_SET_ERR_MSG_ATTR(extack, attr, ++ "Attribute TCA_MQPRIO_MAX_RATE64 expected to have 8 bytes length"); ++ return -EINVAL; ++ } ++ ++ if (i >= qopt->num_tc) ++ break; ++ priv->max_rate[i] = *(u64 *)nla_data(attr); ++ i++; ++ } ++ priv->flags |= TC_MQPRIO_F_MAX_RATE; ++ } ++ ++ return 0; ++} ++ + static int mqprio_init(struct Qdisc *sch, struct nlattr *opt, + struct netlink_ext_ack *extack) + { +@@ -139,9 +230,6 @@ static int mqprio_init(struct Qdisc *sch, struct nlattr *opt, + struct Qdisc *qdisc; + int i, err = -EOPNOTSUPP; + struct tc_mqprio_qopt *qopt = NULL; +- struct nlattr *tb[TCA_MQPRIO_MAX + 1]; +- struct nlattr *attr; +- int rem; + int len; + + BUILD_BUG_ON(TC_MAX_QUEUE != TC_QOPT_MAX_QUEUE); +@@ -166,55 +254,9 @@ static int mqprio_init(struct Qdisc *sch, struct nlattr *opt, + + len = nla_len(opt) - NLA_ALIGN(sizeof(*qopt)); + if (len > 0) { +- err = parse_attr(tb, TCA_MQPRIO_MAX, opt, mqprio_policy, +- sizeof(*qopt)); +- if (err < 0) ++ err = mqprio_parse_nlattr(sch, qopt, opt, extack); ++ if (err) + return err; +- +- if (!qopt->hw) +- return -EINVAL; +- +- if (tb[TCA_MQPRIO_MODE]) { +- priv->flags |= TC_MQPRIO_F_MODE; +- priv->mode = *(u16 *)nla_data(tb[TCA_MQPRIO_MODE]); +- } +- +- if (tb[TCA_MQPRIO_SHAPER]) { +- priv->flags |= TC_MQPRIO_F_SHAPER; +- priv->shaper = *(u16 *)nla_data(tb[TCA_MQPRIO_SHAPER]); +- } +- +- if (tb[TCA_MQPRIO_MIN_RATE64]) { +- if (priv->shaper != TC_MQPRIO_SHAPER_BW_RATE) +- return -EINVAL; +- i = 0; +- nla_for_each_nested(attr, tb[TCA_MQPRIO_MIN_RATE64], +- rem) { +- if (nla_type(attr) != TCA_MQPRIO_MIN_RATE64) +- return -EINVAL; +- if (i >= qopt->num_tc) +- break; +- priv->min_rate[i] = *(u64 *)nla_data(attr); +- i++; +- } +- priv->flags |= TC_MQPRIO_F_MIN_RATE; +- } +- +- if (tb[TCA_MQPRIO_MAX_RATE64]) { +- if (priv->shaper != TC_MQPRIO_SHAPER_BW_RATE) +- return -EINVAL; +- i = 0; +- nla_for_each_nested(attr, tb[TCA_MQPRIO_MAX_RATE64], +- rem) { +- if (nla_type(attr) != TCA_MQPRIO_MAX_RATE64) +- return -EINVAL; +- if (i >= qopt->num_tc) +- break; +- priv->max_rate[i] = *(u64 *)nla_data(attr); +- i++; +- } +- priv->flags |= TC_MQPRIO_F_MAX_RATE; +- } + } + + /* pre-allocate qdisc, attachment can't fail */ +diff --git a/net/sched/sch_qfq.c b/net/sched/sch_qfq.c +index 603bd3097bd84..34a54dcd95f23 100644 +--- a/net/sched/sch_qfq.c ++++ b/net/sched/sch_qfq.c +@@ -375,8 +375,13 @@ static int qfq_change_agg(struct Qdisc *sch, struct qfq_class *cl, u32 weight, + u32 lmax) + { + struct qfq_sched *q = qdisc_priv(sch); +- struct qfq_aggregate *new_agg = qfq_find_agg(q, lmax, weight); ++ struct qfq_aggregate *new_agg; + ++ /* 'lmax' can range from [QFQ_MIN_LMAX, pktlen + stab overhead] */ ++ if (lmax > (1UL << QFQ_MTU_SHIFT)) ++ return -EINVAL; ++ ++ new_agg = qfq_find_agg(q, lmax, weight); + if (new_agg == NULL) { /* create new aggregate */ + new_agg = kzalloc(sizeof(*new_agg), GFP_ATOMIC); + if (new_agg == NULL) +diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c +index 01fd049da104a..f966b64d2939a 100644 +--- a/net/unix/af_unix.c ++++ b/net/unix/af_unix.c +@@ -701,7 +701,7 @@ static int unix_set_peek_off(struct sock *sk, int val) + if (mutex_lock_interruptible(&u->iolock)) + return -EINTR; + +- sk->sk_peek_off = val; ++ WRITE_ONCE(sk->sk_peek_off, val); + mutex_unlock(&u->iolock); + + return 0; +diff --git a/security/keys/request_key.c b/security/keys/request_key.c +index 17c9c0cfb6f59..964e2456f34da 100644 +--- a/security/keys/request_key.c ++++ b/security/keys/request_key.c +@@ -401,17 +401,21 @@ static int construct_alloc_key(struct keyring_search_context *ctx, + set_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags); + + if (dest_keyring) { +- ret = __key_link_lock(dest_keyring, &ctx->index_key); ++ ret = __key_link_lock(dest_keyring, &key->index_key); + if (ret < 0) + goto link_lock_failed; +- ret = __key_link_begin(dest_keyring, &ctx->index_key, &edit); +- if (ret < 0) +- goto link_prealloc_failed; + } + +- /* attach the key to the destination keyring under lock, but we do need ++ /* ++ * Attach the key to the destination keyring under lock, but we do need + * to do another check just in case someone beat us to it whilst we +- * waited for locks */ ++ * waited for locks. ++ * ++ * The caller might specify a comparison function which looks for keys ++ * that do not exactly match but are still equivalent from the caller's ++ * perspective. The __key_link_begin() operation must be done only after ++ * an actual key is determined. ++ */ + mutex_lock(&key_construction_mutex); + + rcu_read_lock(); +@@ -420,12 +424,16 @@ static int construct_alloc_key(struct keyring_search_context *ctx, + if (!IS_ERR(key_ref)) + goto key_already_present; + +- if (dest_keyring) ++ if (dest_keyring) { ++ ret = __key_link_begin(dest_keyring, &key->index_key, &edit); ++ if (ret < 0) ++ goto link_alloc_failed; + __key_link(key, &edit); ++ } + + mutex_unlock(&key_construction_mutex); + if (dest_keyring) +- __key_link_end(dest_keyring, &ctx->index_key, edit); ++ __key_link_end(dest_keyring, &key->index_key, edit); + mutex_unlock(&user->cons_lock); + *_key = key; + kleave(" = 0 [%d]", key_serial(key)); +@@ -438,10 +446,13 @@ key_already_present: + mutex_unlock(&key_construction_mutex); + key = key_ref_to_ptr(key_ref); + if (dest_keyring) { ++ ret = __key_link_begin(dest_keyring, &key->index_key, &edit); ++ if (ret < 0) ++ goto link_alloc_failed_unlocked; + ret = __key_link_check_live_key(dest_keyring, key); + if (ret == 0) + __key_link(key, &edit); +- __key_link_end(dest_keyring, &ctx->index_key, edit); ++ __key_link_end(dest_keyring, &key->index_key, edit); + if (ret < 0) + goto link_check_failed; + } +@@ -456,8 +467,10 @@ link_check_failed: + kleave(" = %d [linkcheck]", ret); + return ret; + +-link_prealloc_failed: +- __key_link_end(dest_keyring, &ctx->index_key, edit); ++link_alloc_failed: ++ mutex_unlock(&key_construction_mutex); ++link_alloc_failed_unlocked: ++ __key_link_end(dest_keyring, &key->index_key, edit); + link_lock_failed: + mutex_unlock(&user->cons_lock); + key_put(key); +diff --git a/sound/soc/codecs/cs42l51-i2c.c b/sound/soc/codecs/cs42l51-i2c.c +index 70260e0a8f095..3ff73367897d8 100644 +--- a/sound/soc/codecs/cs42l51-i2c.c ++++ b/sound/soc/codecs/cs42l51-i2c.c +@@ -19,6 +19,12 @@ static struct i2c_device_id cs42l51_i2c_id[] = { + }; + MODULE_DEVICE_TABLE(i2c, cs42l51_i2c_id); + ++const struct of_device_id cs42l51_of_match[] = { ++ { .compatible = "cirrus,cs42l51", }, ++ { } ++}; ++MODULE_DEVICE_TABLE(of, cs42l51_of_match); ++ + static int cs42l51_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) + { +diff --git a/sound/soc/codecs/cs42l51.c b/sound/soc/codecs/cs42l51.c +index cdd7ae90c2b59..07371e32167c8 100644 +--- a/sound/soc/codecs/cs42l51.c ++++ b/sound/soc/codecs/cs42l51.c +@@ -811,13 +811,6 @@ int __maybe_unused cs42l51_resume(struct device *dev) + } + EXPORT_SYMBOL_GPL(cs42l51_resume); + +-const struct of_device_id cs42l51_of_match[] = { +- { .compatible = "cirrus,cs42l51", }, +- { } +-}; +-MODULE_DEVICE_TABLE(of, cs42l51_of_match); +-EXPORT_SYMBOL_GPL(cs42l51_of_match); +- + MODULE_AUTHOR("Arnaud Patard "); + MODULE_DESCRIPTION("Cirrus Logic CS42L51 ALSA SoC Codec Driver"); + MODULE_LICENSE("GPL"); +diff --git a/sound/soc/codecs/cs42l51.h b/sound/soc/codecs/cs42l51.h +index 9d06cf7f88768..4f13c38484b7f 100644 +--- a/sound/soc/codecs/cs42l51.h ++++ b/sound/soc/codecs/cs42l51.h +@@ -16,7 +16,6 @@ int cs42l51_probe(struct device *dev, struct regmap *regmap); + int cs42l51_remove(struct device *dev); + int __maybe_unused cs42l51_suspend(struct device *dev); + int __maybe_unused cs42l51_resume(struct device *dev); +-extern const struct of_device_id cs42l51_of_match[]; + + #define CS42L51_CHIP_ID 0x1B + #define CS42L51_CHIP_REV_A 0x00 +diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c +index 9e8c564f6e9c4..9787257b69a92 100644 +--- a/sound/soc/codecs/wm8904.c ++++ b/sound/soc/codecs/wm8904.c +@@ -2276,6 +2276,9 @@ static int wm8904_i2c_probe(struct i2c_client *i2c, + regmap_update_bits(wm8904->regmap, WM8904_BIAS_CONTROL_0, + WM8904_POBCTRL, 0); + ++ /* Fill the cache for the ADC test register */ ++ regmap_read(wm8904->regmap, WM8904_ADC_TEST_0, &val); ++ + /* Can leave the device powered off until we need it */ + regcache_cache_only(wm8904->regmap, true); + regulator_bulk_disable(ARRAY_SIZE(wm8904->supplies), wm8904->supplies); +diff --git a/sound/soc/fsl/fsl_spdif.c b/sound/soc/fsl/fsl_spdif.c +index 7858a5499ac5d..4fd4ba9972afd 100644 +--- a/sound/soc/fsl/fsl_spdif.c ++++ b/sound/soc/fsl/fsl_spdif.c +@@ -615,6 +615,8 @@ static int fsl_spdif_trigger(struct snd_pcm_substream *substream, + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + regmap_update_bits(regmap, REG_SPDIF_SCR, dmaen, 0); + regmap_update_bits(regmap, REG_SPDIF_SIE, intr, 0); ++ regmap_write(regmap, REG_SPDIF_STL, 0x0); ++ regmap_write(regmap, REG_SPDIF_STR, 0x0); + break; + default: + return -EINVAL; +diff --git a/tools/perf/tests/shell/test_uprobe_from_different_cu.sh b/tools/perf/tests/shell/test_uprobe_from_different_cu.sh +index 00d2e0e2e0c28..319f36ebb9a40 100644 +--- a/tools/perf/tests/shell/test_uprobe_from_different_cu.sh ++++ b/tools/perf/tests/shell/test_uprobe_from_different_cu.sh +@@ -4,6 +4,12 @@ + + set -e + ++# skip if there's no gcc ++if ! [ -x "$(command -v gcc)" ]; then ++ echo "failed: no gcc compiler" ++ exit 2 ++fi ++ + temp_dir=$(mktemp -d /tmp/perf-uprobe-different-cu-sh.XXXXXXXXXX) + + cleanup() +@@ -11,7 +17,7 @@ cleanup() + trap - EXIT TERM INT + if [[ "${temp_dir}" =~ ^/tmp/perf-uprobe-different-cu-sh.*$ ]]; then + echo "--- Cleaning up ---" +- perf probe -x ${temp_dir}/testfile -d foo ++ perf probe -x ${temp_dir}/testfile -d foo || true + rm -f "${temp_dir}/"* + rmdir "${temp_dir}" + fi +diff --git a/tools/testing/selftests/rseq/rseq.c b/tools/testing/selftests/rseq/rseq.c +index 986b9458efb26..b736a5169aad0 100644 +--- a/tools/testing/selftests/rseq/rseq.c ++++ b/tools/testing/selftests/rseq/rseq.c +@@ -32,9 +32,17 @@ + #include "../kselftest.h" + #include "rseq.h" + +-static const ptrdiff_t *libc_rseq_offset_p; +-static const unsigned int *libc_rseq_size_p; +-static const unsigned int *libc_rseq_flags_p; ++/* ++ * Define weak versions to play nice with binaries that are statically linked ++ * against a libc that doesn't support registering its own rseq. ++ */ ++__weak ptrdiff_t __rseq_offset; ++__weak unsigned int __rseq_size; ++__weak unsigned int __rseq_flags; ++ ++static const ptrdiff_t *libc_rseq_offset_p = &__rseq_offset; ++static const unsigned int *libc_rseq_size_p = &__rseq_size; ++static const unsigned int *libc_rseq_flags_p = &__rseq_flags; + + /* Offset from the thread pointer to the rseq area. */ + ptrdiff_t rseq_offset; +@@ -108,10 +116,19 @@ int rseq_unregister_current_thread(void) + static __attribute__((constructor)) + void rseq_init(void) + { +- libc_rseq_offset_p = dlsym(RTLD_NEXT, "__rseq_offset"); +- libc_rseq_size_p = dlsym(RTLD_NEXT, "__rseq_size"); +- libc_rseq_flags_p = dlsym(RTLD_NEXT, "__rseq_flags"); +- if (libc_rseq_size_p && libc_rseq_offset_p && libc_rseq_flags_p) { ++ /* ++ * If the libc's registered rseq size isn't already valid, it may be ++ * because the binary is dynamically linked and not necessarily due to ++ * libc not having registered a restartable sequence. Try to find the ++ * symbols if that's the case. ++ */ ++ if (!*libc_rseq_size_p) { ++ libc_rseq_offset_p = dlsym(RTLD_NEXT, "__rseq_offset"); ++ libc_rseq_size_p = dlsym(RTLD_NEXT, "__rseq_size"); ++ libc_rseq_flags_p = dlsym(RTLD_NEXT, "__rseq_flags"); ++ } ++ if (libc_rseq_size_p && libc_rseq_offset_p && libc_rseq_flags_p && ++ *libc_rseq_size_p != 0) { + /* rseq registration owned by glibc */ + rseq_offset = *libc_rseq_offset_p; + rseq_size = *libc_rseq_size_p;