commit:     c579c98ecd05dd166b78e1503aa5ee23e379b1fd
Author:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Thu May 22 13:40:00 2025 +0000
Commit:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Thu May 22 13:40:00 2025 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=c579c98e

Linux patch 5.15.184

Signed-off-by: Mike Pagano <mpagano <AT> gentoo.org>

 0000_README               |    4 +
 1183_linux-5.15.184.patch | 2835 +++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 2839 insertions(+)

diff --git a/0000_README b/0000_README
index f44e48d0..aec14aab 100644
--- a/0000_README
+++ b/0000_README
@@ -775,6 +775,10 @@ Patch:  1182_linux-5.15.183.patch
 From:   https://www.kernel.org
 Desc:   Linux 5.15.183
 
+Patch:  1183_linux-5.15.184.patch
+From:   https://www.kernel.org
+Desc:   Linux 5.15.184
+
 Patch:  1500_XATTR_USER_PREFIX.patch
 From:   https://bugs.gentoo.org/show_bug.cgi?id=470644
 Desc:   Support for namespace user.pax.* on tmpfs.

diff --git a/1183_linux-5.15.184.patch b/1183_linux-5.15.184.patch
new file mode 100644
index 00000000..58f68c5f
--- /dev/null
+++ b/1183_linux-5.15.184.patch
@@ -0,0 +1,2835 @@
+diff --git a/Documentation/ABI/testing/sysfs-devices-system-cpu 
b/Documentation/ABI/testing/sysfs-devices-system-cpu
+index 23e0537f6e0c79..1d657a6b1b53bd 100644
+--- a/Documentation/ABI/testing/sysfs-devices-system-cpu
++++ b/Documentation/ABI/testing/sysfs-devices-system-cpu
+@@ -512,6 +512,7 @@ Description:       information about CPUs heterogeneity.
+ 
+ What:         /sys/devices/system/cpu/vulnerabilities
+               /sys/devices/system/cpu/vulnerabilities/gather_data_sampling
++              
/sys/devices/system/cpu/vulnerabilities/indirect_target_selection
+               /sys/devices/system/cpu/vulnerabilities/itlb_multihit
+               /sys/devices/system/cpu/vulnerabilities/l1tf
+               /sys/devices/system/cpu/vulnerabilities/mds
+diff --git a/Documentation/admin-guide/hw-vuln/index.rst 
b/Documentation/admin-guide/hw-vuln/index.rst
+index 3e4a14e38b49e8..dc69ba0b05e474 100644
+--- a/Documentation/admin-guide/hw-vuln/index.rst
++++ b/Documentation/admin-guide/hw-vuln/index.rst
+@@ -22,3 +22,4 @@ are configurable at compile, boot or run time.
+    gather_data_sampling.rst
+    srso
+    reg-file-data-sampling
++   indirect-target-selection
+diff --git a/Documentation/admin-guide/hw-vuln/indirect-target-selection.rst 
b/Documentation/admin-guide/hw-vuln/indirect-target-selection.rst
+new file mode 100644
+index 00000000000000..4788e14ebce09a
+--- /dev/null
++++ b/Documentation/admin-guide/hw-vuln/indirect-target-selection.rst
+@@ -0,0 +1,156 @@
++.. SPDX-License-Identifier: GPL-2.0
++
++Indirect Target Selection (ITS)
++===============================
++
++ITS is a vulnerability in some Intel CPUs that support Enhanced IBRS and were
++released before Alder Lake. ITS may allow an attacker to control the 
prediction
++of indirect branches and RETs located in the lower half of a cacheline.
++
++ITS is assigned CVE-2024-28956 with a CVSS score of 4.7 (Medium).
++
++Scope of Impact
++---------------
++- **eIBRS Guest/Host Isolation**: Indirect branches in KVM/kernel may still be
++  predicted with unintended target corresponding to a branch in the guest.
++
++- **Intra-Mode BTI**: In-kernel training such as through cBPF or other native
++  gadgets.
++
++- **Indirect Branch Prediction Barrier (IBPB)**: After an IBPB, indirect
++  branches may still be predicted with targets corresponding to direct 
branches
++  executed prior to the IBPB. This is fixed by the IPU 2025.1 microcode, which
++  should be available via distro updates. Alternatively microcode can be
++  obtained from Intel's github repository [#f1]_.
++
++Affected CPUs
++-------------
++Below is the list of ITS affected CPUs [#f2]_ [#f3]_:
++
++   ========================  ============  ====================  
===============
++   Common name               Family_Model  eIBRS                 Intra-mode 
BTI
++                                           Guest/Host Isolation
++   ========================  ============  ====================  
===============
++   SKYLAKE_X (step >= 6)     06_55H        Affected              Affected
++   ICELAKE_X                 06_6AH        Not affected          Affected
++   ICELAKE_D                 06_6CH        Not affected          Affected
++   ICELAKE_L                 06_7EH        Not affected          Affected
++   TIGERLAKE_L               06_8CH        Not affected          Affected
++   TIGERLAKE                 06_8DH        Not affected          Affected
++   KABYLAKE_L (step >= 12)   06_8EH        Affected              Affected
++   KABYLAKE (step >= 13)     06_9EH        Affected              Affected
++   COMETLAKE                 06_A5H        Affected              Affected
++   COMETLAKE_L               06_A6H        Affected              Affected
++   ROCKETLAKE                06_A7H        Not affected          Affected
++   ========================  ============  ====================  
===============
++
++- All affected CPUs enumerate Enhanced IBRS feature.
++- IBPB isolation is affected on all ITS affected CPUs, and need a microcode
++  update for mitigation.
++- None of the affected CPUs enumerate BHI_CTRL which was introduced in Golden
++  Cove (Alder Lake and Sapphire Rapids). This can help guests to determine the
++  host's affected status.
++- Intel Atom CPUs are not affected by ITS.
++
++Mitigation
++----------
++As only the indirect branches and RETs that have their last byte of 
instruction
++in the lower half of the cacheline are vulnerable to ITS, the basic idea 
behind
++the mitigation is to not allow indirect branches in the lower half.
++
++This is achieved by relying on existing retpoline support in the kernel, and 
in
++compilers. ITS-vulnerable retpoline sites are runtime patched to point to 
newly
++added ITS-safe thunks. These safe thunks consists of indirect branch in the
++second half of the cacheline. Not all retpoline sites are patched to thunks, 
if
++a retpoline site is evaluated to be ITS-safe, it is replaced with an inline
++indirect branch.
++
++Dynamic thunks
++~~~~~~~~~~~~~~
++From a dynamically allocated pool of safe-thunks, each vulnerable site is
++replaced with a new thunk, such that they get a unique address. This could
++improve the branch prediction accuracy. Also, it is a defense-in-depth measure
++against aliasing.
++
++Note, for simplicity, indirect branches in eBPF programs are always replaced
++with a jump to a static thunk in __x86_indirect_its_thunk_array. If required,
++in future this can be changed to use dynamic thunks.
++
++All vulnerable RETs are replaced with a static thunk, they do not use dynamic
++thunks. This is because RETs get their prediction from RSB mostly that does 
not
++depend on source address. RETs that underflow RSB may benefit from dynamic
++thunks. But, RETs significantly outnumber indirect branches, and any benefit
++from a unique source address could be outweighed by the increased icache
++footprint and iTLB pressure.
++
++Retpoline
++~~~~~~~~~
++Retpoline sequence also mitigates ITS-unsafe indirect branches. For this
++reason, when retpoline is enabled, ITS mitigation only relocates the RETs to
++safe thunks. Unless user requested the RSB-stuffing mitigation.
++
++Mitigation in guests
++^^^^^^^^^^^^^^^^^^^^
++All guests deploy ITS mitigation by default, irrespective of eIBRS enumeration
++and Family/Model of the guest. This is because eIBRS feature could be hidden
++from a guest. One exception to this is when a guest enumerates BHI_DIS_S, 
which
++indicates that the guest is running on an unaffected host.
++
++To prevent guests from unnecessarily deploying the mitigation on unaffected
++platforms, Intel has defined ITS_NO bit(62) in MSR IA32_ARCH_CAPABILITIES. 
When
++a guest sees this bit set, it should not enumerate the ITS bug. Note, this bit
++is not set by any hardware, but is **intended for VMMs to synthesize** it for
++guests as per the host's affected status.
++
++Mitigation options
++^^^^^^^^^^^^^^^^^^
++The ITS mitigation can be controlled using the "indirect_target_selection"
++kernel parameter. The available options are:
++
++   ======== 
===================================================================
++   on       (default)  Deploy the "Aligned branch/return thunks" mitigation.
++          If spectre_v2 mitigation enables retpoline, aligned-thunks are only
++          deployed for the affected RET instructions. Retpoline mitigates
++          indirect branches.
++
++   off      Disable ITS mitigation.
++
++   vmexit   Equivalent to "=on" if the CPU is affected by guest/host isolation
++          part of ITS. Otherwise, mitigation is not deployed. This option is
++          useful when host userspace is not in the threat model, and only
++          attacks from guest to host are considered.
++
++   force    Force the ITS bug and deploy the default mitigation.
++   ======== 
===================================================================
++
++Sysfs reporting
++---------------
++
++The sysfs file showing ITS mitigation status is:
++
++  /sys/devices/system/cpu/vulnerabilities/indirect_target_selection
++
++Note, microcode mitigation status is not reported in this file.
++
++The possible values in this file are:
++
++.. list-table::
++
++   * - Not affected
++     - The processor is not vulnerable.
++   * - Vulnerable
++     - System is vulnerable and no mitigation has been applied.
++   * - Vulnerable, KVM: Not affected
++     - System is vulnerable to intra-mode BTI, but not affected by eIBRS
++       guest/host isolation.
++   * - Mitigation: Aligned branch/return thunks
++     - The mitigation is enabled, affected indirect branches and RETs are
++       relocated to safe thunks.
++
++References
++----------
++.. [#f1] Microcode repository - 
https://github.com/intel/Intel-Linux-Processor-Microcode-Data-Files
++
++.. [#f2] Affected Processors list - 
https://www.intel.com/content/www/us/en/developer/topic-technology/software-security-guidance/processors-affected-consolidated-product-cpu-model.html
++
++.. [#f3] Affected Processors list (machine readable) - 
https://github.com/intel/Intel-affected-processor-list
+diff --git a/Documentation/admin-guide/kernel-parameters.txt 
b/Documentation/admin-guide/kernel-parameters.txt
+index ede522c60ac4f1..4bc5d8c97d097b 100644
+--- a/Documentation/admin-guide/kernel-parameters.txt
++++ b/Documentation/admin-guide/kernel-parameters.txt
+@@ -1926,6 +1926,20 @@
+                       different crypto accelerators. This option can be used
+                       to achieve best performance for particular HW.
+ 
++      indirect_target_selection= [X86,Intel] Mitigation control for Indirect
++                      Target Selection(ITS) bug in Intel CPUs. Updated
++                      microcode is also required for a fix in IBPB.
++
++                      on:     Enable mitigation (default).
++                      off:    Disable mitigation.
++                      force:  Force the ITS bug and deploy default
++                              mitigation.
++                      vmexit: Only deploy mitigation if CPU is affected by
++                              guest/host isolation part of ITS.
++
++                      For details see:
++                      
Documentation/admin-guide/hw-vuln/indirect-target-selection.rst
++
+       init=           [KNL]
+                       Format: <full_path>
+                       Run specified binary instead of /sbin/init as init
+@@ -3073,6 +3087,7 @@
+                               improves system performance, but it may also
+                               expose users to several CPU vulnerabilities.
+                               Equivalent to: gather_data_sampling=off [X86]
++                                             indirect_target_selection=off 
[X86]
+                                              kpti=0 [ARM64]
+                                              kvm.nx_huge_pages=off [X86]
+                                              l1tf=off [X86]
+diff --git a/Makefile b/Makefile
+index 09de195b86f268..0840259608be33 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,7 +1,7 @@
+ # SPDX-License-Identifier: GPL-2.0
+ VERSION = 5
+ PATCHLEVEL = 15
+-SUBLEVEL = 183
++SUBLEVEL = 184
+ EXTRAVERSION =
+ NAME = Trick or Treat
+ 
+diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
+index de6a66ad3fa624..026a5714f78f39 100644
+--- a/arch/x86/Kconfig
++++ b/arch/x86/Kconfig
+@@ -2517,6 +2517,17 @@ config MITIGATION_SPECTRE_BHI
+         indirect branches.
+         See <file:Documentation/admin-guide/hw-vuln/spectre.rst>
+ 
++config MITIGATION_ITS
++      bool "Enable Indirect Target Selection mitigation"
++      depends on CPU_SUP_INTEL && X86_64
++      depends on RETPOLINE && RETHUNK
++      default y
++      help
++        Enable Indirect Target Selection (ITS) mitigation. ITS is a bug in
++        BPU on some Intel CPUs that may allow Spectre V2 style attacks. If
++        disabled, mitigation cannot be enabled via cmdline.
++        See 
<file:Documentation/admin-guide/hw-vuln/indirect-target-selection.rst>
++
+ endif
+ 
+ config ARCH_HAS_ADD_PAGES
+diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S
+index f656c6e0e45882..ed74778c8ebd7f 100644
+--- a/arch/x86/entry/entry_64.S
++++ b/arch/x86/entry/entry_64.S
+@@ -1530,7 +1530,9 @@ SYM_CODE_END(rewind_stack_and_make_dead)
+  * ORC to unwind properly.
+  *
+  * The alignment is for performance and not for safety, and may be safely
+- * refactored in the future if needed.
++ * refactored in the future if needed. The .skips are for safety, to ensure
++ * that all RETs are in the second half of a cacheline to mitigate Indirect
++ * Target Selection, rather than taking the slowpath via its_return_thunk.
+  */
+ SYM_FUNC_START(clear_bhb_loop)
+       push    %rbp
+@@ -1540,10 +1542,22 @@ SYM_FUNC_START(clear_bhb_loop)
+       call    1f
+       jmp     5f
+       .align 64, 0xcc
++      /*
++       * Shift instructions so that the RET is in the upper half of the
++       * cacheline and don't take the slowpath to its_return_thunk.
++       */
++      .skip 32 - (.Lret1 - 1f), 0xcc
+       ANNOTATE_INTRA_FUNCTION_CALL
+ 1:    call    2f
+-      RET
++.Lret1:       RET
+       .align 64, 0xcc
++      /*
++       * As above shift instructions for RET at .Lret2 as well.
++       *
++       * This should be ideally be: .skip 32 - (.Lret2 - 2f), 0xcc
++       * but some Clang versions (e.g. 18) don't like this.
++       */
++      .skip 32 - 18, 0xcc
+ 2:    movl    $5, %eax
+ 3:    jmp     4f
+       nop
+@@ -1551,7 +1565,7 @@ SYM_FUNC_START(clear_bhb_loop)
+       jnz     3b
+       sub     $1, %ecx
+       jnz     1b
+-      RET
++.Lret2:       RET
+ 5:    lfence
+       pop     %rbp
+       RET
+diff --git a/arch/x86/include/asm/alternative.h 
b/arch/x86/include/asm/alternative.h
+index a364971967c40e..1797f80c10de4e 100644
+--- a/arch/x86/include/asm/alternative.h
++++ b/arch/x86/include/asm/alternative.h
+@@ -5,6 +5,7 @@
+ #include <linux/types.h>
+ #include <linux/stringify.h>
+ #include <asm/asm.h>
++#include <asm/bug.h>
+ 
+ #define ALTINSTR_FLAG_INV     (1 << 15)
+ #define ALT_NOT(feat)         ((feat) | ALTINSTR_FLAG_INV)
+@@ -80,6 +81,37 @@ extern void apply_returns(s32 *start, s32 *end);
+ 
+ struct module;
+ 
++#ifdef CONFIG_MITIGATION_ITS
++extern void its_init_mod(struct module *mod);
++extern void its_fini_mod(struct module *mod);
++extern void its_free_mod(struct module *mod);
++extern u8 *its_static_thunk(int reg);
++#else /* CONFIG_MITIGATION_ITS */
++static inline void its_init_mod(struct module *mod) { }
++static inline void its_fini_mod(struct module *mod) { }
++static inline void its_free_mod(struct module *mod) { }
++static inline u8 *its_static_thunk(int reg)
++{
++      WARN_ONCE(1, "ITS not compiled in");
++
++      return NULL;
++}
++#endif
++
++#ifdef CONFIG_RETHUNK
++extern bool cpu_wants_rethunk(void);
++extern bool cpu_wants_rethunk_at(void *addr);
++#else
++static __always_inline bool cpu_wants_rethunk(void)
++{
++      return false;
++}
++static __always_inline bool cpu_wants_rethunk_at(void *addr)
++{
++      return false;
++}
++#endif
++
+ #ifdef CONFIG_SMP
+ extern void alternatives_smp_module_add(struct module *mod, char *name,
+                                       void *locks, void *locks_end,
+diff --git a/arch/x86/include/asm/cpufeatures.h 
b/arch/x86/include/asm/cpufeatures.h
+index 4faa47cc1a5c3c..e2bf1cba02cdde 100644
+--- a/arch/x86/include/asm/cpufeatures.h
++++ b/arch/x86/include/asm/cpufeatures.h
+@@ -433,6 +433,7 @@
+ #define X86_FEATURE_BHI_CTRL          (21*32+ 2) /* "" BHI_DIS_S HW control 
available */
+ #define X86_FEATURE_CLEAR_BHB_HW      (21*32+ 3) /* "" BHI_DIS_S HW control 
enabled */
+ #define X86_FEATURE_CLEAR_BHB_LOOP_ON_VMEXIT (21*32+ 4) /* "" Clear branch 
history at vmexit using SW loop */
++#define X86_FEATURE_INDIRECT_THUNK_ITS        (21*32 + 5) /* "" Use thunk for 
indirect branches in lower half of cacheline */
+ 
+ /*
+  * BUG word(s)
+@@ -483,4 +484,6 @@
+ #define X86_BUG_RFDS                  X86_BUG(1*32 + 2) /* CPU is vulnerable 
to Register File Data Sampling */
+ #define X86_BUG_BHI                   X86_BUG(1*32 + 3) /* CPU is affected by 
Branch History Injection */
+ #define X86_BUG_IBPB_NO_RET           X86_BUG(1*32 + 4) /* "ibpb_no_ret" IBPB 
omits return target predictions */
++#define X86_BUG_ITS                   X86_BUG(1*32 + 5) /* CPU is affected by 
Indirect Target Selection */
++#define X86_BUG_ITS_NATIVE_ONLY               X86_BUG(1*32 + 6) /* CPU is 
affected by ITS, VMX is not affected */
+ #endif /* _ASM_X86_CPUFEATURES_H */
+diff --git a/arch/x86/include/asm/msr-index.h 
b/arch/x86/include/asm/msr-index.h
+index 03b12c19458892..241b688cc9b858 100644
+--- a/arch/x86/include/asm/msr-index.h
++++ b/arch/x86/include/asm/msr-index.h
+@@ -183,6 +183,14 @@
+                                                * VERW clears CPU Register
+                                                * File.
+                                                */
++#define ARCH_CAP_ITS_NO                       BIT_ULL(62) /*
++                                                   * Not susceptible to
++                                                   * Indirect Target 
Selection.
++                                                   * This bit is not set by
++                                                   * HW, but is synthesized by
++                                                   * VMMs for guests to know
++                                                   * their affected status.
++                                                   */
+ 
+ #define MSR_IA32_FLUSH_CMD            0x0000010b
+ #define L1D_FLUSH                     BIT(0)  /*
+diff --git a/arch/x86/include/asm/nospec-branch.h 
b/arch/x86/include/asm/nospec-branch.h
+index bdf22582a8c013..17156b61fcc32d 100644
+--- a/arch/x86/include/asm/nospec-branch.h
++++ b/arch/x86/include/asm/nospec-branch.h
+@@ -118,6 +118,18 @@
+ #endif
+ .endm
+ 
++/*
++ * Emits a conditional CS prefix that is compatible with
++ * -mindirect-branch-cs-prefix.
++ */
++.macro __CS_PREFIX reg:req
++      .irp rs,r8,r9,r10,r11,r12,r13,r14,r15
++      .ifc \reg,\rs
++      .byte 0x2e
++      .endif
++      .endr
++.endm
++
+ /*
+  * JMP_NOSPEC and CALL_NOSPEC macros can be used instead of a simple
+  * indirect jmp/call which may be susceptible to the Spectre variant 2
+@@ -125,19 +137,18 @@
+  */
+ .macro JMP_NOSPEC reg:req
+ #ifdef CONFIG_RETPOLINE
+-      ALTERNATIVE_2 __stringify(ANNOTATE_RETPOLINE_SAFE; jmp *%\reg), \
+-                    __stringify(jmp __x86_indirect_thunk_\reg), 
X86_FEATURE_RETPOLINE, \
+-                    __stringify(lfence; ANNOTATE_RETPOLINE_SAFE; jmp *%\reg), 
X86_FEATURE_RETPOLINE_LFENCE
++      __CS_PREFIX \reg
++      jmp     __x86_indirect_thunk_\reg
+ #else
+       jmp     *%\reg
++      int3
+ #endif
+ .endm
+ 
+ .macro CALL_NOSPEC reg:req
+ #ifdef CONFIG_RETPOLINE
+-      ALTERNATIVE_2 __stringify(ANNOTATE_RETPOLINE_SAFE; call *%\reg), \
+-                    __stringify(call __x86_indirect_thunk_\reg), 
X86_FEATURE_RETPOLINE, \
+-                    __stringify(lfence; ANNOTATE_RETPOLINE_SAFE; call 
*%\reg), X86_FEATURE_RETPOLINE_LFENCE
++      __CS_PREFIX \reg
++      call    __x86_indirect_thunk_\reg
+ #else
+       call    *%\reg
+ #endif
+@@ -239,6 +250,12 @@ extern void __x86_return_thunk(void);
+ static inline void __x86_return_thunk(void) {}
+ #endif
+ 
++#ifdef CONFIG_MITIGATION_ITS
++extern void its_return_thunk(void);
++#else
++static inline void its_return_thunk(void) {}
++#endif
++
+ extern void retbleed_return_thunk(void);
+ extern void srso_return_thunk(void);
+ extern void srso_alias_return_thunk(void);
+@@ -260,6 +277,11 @@ extern void (*x86_return_thunk)(void);
+ 
+ typedef u8 retpoline_thunk_t[RETPOLINE_THUNK_SIZE];
+ 
++#define ITS_THUNK_SIZE        64
++typedef u8 its_thunk_t[ITS_THUNK_SIZE];
++
++extern its_thunk_t     __x86_indirect_its_thunk_array[];
++
+ #define GEN(reg) \
+       extern retpoline_thunk_t __x86_indirect_thunk_ ## reg;
+ #include <asm/GEN-for-each-reg.h>
+@@ -269,20 +291,23 @@ extern retpoline_thunk_t __x86_indirect_thunk_array[];
+ 
+ #ifdef CONFIG_X86_64
+ 
++/*
++ * Emits a conditional CS prefix that is compatible with
++ * -mindirect-branch-cs-prefix.
++ */
++#define __CS_PREFIX(reg)                              \
++      ".irp rs,r8,r9,r10,r11,r12,r13,r14,r15\n"       \
++      ".ifc \\rs," reg "\n"                           \
++      ".byte 0x2e\n"                                  \
++      ".endif\n"                                      \
++      ".endr\n"
++
+ /*
+  * Inline asm uses the %V modifier which is only in newer GCC
+  * which is ensured when CONFIG_RETPOLINE is defined.
+  */
+-# define CALL_NOSPEC                                          \
+-      ALTERNATIVE_2(                                          \
+-      ANNOTATE_RETPOLINE_SAFE                                 \
+-      "call *%[thunk_target]\n",                              \
+-      "call __x86_indirect_thunk_%V[thunk_target]\n",         \
+-      X86_FEATURE_RETPOLINE,                                  \
+-      "lfence;\n"                                             \
+-      ANNOTATE_RETPOLINE_SAFE                                 \
+-      "call *%[thunk_target]\n",                              \
+-      X86_FEATURE_RETPOLINE_LFENCE)
++#define CALL_NOSPEC   __CS_PREFIX("%V[thunk_target]") \
++                      "call __x86_indirect_thunk_%V[thunk_target]\n"
+ 
+ # define THUNK_TARGET(addr) [thunk_target] "r" (addr)
+ 
+diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c
+index 5614e6d219b756..43ec73da66d8b8 100644
+--- a/arch/x86/kernel/alternative.c
++++ b/arch/x86/kernel/alternative.c
+@@ -18,6 +18,7 @@
+ #include <linux/mmu_context.h>
+ #include <linux/bsearch.h>
+ #include <linux/sync_core.h>
++#include <linux/moduleloader.h>
+ #include <asm/text-patching.h>
+ #include <asm/alternative.h>
+ #include <asm/sections.h>
+@@ -30,6 +31,7 @@
+ #include <asm/fixmap.h>
+ #include <asm/paravirt.h>
+ #include <asm/asm-prototypes.h>
++#include <asm/set_memory.h>
+ 
+ int __read_mostly alternatives_patched;
+ 
+@@ -395,6 +397,216 @@ static int emit_indirect(int op, int reg, u8 *bytes)
+       return i;
+ }
+ 
++#ifdef CONFIG_MITIGATION_ITS
++
++#ifdef CONFIG_MODULES
++static struct module *its_mod;
++static void *its_page;
++static unsigned int its_offset;
++
++/* Initialize a thunk with the "jmp *reg; int3" instructions. */
++static void *its_init_thunk(void *thunk, int reg)
++{
++      u8 *bytes = thunk;
++      int i = 0;
++
++      if (reg >= 8) {
++              bytes[i++] = 0x41; /* REX.B prefix */
++              reg -= 8;
++      }
++      bytes[i++] = 0xff;
++      bytes[i++] = 0xe0 + reg; /* jmp *reg */
++      bytes[i++] = 0xcc;
++
++      return thunk;
++}
++
++void its_init_mod(struct module *mod)
++{
++      if (!cpu_feature_enabled(X86_FEATURE_INDIRECT_THUNK_ITS))
++              return;
++
++      mutex_lock(&text_mutex);
++      its_mod = mod;
++      its_page = NULL;
++}
++
++void its_fini_mod(struct module *mod)
++{
++      int i;
++
++      if (!cpu_feature_enabled(X86_FEATURE_INDIRECT_THUNK_ITS))
++              return;
++
++      WARN_ON_ONCE(its_mod != mod);
++
++      its_mod = NULL;
++      its_page = NULL;
++      mutex_unlock(&text_mutex);
++
++      for (i = 0; i < mod->its_num_pages; i++) {
++              void *page = mod->its_page_array[i];
++              set_memory_ro((unsigned long)page, 1);
++              set_memory_x((unsigned long)page, 1);
++      }
++}
++
++void its_free_mod(struct module *mod)
++{
++      int i;
++
++      if (!cpu_feature_enabled(X86_FEATURE_INDIRECT_THUNK_ITS))
++              return;
++
++      for (i = 0; i < mod->its_num_pages; i++) {
++              void *page = mod->its_page_array[i];
++              module_memfree(page);
++      }
++      kfree(mod->its_page_array);
++}
++
++static void *its_alloc(void)
++{
++      void *page = module_alloc(PAGE_SIZE);
++
++      if (!page)
++              return NULL;
++
++      if (its_mod) {
++              void *tmp = krealloc(its_mod->its_page_array,
++                                   (its_mod->its_num_pages+1) * sizeof(void 
*),
++                                   GFP_KERNEL);
++              if (!tmp) {
++                      module_memfree(page);
++                      return NULL;
++              }
++
++              its_mod->its_page_array = tmp;
++              its_mod->its_page_array[its_mod->its_num_pages++] = page;
++      }
++
++      return page;
++}
++
++static void *its_allocate_thunk(int reg)
++{
++      int size = 3 + (reg / 8);
++      void *thunk;
++
++      if (!its_page || (its_offset + size - 1) >= PAGE_SIZE) {
++              its_page = its_alloc();
++              if (!its_page) {
++                      pr_err("ITS page allocation failed\n");
++                      return NULL;
++              }
++              memset(its_page, INT3_INSN_OPCODE, PAGE_SIZE);
++              its_offset = 32;
++      }
++
++      /*
++       * If the indirect branch instruction will be in the lower half
++       * of a cacheline, then update the offset to reach the upper half.
++       */
++      if ((its_offset + size - 1) % 64 < 32)
++              its_offset = ((its_offset - 1) | 0x3F) + 33;
++
++      thunk = its_page + its_offset;
++      its_offset += size;
++
++      set_memory_rw((unsigned long)its_page, 1);
++      thunk = its_init_thunk(thunk, reg);
++      set_memory_ro((unsigned long)its_page, 1);
++      set_memory_x((unsigned long)its_page, 1);
++
++      return thunk;
++}
++#else /* CONFIG_MODULES */
++
++static void *its_allocate_thunk(int reg)
++{
++      return NULL;
++}
++
++#endif /* CONFIG_MODULES */
++
++static int __emit_trampoline(void *addr, struct insn *insn, u8 *bytes,
++                           void *call_dest, void *jmp_dest)
++{
++      u8 op = insn->opcode.bytes[0];
++      int i = 0;
++
++      /*
++       * Clang does 'weird' Jcc __x86_indirect_thunk_r11 conditional
++       * tail-calls. Deal with them.
++       */
++      if (is_jcc32(insn)) {
++              bytes[i++] = op;
++              op = insn->opcode.bytes[1];
++              goto clang_jcc;
++      }
++
++      if (insn->length == 6)
++              bytes[i++] = 0x2e; /* CS-prefix */
++
++      switch (op) {
++      case CALL_INSN_OPCODE:
++              __text_gen_insn(bytes+i, op, addr+i,
++                              call_dest,
++                              CALL_INSN_SIZE);
++              i += CALL_INSN_SIZE;
++              break;
++
++      case JMP32_INSN_OPCODE:
++clang_jcc:
++              __text_gen_insn(bytes+i, op, addr+i,
++                              jmp_dest,
++                              JMP32_INSN_SIZE);
++              i += JMP32_INSN_SIZE;
++              break;
++
++      default:
++              WARN(1, "%pS %px %*ph\n", addr, addr, 6, addr);
++              return -1;
++      }
++
++      WARN_ON_ONCE(i != insn->length);
++
++      return i;
++}
++
++static int emit_its_trampoline(void *addr, struct insn *insn, int reg, u8 
*bytes)
++{
++      u8 *thunk = __x86_indirect_its_thunk_array[reg];
++      u8 *tmp = its_allocate_thunk(reg);
++
++      if (tmp)
++              thunk = tmp;
++
++      return __emit_trampoline(addr, insn, bytes, thunk, thunk);
++}
++
++/* Check if an indirect branch is at ITS-unsafe address */
++static bool cpu_wants_indirect_its_thunk_at(unsigned long addr, int reg)
++{
++      if (!cpu_feature_enabled(X86_FEATURE_INDIRECT_THUNK_ITS))
++              return false;
++
++      /* Indirect branch opcode is 2 or 3 bytes depending on reg */
++      addr += 1 + reg / 8;
++
++      /* Lower-half of the cacheline? */
++      return !(addr & 0x20);
++}
++
++u8 *its_static_thunk(int reg)
++{
++      u8 *thunk = __x86_indirect_its_thunk_array[reg];
++
++      return thunk;
++}
++
++#endif
++
+ /*
+  * Rewrite the compiler generated retpoline thunk calls.
+  *
+@@ -466,6 +678,15 @@ static int patch_retpoline(void *addr, struct insn *insn, 
u8 *bytes)
+               bytes[i++] = 0xe8; /* LFENCE */
+       }
+ 
++#ifdef CONFIG_MITIGATION_ITS
++      /*
++       * Check if the address of last byte of emitted-indirect is in
++       * lower-half of the cacheline. Such branches need ITS mitigation.
++       */
++      if (cpu_wants_indirect_its_thunk_at((unsigned long)addr + i, reg))
++              return emit_its_trampoline(addr, insn, reg, bytes);
++#endif
++
+       ret = emit_indirect(op, reg, bytes + i);
+       if (ret < 0)
+               return ret;
+@@ -528,6 +749,21 @@ void __init_or_module noinline apply_retpolines(s32 
*start, s32 *end)
+ 
+ #ifdef CONFIG_RETHUNK
+ 
++bool cpu_wants_rethunk(void)
++{
++      return cpu_feature_enabled(X86_FEATURE_RETHUNK);
++}
++
++bool cpu_wants_rethunk_at(void *addr)
++{
++      if (!cpu_feature_enabled(X86_FEATURE_RETHUNK))
++              return false;
++      if (x86_return_thunk != its_return_thunk)
++              return true;
++
++      return !((unsigned long)addr & 0x20);
++}
++
+ /*
+  * Rewrite the compiler generated return thunk tail-calls.
+  *
+@@ -543,13 +779,12 @@ static int patch_return(void *addr, struct insn *insn, 
u8 *bytes)
+ {
+       int i = 0;
+ 
+-      if (cpu_feature_enabled(X86_FEATURE_RETHUNK)) {
+-              if (x86_return_thunk == __x86_return_thunk)
+-                      return -1;
+-
++      /* Patch the custom return thunks... */
++      if (cpu_wants_rethunk_at(addr)) {
+               i = JMP32_INSN_SIZE;
+               __text_gen_insn(bytes, JMP32_INSN_OPCODE, addr, 
x86_return_thunk, i);
+       } else {
++              /* ... or patch them out if not needed. */
+               bytes[i++] = RET_INSN_OPCODE;
+       }
+ 
+diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c
+index c10d93d2773b4b..63af3d73d19e5d 100644
+--- a/arch/x86/kernel/cpu/bugs.c
++++ b/arch/x86/kernel/cpu/bugs.c
+@@ -48,6 +48,7 @@ static void __init srbds_select_mitigation(void);
+ static void __init l1d_flush_select_mitigation(void);
+ static void __init gds_select_mitigation(void);
+ static void __init srso_select_mitigation(void);
++static void __init its_select_mitigation(void);
+ 
+ /* The base value of the SPEC_CTRL MSR without task-specific bits set */
+ u64 x86_spec_ctrl_base;
+@@ -66,6 +67,14 @@ static DEFINE_MUTEX(spec_ctrl_mutex);
+ 
+ void (*x86_return_thunk)(void) __ro_after_init = &__x86_return_thunk;
+ 
++static void __init set_return_thunk(void *thunk)
++{
++      if (x86_return_thunk != __x86_return_thunk)
++              pr_warn("x86/bugs: return thunk changed\n");
++
++      x86_return_thunk = thunk;
++}
++
+ /* Update SPEC_CTRL MSR and its cached copy unconditionally */
+ static void update_spec_ctrl(u64 val)
+ {
+@@ -174,6 +183,7 @@ void __init cpu_select_mitigations(void)
+        */
+       srso_select_mitigation();
+       gds_select_mitigation();
++      its_select_mitigation();
+ }
+ 
+ /*
+@@ -1081,7 +1091,7 @@ static void __init retbleed_select_mitigation(void)
+               setup_force_cpu_cap(X86_FEATURE_UNRET);
+ 
+               if (IS_ENABLED(CONFIG_RETHUNK))
+-                      x86_return_thunk = retbleed_return_thunk;
++                      set_return_thunk(retbleed_return_thunk);
+ 
+               if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD &&
+                   boot_cpu_data.x86_vendor != X86_VENDOR_HYGON)
+@@ -1142,6 +1152,116 @@ static void __init retbleed_select_mitigation(void)
+       pr_info("%s\n", retbleed_strings[retbleed_mitigation]);
+ }
+ 
++#undef pr_fmt
++#define pr_fmt(fmt)     "ITS: " fmt
++
++enum its_mitigation_cmd {
++      ITS_CMD_OFF,
++      ITS_CMD_ON,
++      ITS_CMD_VMEXIT,
++};
++
++enum its_mitigation {
++      ITS_MITIGATION_OFF,
++      ITS_MITIGATION_VMEXIT_ONLY,
++      ITS_MITIGATION_ALIGNED_THUNKS,
++};
++
++static const char * const its_strings[] = {
++      [ITS_MITIGATION_OFF]                    = "Vulnerable",
++      [ITS_MITIGATION_VMEXIT_ONLY]            = "Mitigation: Vulnerable, KVM: 
Not affected",
++      [ITS_MITIGATION_ALIGNED_THUNKS]         = "Mitigation: Aligned 
branch/return thunks",
++};
++
++static enum its_mitigation its_mitigation __ro_after_init = 
ITS_MITIGATION_ALIGNED_THUNKS;
++
++static enum its_mitigation_cmd its_cmd __ro_after_init =
++      IS_ENABLED(CONFIG_MITIGATION_ITS) ? ITS_CMD_ON : ITS_CMD_OFF;
++
++static int __init its_parse_cmdline(char *str)
++{
++      if (!str)
++              return -EINVAL;
++
++      if (!IS_ENABLED(CONFIG_MITIGATION_ITS)) {
++              pr_err("Mitigation disabled at compile time, ignoring option 
(%s)", str);
++              return 0;
++      }
++
++      if (!strcmp(str, "off")) {
++              its_cmd = ITS_CMD_OFF;
++      } else if (!strcmp(str, "on")) {
++              its_cmd = ITS_CMD_ON;
++      } else if (!strcmp(str, "force")) {
++              its_cmd = ITS_CMD_ON;
++              setup_force_cpu_bug(X86_BUG_ITS);
++      } else if (!strcmp(str, "vmexit")) {
++              its_cmd = ITS_CMD_VMEXIT;
++      } else {
++              pr_err("Ignoring unknown indirect_target_selection option 
(%s).", str);
++      }
++
++      return 0;
++}
++early_param("indirect_target_selection", its_parse_cmdline);
++
++static void __init its_select_mitigation(void)
++{
++      enum its_mitigation_cmd cmd = its_cmd;
++
++      if (!boot_cpu_has_bug(X86_BUG_ITS) || cpu_mitigations_off()) {
++              its_mitigation = ITS_MITIGATION_OFF;
++              return;
++      }
++
++      /* Exit early to avoid irrelevant warnings */
++      if (cmd == ITS_CMD_OFF) {
++              its_mitigation = ITS_MITIGATION_OFF;
++              goto out;
++      }
++      if (spectre_v2_enabled == SPECTRE_V2_NONE) {
++              pr_err("WARNING: Spectre-v2 mitigation is off, disabling 
ITS\n");
++              its_mitigation = ITS_MITIGATION_OFF;
++              goto out;
++      }
++      if (!IS_ENABLED(CONFIG_RETPOLINE) || !IS_ENABLED(CONFIG_RETHUNK)) {
++              pr_err("WARNING: ITS mitigation depends on retpoline and 
rethunk support\n");
++              its_mitigation = ITS_MITIGATION_OFF;
++              goto out;
++      }
++      if (IS_ENABLED(CONFIG_DEBUG_FORCE_FUNCTION_ALIGN_64B)) {
++              pr_err("WARNING: ITS mitigation is not compatible with 
CONFIG_DEBUG_FORCE_FUNCTION_ALIGN_64B\n");
++              its_mitigation = ITS_MITIGATION_OFF;
++              goto out;
++      }
++      if (boot_cpu_has(X86_FEATURE_RETPOLINE_LFENCE)) {
++              pr_err("WARNING: ITS mitigation is not compatible with lfence 
mitigation\n");
++              its_mitigation = ITS_MITIGATION_OFF;
++              goto out;
++      }
++
++      switch (cmd) {
++      case ITS_CMD_OFF:
++              its_mitigation = ITS_MITIGATION_OFF;
++              break;
++      case ITS_CMD_VMEXIT:
++              if (boot_cpu_has_bug(X86_BUG_ITS_NATIVE_ONLY)) {
++                      its_mitigation = ITS_MITIGATION_VMEXIT_ONLY;
++                      goto out;
++              }
++              fallthrough;
++      case ITS_CMD_ON:
++              its_mitigation = ITS_MITIGATION_ALIGNED_THUNKS;
++              if (!boot_cpu_has(X86_FEATURE_RETPOLINE))
++                      setup_force_cpu_cap(X86_FEATURE_INDIRECT_THUNK_ITS);
++              setup_force_cpu_cap(X86_FEATURE_RETHUNK);
++              set_return_thunk(its_return_thunk);
++              break;
++      }
++out:
++      pr_info("%s\n", its_strings[its_mitigation]);
++}
++
+ #undef pr_fmt
+ #define pr_fmt(fmt)     "Spectre V2 : " fmt
+ 
+@@ -2592,10 +2712,10 @@ static void __init srso_select_mitigation(void)
+ 
+                       if (boot_cpu_data.x86 == 0x19) {
+                               setup_force_cpu_cap(X86_FEATURE_SRSO_ALIAS);
+-                              x86_return_thunk = srso_alias_return_thunk;
++                              set_return_thunk(srso_alias_return_thunk);
+                       } else {
+                               setup_force_cpu_cap(X86_FEATURE_SRSO);
+-                              x86_return_thunk = srso_return_thunk;
++                              set_return_thunk(srso_return_thunk);
+                       }
+                       srso_mitigation = SRSO_MITIGATION_SAFE_RET;
+               } else {
+@@ -2775,6 +2895,11 @@ static ssize_t rfds_show_state(char *buf)
+       return sysfs_emit(buf, "%s\n", rfds_strings[rfds_mitigation]);
+ }
+ 
++static ssize_t its_show_state(char *buf)
++{
++      return sysfs_emit(buf, "%s\n", its_strings[its_mitigation]);
++}
++
+ static char *stibp_state(void)
+ {
+       if (spectre_v2_in_eibrs_mode(spectre_v2_enabled) &&
+@@ -2959,6 +3084,9 @@ static ssize_t cpu_show_common(struct device *dev, 
struct device_attribute *attr
+       case X86_BUG_RFDS:
+               return rfds_show_state(buf);
+ 
++      case X86_BUG_ITS:
++              return its_show_state(buf);
++
+       default:
+               break;
+       }
+@@ -3038,4 +3166,9 @@ ssize_t cpu_show_reg_file_data_sampling(struct device 
*dev, struct device_attrib
+ {
+       return cpu_show_common(dev, attr, buf, X86_BUG_RFDS);
+ }
++
++ssize_t cpu_show_indirect_target_selection(struct device *dev, struct 
device_attribute *attr, char *buf)
++{
++      return cpu_show_common(dev, attr, buf, X86_BUG_ITS);
++}
+ #endif
+diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
+index 1ebd67c95d869a..dc15568e14d935 100644
+--- a/arch/x86/kernel/cpu/common.c
++++ b/arch/x86/kernel/cpu/common.c
+@@ -1141,6 +1141,10 @@ static const __initconst struct x86_cpu_id 
cpu_vuln_whitelist[] = {
+ #define GDS           BIT(6)
+ /* CPU is affected by Register File Data Sampling */
+ #define RFDS          BIT(7)
++/* CPU is affected by Indirect Target Selection */
++#define ITS           BIT(8)
++/* CPU is affected by Indirect Target Selection, but guest-host isolation is 
not affected */
++#define ITS_NATIVE_ONLY       BIT(9)
+ 
+ static const struct x86_cpu_id cpu_vuln_blacklist[] __initconst = {
+       VULNBL_INTEL_STEPPINGS(IVYBRIDGE,       X86_STEPPING_ANY,               
SRBDS),
+@@ -1152,22 +1156,25 @@ static const struct x86_cpu_id cpu_vuln_blacklist[] 
__initconst = {
+       VULNBL_INTEL_STEPPINGS(BROADWELL_G,     X86_STEPPING_ANY,               
SRBDS),
+       VULNBL_INTEL_STEPPINGS(BROADWELL_X,     X86_STEPPING_ANY,               
MMIO),
+       VULNBL_INTEL_STEPPINGS(BROADWELL,       X86_STEPPING_ANY,               
SRBDS),
+-      VULNBL_INTEL_STEPPINGS(SKYLAKE_X,       X86_STEPPING_ANY,               
MMIO | RETBLEED | GDS),
++      VULNBL_INTEL_STEPPINGS(SKYLAKE_X,       X86_STEPPINGS(0x0, 0x5),        
MMIO | RETBLEED | GDS),
++      VULNBL_INTEL_STEPPINGS(SKYLAKE_X,       X86_STEPPING_ANY,               
MMIO | RETBLEED | GDS | ITS),
+       VULNBL_INTEL_STEPPINGS(SKYLAKE_L,       X86_STEPPING_ANY,               
MMIO | RETBLEED | GDS | SRBDS),
+       VULNBL_INTEL_STEPPINGS(SKYLAKE,         X86_STEPPING_ANY,               
MMIO | RETBLEED | GDS | SRBDS),
+-      VULNBL_INTEL_STEPPINGS(KABYLAKE_L,      X86_STEPPING_ANY,               
MMIO | RETBLEED | GDS | SRBDS),
+-      VULNBL_INTEL_STEPPINGS(KABYLAKE,        X86_STEPPING_ANY,               
MMIO | RETBLEED | GDS | SRBDS),
++      VULNBL_INTEL_STEPPINGS(KABYLAKE_L,      X86_STEPPINGS(0x0, 0xb),        
MMIO | RETBLEED | GDS | SRBDS),
++      VULNBL_INTEL_STEPPINGS(KABYLAKE_L,      X86_STEPPING_ANY,               
MMIO | RETBLEED | GDS | SRBDS | ITS),
++      VULNBL_INTEL_STEPPINGS(KABYLAKE,        X86_STEPPINGS(0x0, 0xc),        
MMIO | RETBLEED | GDS | SRBDS),
++      VULNBL_INTEL_STEPPINGS(KABYLAKE,        X86_STEPPING_ANY,               
MMIO | RETBLEED | GDS | SRBDS | ITS),
+       VULNBL_INTEL_STEPPINGS(CANNONLAKE_L,    X86_STEPPING_ANY,               
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 | GDS),
+-      VULNBL_INTEL_STEPPINGS(TIGERLAKE_L,     X86_STEPPING_ANY,               
GDS),
+-      VULNBL_INTEL_STEPPINGS(TIGERLAKE,       X86_STEPPING_ANY,               
GDS),
++      VULNBL_INTEL_STEPPINGS(ICELAKE_L,       X86_STEPPING_ANY,               
MMIO | MMIO_SBDS | RETBLEED | GDS | ITS | ITS_NATIVE_ONLY),
++      VULNBL_INTEL_STEPPINGS(ICELAKE_D,       X86_STEPPING_ANY,               
MMIO | GDS | ITS | ITS_NATIVE_ONLY),
++      VULNBL_INTEL_STEPPINGS(ICELAKE_X,       X86_STEPPING_ANY,               
MMIO | GDS | ITS | ITS_NATIVE_ONLY),
++      VULNBL_INTEL_STEPPINGS(COMETLAKE,       X86_STEPPING_ANY,               
MMIO | MMIO_SBDS | RETBLEED | GDS | ITS),
++      VULNBL_INTEL_STEPPINGS(COMETLAKE_L,     X86_STEPPINGS(0x0, 0x0),        
MMIO | RETBLEED | ITS),
++      VULNBL_INTEL_STEPPINGS(COMETLAKE_L,     X86_STEPPING_ANY,               
MMIO | MMIO_SBDS | RETBLEED | GDS | ITS),
++      VULNBL_INTEL_STEPPINGS(TIGERLAKE_L,     X86_STEPPING_ANY,               
GDS | ITS | ITS_NATIVE_ONLY),
++      VULNBL_INTEL_STEPPINGS(TIGERLAKE,       X86_STEPPING_ANY,               
GDS | ITS | ITS_NATIVE_ONLY),
+       VULNBL_INTEL_STEPPINGS(LAKEFIELD,       X86_STEPPING_ANY,               
MMIO | MMIO_SBDS | RETBLEED),
+-      VULNBL_INTEL_STEPPINGS(ROCKETLAKE,      X86_STEPPING_ANY,               
MMIO | RETBLEED | GDS),
++      VULNBL_INTEL_STEPPINGS(ROCKETLAKE,      X86_STEPPING_ANY,               
MMIO | RETBLEED | GDS | ITS | ITS_NATIVE_ONLY),
+       VULNBL_INTEL_STEPPINGS(ALDERLAKE,       X86_STEPPING_ANY,               
RFDS),
+       VULNBL_INTEL_STEPPINGS(ALDERLAKE_L,     X86_STEPPING_ANY,               
RFDS),
+       VULNBL_INTEL_STEPPINGS(RAPTORLAKE,      X86_STEPPING_ANY,               
RFDS),
+@@ -1231,6 +1238,32 @@ static bool __init vulnerable_to_rfds(u64 
x86_arch_cap_msr)
+       return cpu_matches(cpu_vuln_blacklist, RFDS);
+ }
+ 
++static bool __init vulnerable_to_its(u64 x86_arch_cap_msr)
++{
++      /* The "immunity" bit trumps everything else: */
++      if (x86_arch_cap_msr & ARCH_CAP_ITS_NO)
++              return false;
++      if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL)
++              return false;
++
++      /* None of the affected CPUs have BHI_CTRL */
++      if (boot_cpu_has(X86_FEATURE_BHI_CTRL))
++              return false;
++
++      /*
++       * If a VMM did not expose ITS_NO, assume that a guest could
++       * be running on a vulnerable hardware or may migrate to such
++       * hardware.
++       */
++      if (boot_cpu_has(X86_FEATURE_HYPERVISOR))
++              return true;
++
++      if (cpu_matches(cpu_vuln_blacklist, ITS))
++              return true;
++
++      return false;
++}
++
+ static void __init cpu_set_bug_bits(struct cpuinfo_x86 *c)
+ {
+       u64 x86_arch_cap_msr = x86_read_arch_cap_msr();
+@@ -1358,6 +1391,12 @@ static void __init cpu_set_bug_bits(struct cpuinfo_x86 
*c)
+       if (cpu_has(c, X86_FEATURE_AMD_IBPB) && !cpu_has(c, 
X86_FEATURE_AMD_IBPB_RET))
+               setup_force_cpu_bug(X86_BUG_IBPB_NO_RET);
+ 
++      if (vulnerable_to_its(x86_arch_cap_msr)) {
++              setup_force_cpu_bug(X86_BUG_ITS);
++              if (cpu_matches(cpu_vuln_blacklist, ITS_NATIVE_ONLY))
++                      setup_force_cpu_bug(X86_BUG_ITS_NATIVE_ONLY);
++      }
++
+       if (cpu_matches(cpu_vuln_whitelist, NO_MELTDOWN))
+               return;
+ 
+diff --git a/arch/x86/kernel/ftrace.c b/arch/x86/kernel/ftrace.c
+index 85c09843df1b9e..fee8c63e15d474 100644
+--- a/arch/x86/kernel/ftrace.c
++++ b/arch/x86/kernel/ftrace.c
+@@ -367,7 +367,7 @@ create_trampoline(struct ftrace_ops *ops, unsigned int 
*tramp_size)
+               goto fail;
+ 
+       ip = trampoline + size;
+-      if (cpu_feature_enabled(X86_FEATURE_RETHUNK))
++      if (cpu_wants_rethunk_at(ip))
+               __text_gen_insn(ip, JMP32_INSN_OPCODE, ip, x86_return_thunk, 
JMP32_INSN_SIZE);
+       else
+               memcpy(ip, retq, sizeof(retq));
+@@ -422,8 +422,6 @@ create_trampoline(struct ftrace_ops *ops, unsigned int 
*tramp_size)
+       /* ALLOC_TRAMP flags lets us know we created it */
+       ops->flags |= FTRACE_OPS_FL_ALLOC_TRAMP;
+ 
+-      set_vm_flush_reset_perms(trampoline);
+-
+       if (likely(system_state != SYSTEM_BOOTING))
+               set_memory_ro((unsigned long)trampoline, npages);
+       set_memory_x((unsigned long)trampoline, npages);
+diff --git a/arch/x86/kernel/kprobes/core.c b/arch/x86/kernel/kprobes/core.c
+index 99dd504307fdc4..2a0563780ebb2b 100644
+--- a/arch/x86/kernel/kprobes/core.c
++++ b/arch/x86/kernel/kprobes/core.c
+@@ -403,7 +403,6 @@ void *alloc_insn_page(void)
+       if (!page)
+               return NULL;
+ 
+-      set_vm_flush_reset_perms(page);
+       /*
+        * First make the page read-only, and only then make it executable to
+        * prevent it from being W+X in between.
+diff --git a/arch/x86/kernel/module.c b/arch/x86/kernel/module.c
+index 06b53ea940bf60..f0f2bbf73f205e 100644
+--- a/arch/x86/kernel/module.c
++++ b/arch/x86/kernel/module.c
+@@ -74,10 +74,10 @@ void *module_alloc(unsigned long size)
+               return NULL;
+ 
+       p = __vmalloc_node_range(size, MODULE_ALIGN,
+-                                  MODULES_VADDR + get_module_load_offset(),
+-                                  MODULES_END, gfp_mask,
+-                                  PAGE_KERNEL, VM_DEFER_KMEMLEAK, 
NUMA_NO_NODE,
+-                                  __builtin_return_address(0));
++                               MODULES_VADDR + get_module_load_offset(),
++                               MODULES_END, gfp_mask, PAGE_KERNEL,
++                               VM_FLUSH_RESET_PERMS | VM_DEFER_KMEMLEAK,
++                               NUMA_NO_NODE, __builtin_return_address(0));
+       if (p && (kasan_module_alloc(p, size, gfp_mask) < 0)) {
+               vfree(p);
+               return NULL;
+@@ -283,10 +283,16 @@ int module_finalize(const Elf_Ehdr *hdr,
+               void *pseg = (void *)para->sh_addr;
+               apply_paravirt(pseg, pseg + para->sh_size);
+       }
++
++      its_init_mod(me);
++
+       if (retpolines) {
+               void *rseg = (void *)retpolines->sh_addr;
+               apply_retpolines(rseg, rseg + retpolines->sh_size);
+       }
++
++      its_fini_mod(me);
++
+       if (returns) {
+               void *rseg = (void *)returns->sh_addr;
+               apply_returns(rseg, rseg + returns->sh_size);
+@@ -317,4 +323,5 @@ int module_finalize(const Elf_Ehdr *hdr,
+ void module_arch_cleanup(struct module *mod)
+ {
+       alternatives_smp_module_del(mod);
++      its_free_mod(mod);
+ }
+diff --git a/arch/x86/kernel/static_call.c b/arch/x86/kernel/static_call.c
+index a5dd11c92d055c..74eb1d6c7bb0d0 100644
+--- a/arch/x86/kernel/static_call.c
++++ b/arch/x86/kernel/static_call.c
+@@ -81,7 +81,7 @@ static void __ref __static_call_transform(void *insn, enum 
insn_type type,
+               break;
+ 
+       case RET:
+-              if (cpu_feature_enabled(X86_FEATURE_RETHUNK))
++              if (cpu_wants_rethunk_at(insn))
+                       code = text_gen_insn(JMP32_INSN_OPCODE, insn, 
x86_return_thunk);
+               else
+                       code = &retinsn;
+diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S
+index 351c604de263ac..c570da8be03077 100644
+--- a/arch/x86/kernel/vmlinux.lds.S
++++ b/arch/x86/kernel/vmlinux.lds.S
+@@ -532,6 +532,16 @@ INIT_PER_CPU(irq_stack_backing_store);
+               "SRSO function pair won't alias");
+ #endif
+ 
++#if defined(CONFIG_MITIGATION_ITS) && 
!defined(CONFIG_DEBUG_FORCE_FUNCTION_ALIGN_64B)
++. = ASSERT(__x86_indirect_its_thunk_rax & 0x20, "__x86_indirect_thunk_rax not 
in second half of cacheline");
++. = ASSERT(((__x86_indirect_its_thunk_rcx - __x86_indirect_its_thunk_rax) % 
64) == 0, "Indirect thunks are not cacheline apart");
++. = ASSERT(__x86_indirect_its_thunk_array == __x86_indirect_its_thunk_rax, 
"Gap in ITS thunk array");
++#endif
++
++#if defined(CONFIG_MITIGATION_ITS) && 
!defined(CONFIG_DEBUG_FORCE_FUNCTION_ALIGN_64B)
++. = ASSERT(its_return_thunk & 0x20, "its_return_thunk not in second half of 
cacheline");
++#endif
++
+ #endif /* CONFIG_X86_64 */
+ 
+ #ifdef CONFIG_KEXEC_CORE
+diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
+index bf03f3ff896e36..b5bf68c2d2fc8f 100644
+--- a/arch/x86/kvm/x86.c
++++ b/arch/x86/kvm/x86.c
+@@ -1499,7 +1499,7 @@ static unsigned int num_msr_based_features;
+        ARCH_CAP_PSCHANGE_MC_NO | ARCH_CAP_TSX_CTRL_MSR | ARCH_CAP_TAA_NO | \
+        ARCH_CAP_SBDR_SSDP_NO | ARCH_CAP_FBSDP_NO | ARCH_CAP_PSDP_NO | \
+        ARCH_CAP_FB_CLEAR | ARCH_CAP_RRSBA | ARCH_CAP_PBRSB_NO | 
ARCH_CAP_GDS_NO | \
+-       ARCH_CAP_RFDS_NO | ARCH_CAP_RFDS_CLEAR | ARCH_CAP_BHI_NO)
++       ARCH_CAP_RFDS_NO | ARCH_CAP_RFDS_CLEAR | ARCH_CAP_BHI_NO | 
ARCH_CAP_ITS_NO)
+ 
+ static u64 kvm_get_arch_capabilities(void)
+ {
+@@ -1538,6 +1538,8 @@ static u64 kvm_get_arch_capabilities(void)
+               data |= ARCH_CAP_MDS_NO;
+       if (!boot_cpu_has_bug(X86_BUG_RFDS))
+               data |= ARCH_CAP_RFDS_NO;
++      if (!boot_cpu_has_bug(X86_BUG_ITS))
++              data |= ARCH_CAP_ITS_NO;
+ 
+       if (!boot_cpu_has(X86_FEATURE_RTM)) {
+               /*
+diff --git a/arch/x86/lib/retpoline.S b/arch/x86/lib/retpoline.S
+index 019096b66eff35..ae0151c6caba57 100644
+--- a/arch/x86/lib/retpoline.S
++++ b/arch/x86/lib/retpoline.S
+@@ -254,6 +254,45 @@ SYM_FUNC_START(entry_untrain_ret)
+ SYM_FUNC_END(entry_untrain_ret)
+ __EXPORT_THUNK(entry_untrain_ret)
+ 
++#ifdef CONFIG_MITIGATION_ITS
++
++.macro ITS_THUNK reg
++
++SYM_INNER_LABEL(__x86_indirect_its_thunk_\reg, SYM_L_GLOBAL)
++      UNWIND_HINT_EMPTY
++      ANNOTATE_NOENDBR
++      ANNOTATE_RETPOLINE_SAFE
++      jmp *%\reg
++      int3
++      .align 32, 0xcc         /* fill to the end of the line */
++      .skip  32, 0xcc         /* skip to the next upper half */
++.endm
++
++/* ITS mitigation requires thunks be aligned to upper half of cacheline */
++.align 64, 0xcc
++.skip 32, 0xcc
++SYM_CODE_START(__x86_indirect_its_thunk_array)
++
++#define GEN(reg) ITS_THUNK reg
++#include <asm/GEN-for-each-reg.h>
++#undef GEN
++
++      .align 64, 0xcc
++SYM_CODE_END(__x86_indirect_its_thunk_array)
++
++.align 64, 0xcc
++.skip 32, 0xcc
++SYM_CODE_START(its_return_thunk)
++      UNWIND_HINT_FUNC
++      ANNOTATE_NOENDBR
++      ANNOTATE_UNRET_SAFE
++      ret
++      int3
++SYM_CODE_END(its_return_thunk)
++EXPORT_SYMBOL(its_return_thunk)
++
++#endif /* CONFIG_MITIGATION_ITS */
++
+ SYM_CODE_START(__x86_return_thunk)
+       UNWIND_HINT_FUNC
+       ANNOTATE_NOENDBR
+diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c
+index f62ebeee8b14ef..37a005df0b9520 100644
+--- a/arch/x86/net/bpf_jit_comp.c
++++ b/arch/x86/net/bpf_jit_comp.c
+@@ -446,7 +446,11 @@ static void emit_indirect_jump(u8 **pprog, int reg, u8 
*ip)
+       u8 *prog = *pprog;
+ 
+ #ifdef CONFIG_RETPOLINE
+-      if (cpu_feature_enabled(X86_FEATURE_RETPOLINE_LFENCE)) {
++      if (IS_ENABLED(CONFIG_MITIGATION_ITS) &&
++          cpu_feature_enabled(X86_FEATURE_INDIRECT_THUNK_ITS)) {
++              OPTIMIZER_HIDE_VAR(reg);
++              emit_jump(&prog, its_static_thunk(reg), ip);
++      } else if (cpu_feature_enabled(X86_FEATURE_RETPOLINE_LFENCE)) {
+               EMIT_LFENCE();
+               EMIT2(0xFF, 0xE0 + reg);
+       } else if (cpu_feature_enabled(X86_FEATURE_RETPOLINE)) {
+@@ -462,7 +466,7 @@ static void emit_return(u8 **pprog, u8 *ip)
+ {
+       u8 *prog = *pprog;
+ 
+-      if (cpu_feature_enabled(X86_FEATURE_RETHUNK)) {
++      if (cpu_wants_rethunk()) {
+               emit_jump(&prog, x86_return_thunk, ip);
+       } else {
+               EMIT1(0xC3);            /* ret */
+diff --git a/block/fops.c b/block/fops.c
+index 4c8948979921a6..72da501542f148 100644
+--- a/block/fops.c
++++ b/block/fops.c
+@@ -259,7 +259,6 @@ static ssize_t __blkdev_direct_IO(struct kiocb *iocb, 
struct iov_iter *iter,
+                               blk_finish_plug(&plug);
+                               return -EAGAIN;
+                       }
+-                      bio->bi_opf |= REQ_NOWAIT;
+               }
+ 
+               if (is_read) {
+@@ -270,6 +269,10 @@ static ssize_t __blkdev_direct_IO(struct kiocb *iocb, 
struct iov_iter *iter,
+                       bio->bi_opf = dio_bio_write_op(iocb);
+                       task_io_account_write(bio->bi_iter.bi_size);
+               }
++
++              if (iocb->ki_flags & IOCB_NOWAIT)
++                      bio->bi_opf |= REQ_NOWAIT;
++
+               dio->size += bio->bi_iter.bi_size;
+               pos += bio->bi_iter.bi_size;
+ 
+diff --git a/drivers/acpi/pptt.c b/drivers/acpi/pptt.c
+index 9fa339639d0c06..0b56fd962b28e7 100644
+--- a/drivers/acpi/pptt.c
++++ b/drivers/acpi/pptt.c
+@@ -219,16 +219,18 @@ static int acpi_pptt_leaf_node(struct acpi_table_header 
*table_hdr,
+                            sizeof(struct acpi_table_pptt));
+       proc_sz = sizeof(struct acpi_pptt_processor);
+ 
+-      while ((unsigned long)entry + proc_sz < table_end) {
++      /* ignore subtable types that are smaller than a processor node */
++      while ((unsigned long)entry + proc_sz <= table_end) {
+               cpu_node = (struct acpi_pptt_processor *)entry;
++
+               if (entry->type == ACPI_PPTT_TYPE_PROCESSOR &&
+                   cpu_node->parent == node_entry)
+                       return 0;
+               if (entry->length == 0)
+                       return 0;
++
+               entry = ACPI_ADD_PTR(struct acpi_subtable_header, entry,
+                                    entry->length);
+-
+       }
+       return 1;
+ }
+@@ -261,15 +263,18 @@ static struct acpi_pptt_processor 
*acpi_find_processor_node(struct acpi_table_he
+       proc_sz = sizeof(struct acpi_pptt_processor);
+ 
+       /* find the processor structure associated with this cpuid */
+-      while ((unsigned long)entry + proc_sz < table_end) {
++      while ((unsigned long)entry + proc_sz <= table_end) {
+               cpu_node = (struct acpi_pptt_processor *)entry;
+ 
+               if (entry->length == 0) {
+                       pr_warn("Invalid zero length subtable\n");
+                       break;
+               }
++              /* entry->length may not equal proc_sz, revalidate the 
processor structure length */
+               if (entry->type == ACPI_PPTT_TYPE_PROCESSOR &&
+                   acpi_cpu_id == cpu_node->acpi_processor_id &&
++                  (unsigned long)entry + entry->length <= table_end &&
++                  entry->length == proc_sz + 
cpu_node->number_of_priv_resources * sizeof(u32) &&
+                    acpi_pptt_leaf_node(table_hdr, cpu_node)) {
+                       return (struct acpi_pptt_processor *)entry;
+               }
+diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c
+index 93222cf3915769..df196e0730972c 100644
+--- a/drivers/base/cpu.c
++++ b/drivers/base/cpu.c
+@@ -595,6 +595,12 @@ ssize_t __weak cpu_show_reg_file_data_sampling(struct 
device *dev,
+       return sysfs_emit(buf, "Not affected\n");
+ }
+ 
++ssize_t __weak cpu_show_indirect_target_selection(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);
+@@ -609,6 +615,7 @@ static DEVICE_ATTR(retbleed, 0444, cpu_show_retbleed, 
NULL);
+ static DEVICE_ATTR(gather_data_sampling, 0444, cpu_show_gds, NULL);
+ static DEVICE_ATTR(spec_rstack_overflow, 0444, cpu_show_spec_rstack_overflow, 
NULL);
+ static DEVICE_ATTR(reg_file_data_sampling, 0444, 
cpu_show_reg_file_data_sampling, NULL);
++static DEVICE_ATTR(indirect_target_selection, 0444, 
cpu_show_indirect_target_selection, NULL);
+ 
+ static struct attribute *cpu_root_vulnerabilities_attrs[] = {
+       &dev_attr_meltdown.attr,
+@@ -625,6 +632,7 @@ static struct attribute *cpu_root_vulnerabilities_attrs[] 
= {
+       &dev_attr_gather_data_sampling.attr,
+       &dev_attr_spec_rstack_overflow.attr,
+       &dev_attr_reg_file_data_sampling.attr,
++      &dev_attr_indirect_target_selection.attr,
+       NULL
+ };
+ 
+diff --git a/drivers/clocksource/i8253.c b/drivers/clocksource/i8253.c
+index 39f7c2d736d169..9a91ce66e16eb9 100644
+--- a/drivers/clocksource/i8253.c
++++ b/drivers/clocksource/i8253.c
+@@ -103,7 +103,9 @@ int __init clocksource_i8253_init(void)
+ #ifdef CONFIG_CLKEVT_I8253
+ void clockevent_i8253_disable(void)
+ {
+-      raw_spin_lock(&i8253_lock);
++      unsigned long flags;
++
++      raw_spin_lock_irqsave(&i8253_lock, flags);
+ 
+       /*
+        * Writing the MODE register should stop the counter, according to
+@@ -133,7 +135,7 @@ void clockevent_i8253_disable(void)
+ 
+       outb_p(0x30, PIT_MODE);
+ 
+-      raw_spin_unlock(&i8253_lock);
++      raw_spin_unlock_irqrestore(&i8253_lock, flags);
+ }
+ 
+ static int pit_shutdown(struct clock_event_device *evt)
+diff --git a/drivers/dma/dmatest.c b/drivers/dma/dmatest.c
+index 0d8d01673010c2..f696246f57fdb3 100644
+--- a/drivers/dma/dmatest.c
++++ b/drivers/dma/dmatest.c
+@@ -828,9 +828,9 @@ static int dmatest_func(void *data)
+               } else {
+                       dma_async_issue_pending(chan);
+ 
+-                      wait_event_timeout(thread->done_wait,
+-                                         done->done,
+-                                         msecs_to_jiffies(params->timeout));
++                      wait_event_freezable_timeout(thread->done_wait,
++                                      done->done,
++                                      msecs_to_jiffies(params->timeout));
+ 
+                       status = dma_async_is_tx_complete(chan, cookie, NULL,
+                                                         NULL);
+diff --git a/drivers/dma/idxd/init.c b/drivers/dma/idxd/init.c
+index e0e0c7f286b67e..f2d27c6ec1ce88 100644
+--- a/drivers/dma/idxd/init.c
++++ b/drivers/dma/idxd/init.c
+@@ -289,6 +289,7 @@ static int idxd_setup_engines(struct idxd_device *idxd)
+               rc = dev_set_name(conf_dev, "engine%d.%d", idxd->id, 
engine->id);
+               if (rc < 0) {
+                       put_device(conf_dev);
++                      kfree(engine);
+                       goto err;
+               }
+ 
+@@ -302,7 +303,10 @@ static int idxd_setup_engines(struct idxd_device *idxd)
+               engine = idxd->engines[i];
+               conf_dev = engine_confdev(engine);
+               put_device(conf_dev);
++              kfree(engine);
+       }
++      kfree(idxd->engines);
++
+       return rc;
+ }
+ 
+@@ -336,6 +340,7 @@ static int idxd_setup_groups(struct idxd_device *idxd)
+               rc = dev_set_name(conf_dev, "group%d.%d", idxd->id, group->id);
+               if (rc < 0) {
+                       put_device(conf_dev);
++                      kfree(group);
+                       goto err;
+               }
+ 
+@@ -355,7 +360,10 @@ static int idxd_setup_groups(struct idxd_device *idxd)
+       while (--i >= 0) {
+               group = idxd->groups[i];
+               put_device(group_confdev(group));
++              kfree(group);
+       }
++      kfree(idxd->groups);
++
+       return rc;
+ }
+ 
+diff --git a/drivers/dma/ti/k3-udma.c b/drivers/dma/ti/k3-udma.c
+index 9db45c4eaaf246..1ca552a324778b 100644
+--- a/drivers/dma/ti/k3-udma.c
++++ b/drivers/dma/ti/k3-udma.c
+@@ -1082,8 +1082,11 @@ static void udma_check_tx_completion(struct work_struct 
*work)
+       u32 residue_diff;
+       ktime_t time_diff;
+       unsigned long delay;
++      unsigned long flags;
+ 
+       while (1) {
++              spin_lock_irqsave(&uc->vc.lock, flags);
++
+               if (uc->desc) {
+                       /* Get previous residue and time stamp */
+                       residue_diff = uc->tx_drain.residue;
+@@ -1118,6 +1121,8 @@ static void udma_check_tx_completion(struct work_struct 
*work)
+                               break;
+                       }
+ 
++                      spin_unlock_irqrestore(&uc->vc.lock, flags);
++
+                       usleep_range(ktime_to_us(delay),
+                                    ktime_to_us(delay) + 10);
+                       continue;
+@@ -1134,6 +1139,8 @@ static void udma_check_tx_completion(struct work_struct 
*work)
+ 
+               break;
+       }
++
++      spin_unlock_irqrestore(&uc->vc.lock, flags);
+ }
+ 
+ static irqreturn_t udma_ring_irq_handler(int irq, void *data)
+@@ -4203,7 +4210,6 @@ static struct dma_chan *udma_of_xlate(struct 
of_phandle_args *dma_spec,
+                                     struct of_dma *ofdma)
+ {
+       struct udma_dev *ud = ofdma->of_dma_data;
+-      dma_cap_mask_t mask = ud->ddev.cap_mask;
+       struct udma_filter_param filter_param;
+       struct dma_chan *chan;
+ 
+@@ -4235,7 +4241,7 @@ static struct dma_chan *udma_of_xlate(struct 
of_phandle_args *dma_spec,
+               }
+       }
+ 
+-      chan = __dma_request_channel(&mask, udma_dma_filter_fn, &filter_param,
++      chan = __dma_request_channel(&ud->ddev.cap_mask, udma_dma_filter_fn, 
&filter_param,
+                                    ofdma->of_node);
+       if (!chan) {
+               dev_err(ud->dev, "get channel fail in %s.\n", __func__);
+diff --git a/drivers/iio/adc/ad7768-1.c b/drivers/iio/adc/ad7768-1.c
+index c922faab4a52b6..e240fac8b6b377 100644
+--- a/drivers/iio/adc/ad7768-1.c
++++ b/drivers/iio/adc/ad7768-1.c
+@@ -169,7 +169,7 @@ struct ad7768_state {
+       union {
+               struct {
+                       __be32 chan;
+-                      s64 timestamp;
++                      aligned_s64 timestamp;
+               } scan;
+               __be32 d32;
+               u8 d8[2];
+diff --git a/drivers/iio/chemical/sps30.c b/drivers/iio/chemical/sps30.c
+index d51314505115e2..43991fe2e35bf4 100644
+--- a/drivers/iio/chemical/sps30.c
++++ b/drivers/iio/chemical/sps30.c
+@@ -108,7 +108,7 @@ static irqreturn_t sps30_trigger_handler(int irq, void *p)
+       int ret;
+       struct {
+               s32 data[4]; /* PM1, PM2P5, PM4, PM10 */
+-              s64 ts;
++              aligned_s64 ts;
+       } scan;
+ 
+       mutex_lock(&state->lock);
+diff --git a/drivers/infiniband/sw/rxe/rxe_cq.c 
b/drivers/infiniband/sw/rxe/rxe_cq.c
+index 4eedaa0244b398..f22f8e950baef4 100644
+--- a/drivers/infiniband/sw/rxe/rxe_cq.c
++++ b/drivers/infiniband/sw/rxe/rxe_cq.c
+@@ -71,11 +71,8 @@ int rxe_cq_from_init(struct rxe_dev *rxe, struct rxe_cq 
*cq, int cqe,
+ 
+       err = do_mmap_info(rxe, uresp ? &uresp->mi : NULL, udata,
+                          cq->queue->buf, cq->queue->buf_size, &cq->queue->ip);
+-      if (err) {
+-              vfree(cq->queue->buf);
+-              kfree(cq->queue);
++      if (err)
+               return err;
+-      }
+ 
+       if (uresp)
+               cq->is_user = 1;
+diff --git a/drivers/net/dsa/sja1105/sja1105_main.c 
b/drivers/net/dsa/sja1105/sja1105_main.c
+index 888f10d93b9ab9..ec1c0ad591184f 100644
+--- a/drivers/net/dsa/sja1105/sja1105_main.c
++++ b/drivers/net/dsa/sja1105/sja1105_main.c
+@@ -1969,6 +1969,7 @@ static void sja1105_bridge_stp_state_set(struct 
dsa_switch *ds, int port,
+       switch (state) {
+       case BR_STATE_DISABLED:
+       case BR_STATE_BLOCKING:
++      case BR_STATE_LISTENING:
+               /* From UM10944 description of DRPDTAG (why put this there?):
+                * "Management traffic flows to the port regardless of the state
+                * of the INGRESS flag". So BPDUs are still be allowed to pass.
+@@ -1978,11 +1979,6 @@ static void sja1105_bridge_stp_state_set(struct 
dsa_switch *ds, int port,
+               mac[port].egress    = false;
+               mac[port].dyn_learn = false;
+               break;
+-      case BR_STATE_LISTENING:
+-              mac[port].ingress   = true;
+-              mac[port].egress    = false;
+-              mac[port].dyn_learn = false;
+-              break;
+       case BR_STATE_LEARNING:
+               mac[port].ingress   = true;
+               mac[port].egress    = false;
+diff --git a/drivers/net/ethernet/cadence/macb_main.c 
b/drivers/net/ethernet/cadence/macb_main.c
+index 275baaaea0e12a..667af80a739b97 100644
+--- a/drivers/net/ethernet/cadence/macb_main.c
++++ b/drivers/net/ethernet/cadence/macb_main.c
+@@ -986,22 +986,15 @@ static void macb_update_stats(struct macb *bp)
+ 
+ static int macb_halt_tx(struct macb *bp)
+ {
+-      unsigned long   halt_time, timeout;
+-      u32             status;
++      u32 status;
+ 
+       macb_writel(bp, NCR, macb_readl(bp, NCR) | MACB_BIT(THALT));
+ 
+-      timeout = jiffies + usecs_to_jiffies(MACB_HALT_TIMEOUT);
+-      do {
+-              halt_time = jiffies;
+-              status = macb_readl(bp, TSR);
+-              if (!(status & MACB_BIT(TGO)))
+-                      return 0;
+-
+-              udelay(250);
+-      } while (time_before(halt_time, timeout));
+-
+-      return -ETIMEDOUT;
++      /* Poll TSR until TGO is cleared or timeout. */
++      return read_poll_timeout_atomic(macb_readl, status,
++                                      !(status & MACB_BIT(TGO)),
++                                      250, MACB_HALT_TIMEOUT, false,
++                                      bp, TSR);
+ }
+ 
+ static void macb_tx_unmap(struct macb *bp, struct macb_tx_skb *tx_skb)
+diff --git a/drivers/net/ethernet/intel/ice/ice_arfs.c 
b/drivers/net/ethernet/intel/ice/ice_arfs.c
+index 9cebae92364ebb..760783f0efe18c 100644
+--- a/drivers/net/ethernet/intel/ice/ice_arfs.c
++++ b/drivers/net/ethernet/intel/ice/ice_arfs.c
+@@ -577,7 +577,7 @@ void ice_free_cpu_rx_rmap(struct ice_vsi *vsi)
+ {
+       struct net_device *netdev;
+ 
+-      if (!vsi || vsi->type != ICE_VSI_PF || !vsi->arfs_fltr_list)
++      if (!vsi || vsi->type != ICE_VSI_PF)
+               return;
+ 
+       netdev = vsi->netdev;
+@@ -599,7 +599,7 @@ int ice_set_cpu_rx_rmap(struct ice_vsi *vsi)
+       int base_idx, i;
+ 
+       if (!vsi || vsi->type != ICE_VSI_PF)
+-              return -EINVAL;
++              return 0;
+ 
+       pf = vsi->back;
+       netdev = vsi->netdev;
+@@ -636,7 +636,6 @@ void ice_remove_arfs(struct ice_pf *pf)
+       if (!pf_vsi)
+               return;
+ 
+-      ice_free_cpu_rx_rmap(pf_vsi);
+       ice_clear_arfs(pf_vsi);
+ }
+ 
+@@ -653,9 +652,5 @@ void ice_rebuild_arfs(struct ice_pf *pf)
+               return;
+ 
+       ice_remove_arfs(pf);
+-      if (ice_set_cpu_rx_rmap(pf_vsi)) {
+-              dev_err(ice_pf_to_dev(pf), "Failed to rebuild aRFS\n");
+-              return;
+-      }
+       ice_init_arfs(pf_vsi);
+ }
+diff --git a/drivers/net/ethernet/intel/ice/ice_lib.c 
b/drivers/net/ethernet/intel/ice/ice_lib.c
+index 8a00864ead7c49..71d062b969cd7d 100644
+--- a/drivers/net/ethernet/intel/ice/ice_lib.c
++++ b/drivers/net/ethernet/intel/ice/ice_lib.c
+@@ -2645,6 +2645,8 @@ void ice_vsi_free_irq(struct ice_vsi *vsi)
+               return;
+ 
+       vsi->irqs_ready = false;
++      ice_free_cpu_rx_rmap(vsi);
++
+       ice_for_each_q_vector(vsi, i) {
+               u16 vector = i + base;
+               int irq_num;
+@@ -2658,7 +2660,8 @@ void ice_vsi_free_irq(struct ice_vsi *vsi)
+                       continue;
+ 
+               /* clear the affinity notifier in the IRQ descriptor */
+-              irq_set_affinity_notifier(irq_num, NULL);
++              if (!IS_ENABLED(CONFIG_RFS_ACCEL))
++                      irq_set_affinity_notifier(irq_num, NULL);
+ 
+               /* clear the affinity_mask in the IRQ descriptor */
+               irq_set_affinity_hint(irq_num, NULL);
+diff --git a/drivers/net/ethernet/intel/ice/ice_main.c 
b/drivers/net/ethernet/intel/ice/ice_main.c
+index 735f8cef6bfa45..91840ea92b0dfe 100644
+--- a/drivers/net/ethernet/intel/ice/ice_main.c
++++ b/drivers/net/ethernet/intel/ice/ice_main.c
+@@ -2393,6 +2393,13 @@ static int ice_vsi_req_irq_msix(struct ice_vsi *vsi, 
char *basename)
+               irq_set_affinity_hint(irq_num, &q_vector->affinity_mask);
+       }
+ 
++      err = ice_set_cpu_rx_rmap(vsi);
++      if (err) {
++              netdev_err(vsi->netdev, "Failed to setup CPU RMAP on VSI %u: 
%pe\n",
++                         vsi->vsi_num, ERR_PTR(err));
++              goto free_q_irqs;
++      }
++
+       vsi->irqs_ready = true;
+       return 0;
+ 
+@@ -3380,22 +3387,12 @@ static int ice_setup_pf_sw(struct ice_pf *pf)
+        */
+       ice_napi_add(vsi);
+ 
+-      status = ice_set_cpu_rx_rmap(vsi);
+-      if (status) {
+-              dev_err(ice_pf_to_dev(pf), "Failed to set CPU Rx map VSI %d 
error %d\n",
+-                      vsi->vsi_num, status);
+-              status = -EINVAL;
+-              goto unroll_napi_add;
+-      }
+       status = ice_init_mac_fltr(pf);
+       if (status)
+-              goto free_cpu_rx_map;
++              goto unroll_napi_add;
+ 
+       return status;
+ 
+-free_cpu_rx_map:
+-      ice_free_cpu_rx_rmap(vsi);
+-
+ unroll_napi_add:
+       if (vsi) {
+               ice_napi_del(vsi);
+@@ -4886,7 +4883,6 @@ static int __maybe_unused ice_suspend(struct device *dev)
+                       continue;
+               ice_vsi_free_q_vectors(pf->vsi[v]);
+       }
+-      ice_free_cpu_rx_rmap(ice_get_main_vsi(pf));
+       ice_clear_interrupt_scheme(pf);
+ 
+       pci_save_state(pdev);
+diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c 
b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c
+index d7c93c409a7765..3bc2f83176d036 100644
+--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c
++++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c
+@@ -1485,8 +1485,11 @@ static int qlcnic_sriov_channel_cfg_cmd(struct 
qlcnic_adapter *adapter, u8 cmd_o
+       }
+ 
+       cmd_op = (cmd.rsp.arg[0] & 0xff);
+-      if (cmd.rsp.arg[0] >> 25 == 2)
+-              return 2;
++      if (cmd.rsp.arg[0] >> 25 == 2) {
++              ret = 2;
++              goto out;
++      }
++
+       if (cmd_op == QLCNIC_BC_CMD_CHANNEL_INIT)
+               set_bit(QLC_BC_VF_STATE, &vf->state);
+       else
+diff --git a/drivers/net/wireless/mediatek/mt76/dma.c 
b/drivers/net/wireless/mediatek/mt76/dma.c
+index f225a34e218619..e0d6d7ee66defd 100644
+--- a/drivers/net/wireless/mediatek/mt76/dma.c
++++ b/drivers/net/wireless/mediatek/mt76/dma.c
+@@ -684,6 +684,7 @@ void mt76_dma_cleanup(struct mt76_dev *dev)
+       int i;
+ 
+       mt76_worker_disable(&dev->tx_worker);
++      napi_disable(&dev->tx_napi);
+       netif_napi_del(&dev->tx_napi);
+ 
+       for (i = 0; i < ARRAY_SIZE(dev->phy.q_tx); i++) {
+diff --git a/drivers/phy/renesas/phy-rcar-gen3-usb2.c 
b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
+index 7e61c6b278a742..670514d44fe3fc 100644
+--- a/drivers/phy/renesas/phy-rcar-gen3-usb2.c
++++ b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
+@@ -453,8 +453,11 @@ static int rcar_gen3_phy_usb2_init(struct phy *p)
+       val = readl(usb2_base + USB2_INT_ENABLE);
+       val |= USB2_INT_ENABLE_UCOM_INTEN | rphy->int_enable_bits;
+       writel(val, usb2_base + USB2_INT_ENABLE);
+-      writel(USB2_SPD_RSM_TIMSET_INIT, usb2_base + USB2_SPD_RSM_TIMSET);
+-      writel(USB2_OC_TIMSET_INIT, usb2_base + USB2_OC_TIMSET);
++
++      if (!rcar_gen3_is_any_rphy_initialized(channel)) {
++              writel(USB2_SPD_RSM_TIMSET_INIT, usb2_base + 
USB2_SPD_RSM_TIMSET);
++              writel(USB2_OC_TIMSET_INIT, usb2_base + USB2_OC_TIMSET);
++      }
+ 
+       /* Initialize otg part */
+       if (channel->is_otg_channel) {
+diff --git a/drivers/phy/tegra/xusb.c b/drivers/phy/tegra/xusb.c
+index be31b1e25b3806..17a119e8cf7ed0 100644
+--- a/drivers/phy/tegra/xusb.c
++++ b/drivers/phy/tegra/xusb.c
+@@ -542,16 +542,16 @@ static int tegra_xusb_port_init(struct tegra_xusb_port 
*port,
+ 
+       err = dev_set_name(&port->dev, "%s-%u", name, index);
+       if (err < 0)
+-              goto unregister;
++              goto put_device;
+ 
+       err = device_add(&port->dev);
+       if (err < 0)
+-              goto unregister;
++              goto put_device;
+ 
+       return 0;
+ 
+-unregister:
+-      device_unregister(&port->dev);
++put_device:
++      put_device(&port->dev);
+       return err;
+ }
+ 
+diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
+index a34d0f53ad16f2..d9933d37181296 100644
+--- a/drivers/platform/x86/asus-wmi.c
++++ b/drivers/platform/x86/asus-wmi.c
+@@ -3052,7 +3052,8 @@ static int asus_wmi_add(struct platform_device *pdev)
+               goto fail_leds;
+ 
+       asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_WLAN, &result);
+-      if (result & (ASUS_WMI_DSTS_PRESENCE_BIT | ASUS_WMI_DSTS_USER_BIT))
++      if ((result & (ASUS_WMI_DSTS_PRESENCE_BIT | ASUS_WMI_DSTS_USER_BIT)) ==
++          (ASUS_WMI_DSTS_PRESENCE_BIT | ASUS_WMI_DSTS_USER_BIT))
+               asus->driver->wlan_ctrl_by_user = 1;
+ 
+       if (!(asus->driver->wlan_ctrl_by_user && ashs_present())) {
+diff --git a/drivers/spi/spi-loopback-test.c b/drivers/spi/spi-loopback-test.c
+index 4d4f77a186a98a..89fccb9da1b8ee 100644
+--- a/drivers/spi/spi-loopback-test.c
++++ b/drivers/spi/spi-loopback-test.c
+@@ -383,7 +383,7 @@ MODULE_LICENSE("GPL");
+ static void spi_test_print_hex_dump(char *pre, const void *ptr, size_t len)
+ {
+       /* limit the hex_dump */
+-      if (len < 1024) {
++      if (len <= 1024) {
+               print_hex_dump(KERN_INFO, pre,
+                              DUMP_PREFIX_OFFSET, 16, 1,
+                              ptr, len, 0);
+diff --git a/drivers/usb/typec/altmodes/displayport.c 
b/drivers/usb/typec/altmodes/displayport.c
+index 8f0c6da27dd1b1..97a912f0c4eed4 100644
+--- a/drivers/usb/typec/altmodes/displayport.c
++++ b/drivers/usb/typec/altmodes/displayport.c
+@@ -521,22 +521,26 @@ static ssize_t pin_assignment_show(struct device *dev,
+ }
+ static DEVICE_ATTR_RW(pin_assignment);
+ 
+-static struct attribute *dp_altmode_attrs[] = {
++static struct attribute *displayport_attrs[] = {
+       &dev_attr_configuration.attr,
+       &dev_attr_pin_assignment.attr,
+       NULL
+ };
+ 
+-static const struct attribute_group dp_altmode_group = {
++static const struct attribute_group displayport_group = {
+       .name = "displayport",
+-      .attrs = dp_altmode_attrs,
++      .attrs = displayport_attrs,
++};
++
++static const struct attribute_group *displayport_groups[] = {
++      &displayport_group,
++      NULL,
+ };
+ 
+ int dp_altmode_probe(struct typec_altmode *alt)
+ {
+       const struct typec_altmode *port = typec_altmode_get_partner(alt);
+       struct dp_altmode *dp;
+-      int ret;
+ 
+       /* FIXME: Port can only be DFP_U. */
+ 
+@@ -547,10 +551,6 @@ int dp_altmode_probe(struct typec_altmode *alt)
+             DP_CAP_PIN_ASSIGN_DFP_D(alt->vdo)))
+               return -ENODEV;
+ 
+-      ret = sysfs_create_group(&alt->dev.kobj, &dp_altmode_group);
+-      if (ret)
+-              return ret;
+-
+       dp = devm_kzalloc(&alt->dev, sizeof(*dp), GFP_KERNEL);
+       if (!dp)
+               return -ENOMEM;
+@@ -576,7 +576,6 @@ void dp_altmode_remove(struct typec_altmode *alt)
+ {
+       struct dp_altmode *dp = typec_altmode_get_drvdata(alt);
+ 
+-      sysfs_remove_group(&alt->dev.kobj, &dp_altmode_group);
+       cancel_work_sync(&dp->work);
+ }
+ EXPORT_SYMBOL_GPL(dp_altmode_remove);
+@@ -594,6 +593,7 @@ static struct typec_altmode_driver dp_altmode_driver = {
+       .driver = {
+               .name = "typec_displayport",
+               .owner = THIS_MODULE,
++              .dev_groups = displayport_groups,
+       },
+ };
+ module_typec_altmode_driver(dp_altmode_driver);
+diff --git a/drivers/usb/typec/ucsi/displayport.c 
b/drivers/usb/typec/ucsi/displayport.c
+index 8c19081c325542..e3b5fa3b5f955d 100644
+--- a/drivers/usb/typec/ucsi/displayport.c
++++ b/drivers/usb/typec/ucsi/displayport.c
+@@ -54,7 +54,8 @@ static int ucsi_displayport_enter(struct typec_altmode *alt, 
u32 *vdo)
+       u8 cur = 0;
+       int ret;
+ 
+-      mutex_lock(&dp->con->lock);
++      if (!ucsi_con_mutex_lock(dp->con))
++              return -ENOTCONN;
+ 
+       if (!dp->override && dp->initialized) {
+               const struct typec_altmode *p = typec_altmode_get_partner(alt);
+@@ -100,7 +101,7 @@ static int ucsi_displayport_enter(struct typec_altmode 
*alt, u32 *vdo)
+       schedule_work(&dp->work);
+       ret = 0;
+ err_unlock:
+-      mutex_unlock(&dp->con->lock);
++      ucsi_con_mutex_unlock(dp->con);
+ 
+       return ret;
+ }
+@@ -112,7 +113,8 @@ static int ucsi_displayport_exit(struct typec_altmode *alt)
+       u64 command;
+       int ret = 0;
+ 
+-      mutex_lock(&dp->con->lock);
++      if (!ucsi_con_mutex_lock(dp->con))
++              return -ENOTCONN;
+ 
+       if (!dp->override) {
+               const struct typec_altmode *p = typec_altmode_get_partner(alt);
+@@ -144,7 +146,7 @@ static int ucsi_displayport_exit(struct typec_altmode *alt)
+       schedule_work(&dp->work);
+ 
+ out_unlock:
+-      mutex_unlock(&dp->con->lock);
++      ucsi_con_mutex_unlock(dp->con);
+ 
+       return ret;
+ }
+@@ -202,20 +204,21 @@ static int ucsi_displayport_vdm(struct typec_altmode 
*alt,
+       int cmd = PD_VDO_CMD(header);
+       int svdm_version;
+ 
+-      mutex_lock(&dp->con->lock);
++      if (!ucsi_con_mutex_lock(dp->con))
++              return -ENOTCONN;
+ 
+       if (!dp->override && dp->initialized) {
+               const struct typec_altmode *p = typec_altmode_get_partner(alt);
+ 
+               dev_warn(&p->dev,
+                        "firmware doesn't support alternate mode 
overriding\n");
+-              mutex_unlock(&dp->con->lock);
++              ucsi_con_mutex_unlock(dp->con);
+               return -EOPNOTSUPP;
+       }
+ 
+       svdm_version = typec_altmode_get_svdm_version(alt);
+       if (svdm_version < 0) {
+-              mutex_unlock(&dp->con->lock);
++              ucsi_con_mutex_unlock(dp->con);
+               return svdm_version;
+       }
+ 
+@@ -259,7 +262,7 @@ static int ucsi_displayport_vdm(struct typec_altmode *alt,
+               break;
+       }
+ 
+-      mutex_unlock(&dp->con->lock);
++      ucsi_con_mutex_unlock(dp->con);
+ 
+       return 0;
+ }
+diff --git a/drivers/usb/typec/ucsi/ucsi.c b/drivers/usb/typec/ucsi/ucsi.c
+index 979af06f22d837..e42e146d5bed93 100644
+--- a/drivers/usb/typec/ucsi/ucsi.c
++++ b/drivers/usb/typec/ucsi/ucsi.c
+@@ -1351,6 +1351,40 @@ void ucsi_set_drvdata(struct ucsi *ucsi, void *data)
+ }
+ EXPORT_SYMBOL_GPL(ucsi_set_drvdata);
+ 
++/**
++ * ucsi_con_mutex_lock - Acquire the connector mutex
++ * @con: The connector interface to lock
++ *
++ * Returns true on success, false if the connector is disconnected
++ */
++bool ucsi_con_mutex_lock(struct ucsi_connector *con)
++{
++      bool mutex_locked = false;
++      bool connected = true;
++
++      while (connected && !mutex_locked) {
++              mutex_locked = mutex_trylock(&con->lock) != 0;
++              connected = con->status.flags & UCSI_CONSTAT_CONNECTED;
++              if (connected && !mutex_locked)
++                      msleep(20);
++      }
++
++      connected = connected && con->partner;
++      if (!connected && mutex_locked)
++              mutex_unlock(&con->lock);
++
++      return connected;
++}
++
++/**
++ * ucsi_con_mutex_unlock - Release the connector mutex
++ * @con: The connector interface to unlock
++ */
++void ucsi_con_mutex_unlock(struct ucsi_connector *con)
++{
++      mutex_unlock(&con->lock);
++}
++
+ /**
+  * ucsi_create - Allocate UCSI instance
+  * @dev: Device interface to the PPM (Platform Policy Manager)
+diff --git a/drivers/usb/typec/ucsi/ucsi.h b/drivers/usb/typec/ucsi/ucsi.h
+index 656a53ccd89178..87b1a54d68e8bd 100644
+--- a/drivers/usb/typec/ucsi/ucsi.h
++++ b/drivers/usb/typec/ucsi/ucsi.h
+@@ -15,6 +15,7 @@
+ 
+ struct ucsi;
+ struct ucsi_altmode;
++struct ucsi_connector;
+ 
+ /* UCSI offsets (Bytes) */
+ #define UCSI_VERSION                  0
+@@ -62,6 +63,8 @@ int ucsi_register(struct ucsi *ucsi);
+ void ucsi_unregister(struct ucsi *ucsi);
+ void *ucsi_get_drvdata(struct ucsi *ucsi);
+ void ucsi_set_drvdata(struct ucsi *ucsi, void *data);
++bool ucsi_con_mutex_lock(struct ucsi_connector *con);
++void ucsi_con_mutex_unlock(struct ucsi_connector *con);
+ 
+ void ucsi_connector_change(struct ucsi *ucsi, u8 num);
+ 
+diff --git a/drivers/usb/typec/ucsi/ucsi_ccg.c 
b/drivers/usb/typec/ucsi/ucsi_ccg.c
+index fb6211efb5d871..dffdb5eb506b7b 100644
+--- a/drivers/usb/typec/ucsi/ucsi_ccg.c
++++ b/drivers/usb/typec/ucsi/ucsi_ccg.c
+@@ -573,6 +573,10 @@ static int ucsi_ccg_sync_write(struct ucsi *ucsi, 
unsigned int offset,
+                   uc->has_multiple_dp) {
+                       con_index = (uc->last_cmd_sent >> 16) &
+                                   UCSI_CMD_CONNECTOR_MASK;
++                      if (con_index == 0) {
++                              ret = -EINVAL;
++                              goto err_put;
++                      }
+                       con = &uc->ucsi->connector[con_index - 1];
+                       ucsi_ccg_update_set_new_cam_cmd(uc, con, (u64 *)val);
+               }
+@@ -587,6 +591,7 @@ static int ucsi_ccg_sync_write(struct ucsi *ucsi, unsigned 
int offset,
+ 
+ err_clear_bit:
+       clear_bit(DEV_CMD_PENDING, &uc->flags);
++err_put:
+       pm_runtime_put_sync(uc->dev);
+       mutex_unlock(&uc->lock);
+ 
+diff --git a/fs/btrfs/discard.c b/fs/btrfs/discard.c
+index bd9dde374e5d81..7b2f77a8aa982d 100644
+--- a/fs/btrfs/discard.c
++++ b/fs/btrfs/discard.c
+@@ -78,8 +78,6 @@ static void __add_to_discard_list(struct btrfs_discard_ctl 
*discard_ctl,
+                                 struct btrfs_block_group *block_group)
+ {
+       lockdep_assert_held(&discard_ctl->lock);
+-      if (!btrfs_run_discard_work(discard_ctl))
+-              return;
+ 
+       if (list_empty(&block_group->discard_list) ||
+           block_group->discard_index == BTRFS_DISCARD_INDEX_UNUSED) {
+@@ -102,6 +100,9 @@ static void add_to_discard_list(struct btrfs_discard_ctl 
*discard_ctl,
+       if (!btrfs_is_block_group_data_only(block_group))
+               return;
+ 
++      if (!btrfs_run_discard_work(discard_ctl))
++              return;
++
+       spin_lock(&discard_ctl->lock);
+       __add_to_discard_list(discard_ctl, block_group);
+       spin_unlock(&discard_ctl->lock);
+@@ -233,6 +234,18 @@ static struct btrfs_block_group *peek_discard_list(
+                   block_group->used != 0) {
+                       if (btrfs_is_block_group_data_only(block_group)) {
+                               __add_to_discard_list(discard_ctl, block_group);
++                              /*
++                               * The block group must have been moved to other
++                               * discard list even if discard was disabled in
++                               * the meantime or a transaction abort happened,
++                               * otherwise we can end up in an infinite loop,
++                               * always jumping into the 'again' label and
++                               * keep getting this block group over and over
++                               * in case there are no other block groups in
++                               * the discard lists.
++                               */
++                              ASSERT(block_group->discard_index !=
++                                     BTRFS_DISCARD_INDEX_UNUSED);
+                       } else {
+                               list_del_init(&block_group->discard_list);
+                               btrfs_put_block_group(block_group);
+diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
+index 551faae77bc313..8959506a0aa775 100644
+--- a/fs/btrfs/extent-tree.c
++++ b/fs/btrfs/extent-tree.c
+@@ -176,6 +176,14 @@ int btrfs_lookup_extent_info(struct btrfs_trans_handle 
*trans,
+                       ei = btrfs_item_ptr(leaf, path->slots[0],
+                                           struct btrfs_extent_item);
+                       num_refs = btrfs_extent_refs(leaf, ei);
++                      if (unlikely(num_refs == 0)) {
++                              ret = -EUCLEAN;
++                              btrfs_err(fs_info,
++                      "unexpected zero reference count for extent item (%llu 
%u %llu)",
++                                        key.objectid, key.type, key.offset);
++                              btrfs_abort_transaction(trans, ret);
++                              goto out_free;
++                      }
+                       extent_flags = btrfs_extent_flags(leaf, ei);
+               } else {
+                       ret = -EINVAL;
+@@ -187,8 +195,6 @@ int btrfs_lookup_extent_info(struct btrfs_trans_handle 
*trans,
+ 
+                       goto out_free;
+               }
+-
+-              BUG_ON(num_refs == 0);
+       } else {
+               num_refs = 0;
+               extent_flags = 0;
+@@ -218,10 +224,19 @@ int btrfs_lookup_extent_info(struct btrfs_trans_handle 
*trans,
+                       goto search_again;
+               }
+               spin_lock(&head->lock);
+-              if (head->extent_op && head->extent_op->update_flags)
++              if (head->extent_op && head->extent_op->update_flags) {
+                       extent_flags |= head->extent_op->flags_to_set;
+-              else
+-                      BUG_ON(num_refs == 0);
++              } else if (unlikely(num_refs == 0)) {
++                      spin_unlock(&head->lock);
++                      mutex_unlock(&head->mutex);
++                      spin_unlock(&delayed_refs->lock);
++                      ret = -EUCLEAN;
++                      btrfs_err(fs_info,
++                        "unexpected zero reference count for extent %llu 
(%s)",
++                                bytenr, metadata ? "metadata" : "data");
++                      btrfs_abort_transaction(trans, ret);
++                      goto out_free;
++              }
+ 
+               num_refs += head->ref_mod;
+               spin_unlock(&head->lock);
+diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
+index 346fc46d019bf7..a1946d62911c9f 100644
+--- a/fs/btrfs/extent_io.c
++++ b/fs/btrfs/extent_io.c
+@@ -2624,7 +2624,6 @@ int btrfs_repair_one_sector(struct inode *inode,
+       const int icsum = bio_offset >> fs_info->sectorsize_bits;
+       struct bio *repair_bio;
+       struct btrfs_io_bio *repair_io_bio;
+-      blk_status_t status;
+ 
+       btrfs_debug(fs_info,
+                  "repair read error: read error at %llu", start);
+@@ -2664,13 +2663,13 @@ int btrfs_repair_one_sector(struct inode *inode,
+                   "repair read error: submitting new read to mirror %d",
+                   failrec->this_mirror);
+ 
+-      status = submit_bio_hook(inode, repair_bio, failrec->this_mirror,
+-                               failrec->bio_flags);
+-      if (status) {
+-              free_io_failure(failure_tree, tree, failrec);
+-              bio_put(repair_bio);
+-      }
+-      return blk_status_to_errno(status);
++      /*
++       * At this point we have a bio, so any errors from submit_bio_hook()
++       * will be handled by the endio on the repair_bio, so we can't return an
++       * error here.
++       */
++      submit_bio_hook(inode, repair_bio, failrec->this_mirror, 
failrec->bio_flags);
++      return BLK_STS_OK;
+ }
+ 
+ static void end_page_read(struct page *page, bool uptodate, u64 start, u32 
len)
+diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
+index 4a0691aeb7c1db..e4b3f25bb8e48b 100644
+--- a/fs/nfs/nfs4proc.c
++++ b/fs/nfs/nfs4proc.c
+@@ -6835,10 +6835,18 @@ static struct nfs4_unlockdata 
*nfs4_alloc_unlockdata(struct file_lock *fl,
+       struct nfs4_unlockdata *p;
+       struct nfs4_state *state = lsp->ls_state;
+       struct inode *inode = state->inode;
++      struct nfs_lock_context *l_ctx;
+ 
+       p = kzalloc(sizeof(*p), GFP_KERNEL);
+       if (p == NULL)
+               return NULL;
++      l_ctx = nfs_get_lock_context(ctx);
++      if (!IS_ERR(l_ctx)) {
++              p->l_ctx = l_ctx;
++      } else {
++              kfree(p);
++              return NULL;
++      }
+       p->arg.fh = NFS_FH(inode);
+       p->arg.fl = &p->fl;
+       p->arg.seqid = seqid;
+@@ -6846,7 +6854,6 @@ static struct nfs4_unlockdata 
*nfs4_alloc_unlockdata(struct file_lock *fl,
+       p->lsp = lsp;
+       /* Ensure we don't close file until we're done freeing locks! */
+       p->ctx = get_nfs_open_context(ctx);
+-      p->l_ctx = nfs_get_lock_context(ctx);
+       locks_init_lock(&p->fl);
+       locks_copy_lock(&p->fl, fl);
+       p->server = NFS_SERVER(inode);
+diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c
+index 4016cc5316230e..83935bb1719ad9 100644
+--- a/fs/nfs/pnfs.c
++++ b/fs/nfs/pnfs.c
+@@ -729,6 +729,14 @@ pnfs_mark_matching_lsegs_invalid(struct pnfs_layout_hdr 
*lo,
+       return remaining;
+ }
+ 
++static void pnfs_reset_return_info(struct pnfs_layout_hdr *lo)
++{
++      struct pnfs_layout_segment *lseg;
++
++      list_for_each_entry(lseg, &lo->plh_return_segs, pls_list)
++              pnfs_set_plh_return_info(lo, lseg->pls_range.iomode, 0);
++}
++
+ static void
+ pnfs_free_returned_lsegs(struct pnfs_layout_hdr *lo,
+               struct list_head *free_me,
+@@ -1177,6 +1185,7 @@ void pnfs_layoutreturn_free_lsegs(struct pnfs_layout_hdr 
*lo,
+               pnfs_mark_matching_lsegs_invalid(lo, &freeme, range, seq);
+               pnfs_free_returned_lsegs(lo, &freeme, range, seq);
+               pnfs_set_layout_stateid(lo, stateid, NULL, true);
++              pnfs_reset_return_info(lo);
+       } else
+               pnfs_mark_layout_stateid_invalid(lo, &freeme);
+ out_unlock:
+diff --git a/include/linux/cpu.h b/include/linux/cpu.h
+index e1e6a045c38b77..87b5a176e84897 100644
+--- a/include/linux/cpu.h
++++ b/include/linux/cpu.h
+@@ -76,6 +76,8 @@ extern ssize_t cpu_show_gds(struct device *dev,
+                           struct device_attribute *attr, char *buf);
+ extern ssize_t cpu_show_reg_file_data_sampling(struct device *dev,
+                                              struct device_attribute *attr, 
char *buf);
++extern ssize_t cpu_show_indirect_target_selection(struct device *dev,
++                                                struct device_attribute 
*attr, char *buf);
+ 
+ extern __printf(4, 5)
+ struct device *cpu_device_create(struct device *parent, void *drvdata,
+diff --git a/include/linux/module.h b/include/linux/module.h
+index fb9762e16f2858..8e629b03ed1e41 100644
+--- a/include/linux/module.h
++++ b/include/linux/module.h
+@@ -528,6 +528,11 @@ struct module {
+       atomic_t refcnt;
+ #endif
+ 
++#ifdef CONFIG_MITIGATION_ITS
++      int its_num_pages;
++      void **its_page_array;
++#endif
++
+ #ifdef CONFIG_CONSTRUCTORS
+       /* Constructor functions. */
+       ctor_fn_t *ctors;
+diff --git a/include/net/netfilter/nf_tables.h 
b/include/net/netfilter/nf_tables.h
+index 9ee225cff61129..605d4c0a63e9a7 100644
+--- a/include/net/netfilter/nf_tables.h
++++ b/include/net/netfilter/nf_tables.h
+@@ -1088,7 +1088,7 @@ static inline bool nft_chain_is_bound(struct nft_chain 
*chain)
+ 
+ int nft_chain_add(struct nft_table *table, struct nft_chain *chain);
+ void nft_chain_del(struct nft_chain *chain);
+-void nf_tables_chain_destroy(struct nft_ctx *ctx);
++void nf_tables_chain_destroy(struct nft_chain *chain);
+ 
+ struct nft_stats {
+       u64                     bytes;
+diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h
+index 0919dfd3a67a68..55127305478dfd 100644
+--- a/include/net/sch_generic.h
++++ b/include/net/sch_generic.h
+@@ -1035,6 +1035,21 @@ static inline struct sk_buff 
*__qdisc_dequeue_head(struct qdisc_skb_head *qh)
+       return skb;
+ }
+ 
++static inline struct sk_buff *qdisc_dequeue_internal(struct Qdisc *sch, bool 
direct)
++{
++      struct sk_buff *skb;
++
++      skb = __skb_dequeue(&sch->gso_skb);
++      if (skb) {
++              sch->q.qlen--;
++              return skb;
++      }
++      if (direct)
++              return __qdisc_dequeue_head(&sch->q);
++      else
++              return sch->dequeue(sch);
++}
++
+ static inline struct sk_buff *qdisc_dequeue_head(struct Qdisc *sch)
+ {
+       struct sk_buff *skb = __qdisc_dequeue_head(&sch->q);
+diff --git a/kernel/trace/trace_dynevent.c b/kernel/trace/trace_dynevent.c
+index d4f71372332349..6d0e9f869ad688 100644
+--- a/kernel/trace/trace_dynevent.c
++++ b/kernel/trace/trace_dynevent.c
+@@ -16,7 +16,7 @@
+ #include "trace_output.h"     /* for trace_event_sem */
+ #include "trace_dynevent.h"
+ 
+-static DEFINE_MUTEX(dyn_event_ops_mutex);
++DEFINE_MUTEX(dyn_event_ops_mutex);
+ static LIST_HEAD(dyn_event_ops_list);
+ 
+ bool trace_event_dyn_try_get_ref(struct trace_event_call *dyn_call)
+@@ -125,6 +125,20 @@ int dyn_event_release(const char *raw_command, struct 
dyn_event_operations *type
+       return ret;
+ }
+ 
++/*
++ * Locked version of event creation. The event creation must be protected by
++ * dyn_event_ops_mutex because of protecting trace_probe_log.
++ */
++int dyn_event_create(const char *raw_command, struct dyn_event_operations 
*type)
++{
++      int ret;
++
++      mutex_lock(&dyn_event_ops_mutex);
++      ret = type->create(raw_command);
++      mutex_unlock(&dyn_event_ops_mutex);
++      return ret;
++}
++
+ static int create_dyn_event(const char *raw_command)
+ {
+       struct dyn_event_operations *ops;
+diff --git a/kernel/trace/trace_dynevent.h b/kernel/trace/trace_dynevent.h
+index 936477a111d3e7..beee3f8d754444 100644
+--- a/kernel/trace/trace_dynevent.h
++++ b/kernel/trace/trace_dynevent.h
+@@ -100,6 +100,7 @@ void *dyn_event_seq_next(struct seq_file *m, void *v, 
loff_t *pos);
+ void dyn_event_seq_stop(struct seq_file *m, void *v);
+ int dyn_events_release_all(struct dyn_event_operations *type);
+ int dyn_event_release(const char *raw_command, struct dyn_event_operations 
*type);
++int dyn_event_create(const char *raw_command, struct dyn_event_operations 
*type);
+ 
+ /*
+  * for_each_dyn_event -       iterate over the dyn_event list
+diff --git a/kernel/trace/trace_events_trigger.c 
b/kernel/trace/trace_events_trigger.c
+index 106f9813841a15..d56e208f5cb8f9 100644
+--- a/kernel/trace/trace_events_trigger.c
++++ b/kernel/trace/trace_events_trigger.c
+@@ -1244,7 +1244,7 @@ stacktrace_trigger(struct event_trigger_data *data,
+       struct trace_event_file *file = data->private_data;
+ 
+       if (file)
+-              __trace_stack(file->tr, tracing_gen_ctx(), STACK_SKIP);
++              __trace_stack(file->tr, tracing_gen_ctx_dec(), STACK_SKIP);
+       else
+               trace_dump_stack(STACK_SKIP);
+ }
+diff --git a/kernel/trace/trace_functions.c b/kernel/trace/trace_functions.c
+index 1f0e63f5d1f983..18b8580971f6bd 100644
+--- a/kernel/trace/trace_functions.c
++++ b/kernel/trace/trace_functions.c
+@@ -568,11 +568,7 @@ ftrace_traceoff(unsigned long ip, unsigned long parent_ip,
+ 
+ static __always_inline void trace_stack(struct trace_array *tr)
+ {
+-      unsigned int trace_ctx;
+-
+-      trace_ctx = tracing_gen_ctx();
+-
+-      __trace_stack(tr, trace_ctx, FTRACE_STACK_SKIP);
++      __trace_stack(tr, tracing_gen_ctx_dec(), FTRACE_STACK_SKIP);
+ }
+ 
+ static void
+diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c
+index 3a1c54c9918b44..e062f4efec8d0a 100644
+--- a/kernel/trace/trace_kprobe.c
++++ b/kernel/trace/trace_kprobe.c
+@@ -971,7 +971,7 @@ static int create_or_delete_trace_kprobe(const char 
*raw_command)
+       if (raw_command[0] == '-')
+               return dyn_event_release(raw_command, &trace_kprobe_ops);
+ 
+-      ret = trace_kprobe_create(raw_command);
++      ret = dyn_event_create(raw_command, &trace_kprobe_ops);
+       return ret == -ECANCELED ? -EINVAL : ret;
+ }
+ 
+diff --git a/kernel/trace/trace_probe.c b/kernel/trace/trace_probe.c
+index d2a1b7f0306855..38fa6cc118dafa 100644
+--- a/kernel/trace/trace_probe.c
++++ b/kernel/trace/trace_probe.c
+@@ -143,9 +143,12 @@ static const struct fetch_type *find_fetch_type(const 
char *type)
+ }
+ 
+ static struct trace_probe_log trace_probe_log;
++extern struct mutex dyn_event_ops_mutex;
+ 
+ void trace_probe_log_init(const char *subsystem, int argc, const char **argv)
+ {
++      lockdep_assert_held(&dyn_event_ops_mutex);
++
+       trace_probe_log.subsystem = subsystem;
+       trace_probe_log.argc = argc;
+       trace_probe_log.argv = argv;
+@@ -154,11 +157,15 @@ void trace_probe_log_init(const char *subsystem, int 
argc, const char **argv)
+ 
+ void trace_probe_log_clear(void)
+ {
++      lockdep_assert_held(&dyn_event_ops_mutex);
++
+       memset(&trace_probe_log, 0, sizeof(trace_probe_log));
+ }
+ 
+ void trace_probe_log_set_index(int index)
+ {
++      lockdep_assert_held(&dyn_event_ops_mutex);
++
+       trace_probe_log.index = index;
+ }
+ 
+@@ -167,6 +174,8 @@ void __trace_probe_log_err(int offset, int err_type)
+       char *command, *p;
+       int i, len = 0, pos = 0;
+ 
++      lockdep_assert_held(&dyn_event_ops_mutex);
++
+       if (!trace_probe_log.argv)
+               return;
+ 
+diff --git a/kernel/trace/trace_uprobe.c b/kernel/trace/trace_uprobe.c
+index 720b46b34ab941..322d56661d04ad 100644
+--- a/kernel/trace/trace_uprobe.c
++++ b/kernel/trace/trace_uprobe.c
+@@ -729,7 +729,7 @@ static int create_or_delete_trace_uprobe(const char 
*raw_command)
+       if (raw_command[0] == '-')
+               return dyn_event_release(raw_command, &trace_uprobe_ops);
+ 
+-      ret = trace_uprobe_create(raw_command);
++      ret = dyn_event_create(raw_command, &trace_uprobe_ops);
+       return ret == -ECANCELED ? -EINVAL : ret;
+ }
+ 
+diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
+index 07fdd5f18f3c9b..a1f60f275814cd 100644
+--- a/net/netfilter/nf_tables_api.c
++++ b/net/netfilter/nf_tables_api.c
+@@ -1981,9 +1981,9 @@ static void nf_tables_chain_free_chain_rules(struct 
nft_chain *chain)
+       kvfree(chain->rules_next);
+ }
+ 
+-void nf_tables_chain_destroy(struct nft_ctx *ctx)
++void nf_tables_chain_destroy(struct nft_chain *chain)
+ {
+-      struct nft_chain *chain = ctx->chain;
++      const struct nft_table *table = chain->table;
+       struct nft_hook *hook, *next;
+ 
+       if (WARN_ON(chain->use > 0))
+@@ -1995,7 +1995,7 @@ void nf_tables_chain_destroy(struct nft_ctx *ctx)
+       if (nft_is_base_chain(chain)) {
+               struct nft_base_chain *basechain = nft_base_chain(chain);
+ 
+-              if (nft_base_chain_netdev(ctx->family, basechain->ops.hooknum)) 
{
++              if (nft_base_chain_netdev(table->family, 
basechain->ops.hooknum)) {
+                       list_for_each_entry_safe(hook, next,
+                                                &basechain->hook_list, list) {
+                               list_del_rcu(&hook->list);
+@@ -2445,7 +2445,7 @@ static int nf_tables_addchain(struct nft_ctx *ctx, u8 
family, u8 genmask,
+ err_use:
+       nf_tables_unregister_hook(net, table, chain);
+ err_destroy_chain:
+-      nf_tables_chain_destroy(ctx);
++      nf_tables_chain_destroy(chain);
+ 
+       return err;
+ }
+@@ -3440,8 +3440,11 @@ void nf_tables_rule_destroy(const struct nft_ctx *ctx, 
struct nft_rule *rule)
+       kfree(rule);
+ }
+ 
++/* can only be used if rule is no longer visible to dumps */
+ static void nf_tables_rule_release(const struct nft_ctx *ctx, struct nft_rule 
*rule)
+ {
++      lockdep_commit_lock_is_held(ctx->net);
++
+       nft_rule_expr_deactivate(ctx, rule, NFT_TRANS_RELEASE);
+       nf_tables_rule_destroy(ctx, rule);
+ }
+@@ -5177,6 +5180,8 @@ void nf_tables_deactivate_set(const struct nft_ctx *ctx, 
struct nft_set *set,
+                             struct nft_set_binding *binding,
+                             enum nft_trans_phase phase)
+ {
++      lockdep_commit_lock_is_held(ctx->net);
++
+       switch (phase) {
+       case NFT_TRANS_PREPARE_ERROR:
+               nft_set_trans_unbind(ctx, set);
+@@ -8809,7 +8814,7 @@ static void nft_commit_release(struct nft_trans *trans)
+               kfree(nft_trans_chain_name(trans));
+               break;
+       case NFT_MSG_DELCHAIN:
+-              nf_tables_chain_destroy(&trans->ctx);
++              nf_tables_chain_destroy(nft_trans_chain(trans));
+               break;
+       case NFT_MSG_DELRULE:
+               nf_tables_rule_destroy(&trans->ctx, nft_trans_rule(trans));
+@@ -9721,7 +9726,7 @@ static void nf_tables_abort_release(struct nft_trans 
*trans)
+               nf_tables_table_destroy(&trans->ctx);
+               break;
+       case NFT_MSG_NEWCHAIN:
+-              nf_tables_chain_destroy(&trans->ctx);
++              nf_tables_chain_destroy(nft_trans_chain(trans));
+               break;
+       case NFT_MSG_NEWRULE:
+               nf_tables_rule_destroy(&trans->ctx, nft_trans_rule(trans));
+@@ -10428,23 +10433,43 @@ int nft_data_dump(struct sk_buff *skb, int attr, 
const struct nft_data *data,
+ }
+ EXPORT_SYMBOL_GPL(nft_data_dump);
+ 
+-int __nft_release_basechain(struct nft_ctx *ctx)
++static void __nft_release_basechain_now(struct nft_ctx *ctx)
+ {
+       struct nft_rule *rule, *nr;
+ 
+-      if (WARN_ON(!nft_is_base_chain(ctx->chain)))
+-              return 0;
+-
+-      nf_tables_unregister_hook(ctx->net, ctx->chain->table, ctx->chain);
+       list_for_each_entry_safe(rule, nr, &ctx->chain->rules, list) {
+               list_del(&rule->list);
+-              nft_use_dec(&ctx->chain->use);
+               nf_tables_rule_release(ctx, rule);
+       }
++      nf_tables_chain_destroy(ctx->chain);
++}
++
++int __nft_release_basechain(struct nft_ctx *ctx)
++{
++      struct nft_rule *rule;
++
++      if (WARN_ON_ONCE(!nft_is_base_chain(ctx->chain)))
++              return 0;
++
++      nf_tables_unregister_hook(ctx->net, ctx->chain->table, ctx->chain);
++      list_for_each_entry(rule, &ctx->chain->rules, list)
++              nft_use_dec(&ctx->chain->use);
++
+       nft_chain_del(ctx->chain);
+       nft_use_dec(&ctx->table->use);
+-      nf_tables_chain_destroy(ctx);
+ 
++      if (!maybe_get_net(ctx->net)) {
++              __nft_release_basechain_now(ctx);
++              return 0;
++      }
++
++      /* wait for ruleset dumps to complete.  Owning chain is no longer in
++       * lists, so new dumps can't find any of these rules anymore.
++       */
++      synchronize_rcu();
++
++      __nft_release_basechain_now(ctx);
++      put_net(ctx->net);
+       return 0;
+ }
+ EXPORT_SYMBOL_GPL(__nft_release_basechain);
+@@ -10519,10 +10544,9 @@ static void __nft_release_table(struct net *net, 
struct nft_table *table)
+               nft_obj_destroy(&ctx, obj);
+       }
+       list_for_each_entry_safe(chain, nc, &table->chains, list) {
+-              ctx.chain = chain;
+               nft_chain_del(chain);
+               nft_use_dec(&table->use);
+-              nf_tables_chain_destroy(&ctx);
++              nf_tables_chain_destroy(chain);
+       }
+       nf_tables_table_destroy(&ctx);
+ }
+diff --git a/net/netfilter/nft_immediate.c b/net/netfilter/nft_immediate.c
+index d154fe67ca8a63..a889cf1d863ef3 100644
+--- a/net/netfilter/nft_immediate.c
++++ b/net/netfilter/nft_immediate.c
+@@ -221,7 +221,7 @@ static void nft_immediate_destroy(const struct nft_ctx 
*ctx,
+                       list_del(&rule->list);
+                       nf_tables_rule_destroy(&chain_ctx, rule);
+               }
+-              nf_tables_chain_destroy(&chain_ctx);
++              nf_tables_chain_destroy(chain);
+               break;
+       default:
+               break;
+diff --git a/net/sched/sch_codel.c b/net/sched/sch_codel.c
+index 30169b3adbbb06..d99c7386e24e6b 100644
+--- a/net/sched/sch_codel.c
++++ b/net/sched/sch_codel.c
+@@ -174,7 +174,7 @@ static int codel_change(struct Qdisc *sch, struct nlattr 
*opt,
+ 
+       qlen = sch->q.qlen;
+       while (sch->q.qlen > sch->limit) {
+-              struct sk_buff *skb = __qdisc_dequeue_head(&sch->q);
++              struct sk_buff *skb = qdisc_dequeue_internal(sch, true);
+ 
+               dropped += qdisc_pkt_len(skb);
+               qdisc_qstats_backlog_dec(sch, skb);
+diff --git a/net/sched/sch_fq.c b/net/sched/sch_fq.c
+index 5a1274199fe336..65b12b39e2ec5d 100644
+--- a/net/sched/sch_fq.c
++++ b/net/sched/sch_fq.c
+@@ -904,7 +904,7 @@ static int fq_change(struct Qdisc *sch, struct nlattr *opt,
+               sch_tree_lock(sch);
+       }
+       while (sch->q.qlen > sch->limit) {
+-              struct sk_buff *skb = fq_dequeue(sch);
++              struct sk_buff *skb = qdisc_dequeue_internal(sch, false);
+ 
+               if (!skb)
+                       break;
+diff --git a/net/sched/sch_fq_codel.c b/net/sched/sch_fq_codel.c
+index efda894bbb78b2..f954969ea8fece 100644
+--- a/net/sched/sch_fq_codel.c
++++ b/net/sched/sch_fq_codel.c
+@@ -429,7 +429,7 @@ static int fq_codel_change(struct Qdisc *sch, struct 
nlattr *opt,
+ 
+       while (sch->q.qlen > sch->limit ||
+              q->memory_usage > q->memory_limit) {
+-              struct sk_buff *skb = fq_codel_dequeue(sch);
++              struct sk_buff *skb = qdisc_dequeue_internal(sch, false);
+ 
+               q->cstats.drop_len += qdisc_pkt_len(skb);
+               rtnl_kfree_skbs(skb, skb);
+diff --git a/net/sched/sch_fq_pie.c b/net/sched/sch_fq_pie.c
+index 1fb68c973f4510..30259c87564511 100644
+--- a/net/sched/sch_fq_pie.c
++++ b/net/sched/sch_fq_pie.c
+@@ -360,7 +360,7 @@ static int fq_pie_change(struct Qdisc *sch, struct nlattr 
*opt,
+ 
+       /* Drop excess packets if new limit is lower */
+       while (sch->q.qlen > sch->limit) {
+-              struct sk_buff *skb = fq_pie_qdisc_dequeue(sch);
++              struct sk_buff *skb = qdisc_dequeue_internal(sch, false);
+ 
+               len_dropped += qdisc_pkt_len(skb);
+               num_dropped += 1;
+diff --git a/net/sched/sch_hhf.c b/net/sched/sch_hhf.c
+index 420ede8753229f..433bddcbc0c724 100644
+--- a/net/sched/sch_hhf.c
++++ b/net/sched/sch_hhf.c
+@@ -563,7 +563,7 @@ static int hhf_change(struct Qdisc *sch, struct nlattr 
*opt,
+       qlen = sch->q.qlen;
+       prev_backlog = sch->qstats.backlog;
+       while (sch->q.qlen > sch->limit) {
+-              struct sk_buff *skb = hhf_dequeue(sch);
++              struct sk_buff *skb = qdisc_dequeue_internal(sch, false);
+ 
+               rtnl_kfree_skbs(skb, skb);
+       }
+diff --git a/net/sched/sch_pie.c b/net/sched/sch_pie.c
+index 5a457ff61acd87..67ce65af52b5cd 100644
+--- a/net/sched/sch_pie.c
++++ b/net/sched/sch_pie.c
+@@ -193,7 +193,7 @@ static int pie_change(struct Qdisc *sch, struct nlattr 
*opt,
+       /* Drop excess packets if new limit is lower */
+       qlen = sch->q.qlen;
+       while (sch->q.qlen > sch->limit) {
+-              struct sk_buff *skb = __qdisc_dequeue_head(&sch->q);
++              struct sk_buff *skb = qdisc_dequeue_internal(sch, true);
+ 
+               dropped += qdisc_pkt_len(skb);
+               qdisc_qstats_backlog_dec(sch, skb);
+diff --git a/net/sctp/sysctl.c b/net/sctp/sysctl.c
+index 916dc2e81e428f..f3d09998c24dea 100644
+--- a/net/sctp/sysctl.c
++++ b/net/sctp/sysctl.c
+@@ -518,6 +518,8 @@ static int proc_sctp_do_auth(struct ctl_table *ctl, int 
write,
+       return ret;
+ }
+ 
++static DEFINE_MUTEX(sctp_sysctl_mutex);
++
+ static int proc_sctp_do_udp_port(struct ctl_table *ctl, int write,
+                                void *buffer, size_t *lenp, loff_t *ppos)
+ {
+@@ -542,6 +544,7 @@ static int proc_sctp_do_udp_port(struct ctl_table *ctl, 
int write,
+               if (new_value > max || new_value < min)
+                       return -EINVAL;
+ 
++              mutex_lock(&sctp_sysctl_mutex);
+               net->sctp.udp_port = new_value;
+               sctp_udp_sock_stop(net);
+               if (new_value) {
+@@ -554,6 +557,7 @@ static int proc_sctp_do_udp_port(struct ctl_table *ctl, 
int write,
+               lock_sock(sk);
+               sctp_sk(sk)->udp_port = htons(net->sctp.udp_port);
+               release_sock(sk);
++              mutex_unlock(&sctp_sysctl_mutex);
+       }
+ 
+       return ret;
+diff --git a/samples/ftrace/sample-trace-array.c 
b/samples/ftrace/sample-trace-array.c
+index 6aba02a31c96c5..77685a7eb7678e 100644
+--- a/samples/ftrace/sample-trace-array.c
++++ b/samples/ftrace/sample-trace-array.c
+@@ -112,7 +112,7 @@ static int __init sample_trace_array_init(void)
+       /*
+        * If context specific per-cpu buffers havent already been allocated.
+        */
+-      trace_printk_init_buffers();
++      trace_array_init_printk(tr);
+ 
+       simple_tsk = kthread_run(simple_thread, NULL, "sample-instance");
+       if (IS_ERR(simple_tsk)) {
+diff --git a/sound/pci/es1968.c b/sound/pci/es1968.c
+index 4a7e20bb11bcae..802c5ed4a5ba4b 100644
+--- a/sound/pci/es1968.c
++++ b/sound/pci/es1968.c
+@@ -1569,7 +1569,7 @@ static int snd_es1968_capture_open(struct 
snd_pcm_substream *substream)
+       struct snd_pcm_runtime *runtime = substream->runtime;
+       struct es1968 *chip = snd_pcm_substream_chip(substream);
+       struct esschan *es;
+-      int apu1, apu2;
++      int err, apu1, apu2;
+ 
+       apu1 = snd_es1968_alloc_apu_pair(chip, ESM_APU_PCM_CAPTURE);
+       if (apu1 < 0)
+@@ -1613,7 +1613,9 @@ static int snd_es1968_capture_open(struct 
snd_pcm_substream *substream)
+       runtime->hw = snd_es1968_capture;
+       runtime->hw.buffer_bytes_max = runtime->hw.period_bytes_max =
+               calc_available_memory_size(chip) - 1024; /* keep MIXBUF size */
+-      snd_pcm_hw_constraint_pow2(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES);
++      err = snd_pcm_hw_constraint_pow2(runtime, 0, 
SNDRV_PCM_HW_PARAM_BUFFER_BYTES);
++      if (err < 0)
++              return err;
+ 
+       spin_lock_irq(&chip->substream_lock);
+       list_add(&es->list, &chip->substream_list);
+diff --git a/sound/sh/Kconfig b/sound/sh/Kconfig
+index b75fbb3236a7b9..f5fa09d740b4c9 100644
+--- a/sound/sh/Kconfig
++++ b/sound/sh/Kconfig
+@@ -14,7 +14,7 @@ if SND_SUPERH
+ 
+ config SND_AICA
+       tristate "Dreamcast Yamaha AICA sound"
+-      depends on SH_DREAMCAST
++      depends on SH_DREAMCAST && SH_DMA_API
+       select SND_PCM
+       select G2_DMA
+       help
+diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c
+index 10430c76475b5f..488fcdbb6a2d4b 100644
+--- a/sound/usb/quirks.c
++++ b/sound/usb/quirks.c
+@@ -1837,6 +1837,8 @@ static const struct usb_audio_quirk_flags_table 
quirk_flags_table[] = {
+                  QUIRK_FLAG_CTL_MSG_DELAY_1M),
+       DEVICE_FLG(0x0c45, 0x6340, /* Sonix HD USB Camera */
+                  QUIRK_FLAG_GET_SAMPLE_RATE),
++      DEVICE_FLG(0x0c45, 0x636b, /* Microdia JP001 USB Camera */
++                 QUIRK_FLAG_GET_SAMPLE_RATE),
+       DEVICE_FLG(0x0d8c, 0x0014, /* USB Audio Device */
+                  QUIRK_FLAG_CTL_MSG_DELAY_1M),
+       DEVICE_FLG(0x0ecb, 0x205c, /* JBL Quantum610 Wireless */
+@@ -1845,6 +1847,8 @@ static const struct usb_audio_quirk_flags_table 
quirk_flags_table[] = {
+                  QUIRK_FLAG_FIXED_RATE),
+       DEVICE_FLG(0x0fd9, 0x0008, /* Hauppauge HVR-950Q */
+                  QUIRK_FLAG_SHARE_MEDIA_DEVICE | QUIRK_FLAG_ALIGN_TRANSFER),
++      DEVICE_FLG(0x1101, 0x0003, /* Audioengine D1 */
++                 QUIRK_FLAG_GET_SAMPLE_RATE),
+       DEVICE_FLG(0x1224, 0x2a25, /* Jieli Technology USB PHY 2.0 */
+                  QUIRK_FLAG_GET_SAMPLE_RATE),
+       DEVICE_FLG(0x1395, 0x740a, /* Sennheiser DECT */
+diff --git a/tools/testing/selftests/vm/compaction_test.c 
b/tools/testing/selftests/vm/compaction_test.c
+index 7c260060a1a6b8..00ebd9d508ffdf 100644
+--- a/tools/testing/selftests/vm/compaction_test.c
++++ b/tools/testing/selftests/vm/compaction_test.c
+@@ -89,6 +89,8 @@ int check_compaction(unsigned long mem_free, unsigned long 
hugepage_size)
+       int compaction_index = 0;
+       char initial_nr_hugepages[20] = {0};
+       char nr_hugepages[20] = {0};
++      char target_nr_hugepages[24] = {0};
++      int slen;
+ 
+       /* We want to test with 80% of available memory. Else, OOM killer comes
+          in to play */
+@@ -118,11 +120,18 @@ int check_compaction(unsigned long mem_free, unsigned 
long hugepage_size)
+ 
+       lseek(fd, 0, SEEK_SET);
+ 
+-      /* Request a large number of huge pages. The Kernel will allocate
+-         as much as it can */
+-      if (write(fd, "100000", (6*sizeof(char))) != (6*sizeof(char))) {
+-              ksft_test_result_fail("Failed to write 100000 to 
/proc/sys/vm/nr_hugepages: %s\n",
+-                                    strerror(errno));
++      /*
++       * Request huge pages for about half of the free memory. The Kernel
++       * will allocate as much as it can, and we expect it will get at least 
1/3
++       */
++      nr_hugepages_ul = mem_free / hugepage_size / 2;
++      snprintf(target_nr_hugepages, sizeof(target_nr_hugepages),
++               "%lu", nr_hugepages_ul);
++
++      slen = strlen(target_nr_hugepages);
++      if (write(fd, target_nr_hugepages, slen) != slen) {
++              ksft_test_result_fail("Failed to write %lu to 
/proc/sys/vm/nr_hugepages: %s\n",
++                             nr_hugepages_ul, strerror(errno));
+               goto close_fd;
+       }
+ 

Reply via email to